Skip to content

Commit 413672f

Browse files
committed
runtime: detangle sweeper pacing from GC pacing
The sweeper's pacing state is global, so detangle it from the GC pacer's state updates so that the GC pacer can be tested. For #44167. Change-Id: Ibcea989cd435b73c5891f777d9f95f9604e03bd1 Reviewed-on: https://go-review.googlesource.com/c/go/+/309273 Trust: Michael Knyszek <[email protected]> Run-TryBot: Michael Knyszek <[email protected]> TryBot-Result: Go Bot <[email protected]> Reviewed-by: Michael Pratt <[email protected]>
1 parent 353d5b6 commit 413672f

File tree

3 files changed

+45
-34
lines changed

3 files changed

+45
-34
lines changed

src/runtime/mgc.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -971,6 +971,7 @@ func gcMarkTermination(nextTriggerRatio float64) {
971971

972972
// Update GC trigger and pacing for the next cycle.
973973
gcController.commit(nextTriggerRatio)
974+
gcPaceSweeper(gcController.trigger)
974975
gcPaceScavenger(gcController.heapGoal, gcController.lastHeapGoal)
975976

976977
// Update timing memstats

src/runtime/mgcpacer.go

Lines changed: 1 addition & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -735,40 +735,6 @@ func (c *gcControllerState) commit(triggerRatio float64) {
735735
if gcphase != _GCoff {
736736
c.revise()
737737
}
738-
739-
// Update sweep pacing.
740-
if isSweepDone() {
741-
mheap_.sweepPagesPerByte = 0
742-
} else {
743-
// Concurrent sweep needs to sweep all of the in-use
744-
// pages by the time the allocated heap reaches the GC
745-
// trigger. Compute the ratio of in-use pages to sweep
746-
// per byte allocated, accounting for the fact that
747-
// some might already be swept.
748-
heapLiveBasis := atomic.Load64(&c.heapLive)
749-
heapDistance := int64(trigger) - int64(heapLiveBasis)
750-
// Add a little margin so rounding errors and
751-
// concurrent sweep are less likely to leave pages
752-
// unswept when GC starts.
753-
heapDistance -= 1024 * 1024
754-
if heapDistance < _PageSize {
755-
// Avoid setting the sweep ratio extremely high
756-
heapDistance = _PageSize
757-
}
758-
pagesSwept := mheap_.pagesSwept.Load()
759-
pagesInUse := mheap_.pagesInUse.Load()
760-
sweepDistancePages := int64(pagesInUse) - int64(pagesSwept)
761-
if sweepDistancePages <= 0 {
762-
mheap_.sweepPagesPerByte = 0
763-
} else {
764-
mheap_.sweepPagesPerByte = float64(sweepDistancePages) / float64(heapDistance)
765-
mheap_.sweepHeapLiveBasis = heapLiveBasis
766-
// Write pagesSweptBasis last, since this
767-
// signals concurrent sweeps to recompute
768-
// their debt.
769-
mheap_.pagesSweptBasis.Store(pagesSwept)
770-
}
771-
}
772738
}
773739

774740
// effectiveGrowthRatio returns the current effective heap growth
@@ -819,6 +785,7 @@ func setGCPercent(in int32) (out int32) {
819785
systemstack(func() {
820786
lock(&mheap_.lock)
821787
out = gcController.setGCPercent(in)
788+
gcPaceSweeper(gcController.trigger)
822789
gcPaceScavenger(gcController.heapGoal, gcController.lastHeapGoal)
823790
unlock(&mheap_.lock)
824791
})

src/runtime/mgcsweep.go

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -830,3 +830,46 @@ func clobberfree(x unsafe.Pointer, size uintptr) {
830830
*(*uint32)(add(x, i)) = 0xdeadbeef
831831
}
832832
}
833+
834+
// gcPaceSweeper updates the sweeper's pacing parameters.
835+
//
836+
// Must be called whenever the GC's pacing is updated.
837+
//
838+
// The world must be stopped, or mheap_.lock must be held.
839+
func gcPaceSweeper(trigger uint64) {
840+
assertWorldStoppedOrLockHeld(&mheap_.lock)
841+
842+
// Update sweep pacing.
843+
if isSweepDone() {
844+
mheap_.sweepPagesPerByte = 0
845+
} else {
846+
// Concurrent sweep needs to sweep all of the in-use
847+
// pages by the time the allocated heap reaches the GC
848+
// trigger. Compute the ratio of in-use pages to sweep
849+
// per byte allocated, accounting for the fact that
850+
// some might already be swept.
851+
heapLiveBasis := atomic.Load64(&gcController.heapLive)
852+
heapDistance := int64(trigger) - int64(heapLiveBasis)
853+
// Add a little margin so rounding errors and
854+
// concurrent sweep are less likely to leave pages
855+
// unswept when GC starts.
856+
heapDistance -= 1024 * 1024
857+
if heapDistance < _PageSize {
858+
// Avoid setting the sweep ratio extremely high
859+
heapDistance = _PageSize
860+
}
861+
pagesSwept := mheap_.pagesSwept.Load()
862+
pagesInUse := mheap_.pagesInUse.Load()
863+
sweepDistancePages := int64(pagesInUse) - int64(pagesSwept)
864+
if sweepDistancePages <= 0 {
865+
mheap_.sweepPagesPerByte = 0
866+
} else {
867+
mheap_.sweepPagesPerByte = float64(sweepDistancePages) / float64(heapDistance)
868+
mheap_.sweepHeapLiveBasis = heapLiveBasis
869+
// Write pagesSweptBasis last, since this
870+
// signals concurrent sweeps to recompute
871+
// their debt.
872+
mheap_.pagesSweptBasis.Store(pagesSwept)
873+
}
874+
}
875+
}

0 commit comments

Comments
 (0)