mirror of
https://github.com/golang/go
synced 2024-11-17 22:54:48 -07:00
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 <mknyszek@google.com> Run-TryBot: Michael Knyszek <mknyszek@google.com> TryBot-Result: Go Bot <gobot@golang.org> Reviewed-by: Michael Pratt <mpratt@google.com>
This commit is contained in:
parent
353d5b6c53
commit
413672fc84
@ -971,6 +971,7 @@ func gcMarkTermination(nextTriggerRatio float64) {
|
|||||||
|
|
||||||
// Update GC trigger and pacing for the next cycle.
|
// Update GC trigger and pacing for the next cycle.
|
||||||
gcController.commit(nextTriggerRatio)
|
gcController.commit(nextTriggerRatio)
|
||||||
|
gcPaceSweeper(gcController.trigger)
|
||||||
gcPaceScavenger(gcController.heapGoal, gcController.lastHeapGoal)
|
gcPaceScavenger(gcController.heapGoal, gcController.lastHeapGoal)
|
||||||
|
|
||||||
// Update timing memstats
|
// Update timing memstats
|
||||||
|
@ -735,40 +735,6 @@ func (c *gcControllerState) commit(triggerRatio float64) {
|
|||||||
if gcphase != _GCoff {
|
if gcphase != _GCoff {
|
||||||
c.revise()
|
c.revise()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update sweep pacing.
|
|
||||||
if isSweepDone() {
|
|
||||||
mheap_.sweepPagesPerByte = 0
|
|
||||||
} else {
|
|
||||||
// Concurrent sweep needs to sweep all of the in-use
|
|
||||||
// pages by the time the allocated heap reaches the GC
|
|
||||||
// trigger. Compute the ratio of in-use pages to sweep
|
|
||||||
// per byte allocated, accounting for the fact that
|
|
||||||
// some might already be swept.
|
|
||||||
heapLiveBasis := atomic.Load64(&c.heapLive)
|
|
||||||
heapDistance := int64(trigger) - int64(heapLiveBasis)
|
|
||||||
// Add a little margin so rounding errors and
|
|
||||||
// concurrent sweep are less likely to leave pages
|
|
||||||
// unswept when GC starts.
|
|
||||||
heapDistance -= 1024 * 1024
|
|
||||||
if heapDistance < _PageSize {
|
|
||||||
// Avoid setting the sweep ratio extremely high
|
|
||||||
heapDistance = _PageSize
|
|
||||||
}
|
|
||||||
pagesSwept := mheap_.pagesSwept.Load()
|
|
||||||
pagesInUse := mheap_.pagesInUse.Load()
|
|
||||||
sweepDistancePages := int64(pagesInUse) - int64(pagesSwept)
|
|
||||||
if sweepDistancePages <= 0 {
|
|
||||||
mheap_.sweepPagesPerByte = 0
|
|
||||||
} else {
|
|
||||||
mheap_.sweepPagesPerByte = float64(sweepDistancePages) / float64(heapDistance)
|
|
||||||
mheap_.sweepHeapLiveBasis = heapLiveBasis
|
|
||||||
// Write pagesSweptBasis last, since this
|
|
||||||
// signals concurrent sweeps to recompute
|
|
||||||
// their debt.
|
|
||||||
mheap_.pagesSweptBasis.Store(pagesSwept)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// effectiveGrowthRatio returns the current effective heap growth
|
// effectiveGrowthRatio returns the current effective heap growth
|
||||||
@ -819,6 +785,7 @@ func setGCPercent(in int32) (out int32) {
|
|||||||
systemstack(func() {
|
systemstack(func() {
|
||||||
lock(&mheap_.lock)
|
lock(&mheap_.lock)
|
||||||
out = gcController.setGCPercent(in)
|
out = gcController.setGCPercent(in)
|
||||||
|
gcPaceSweeper(gcController.trigger)
|
||||||
gcPaceScavenger(gcController.heapGoal, gcController.lastHeapGoal)
|
gcPaceScavenger(gcController.heapGoal, gcController.lastHeapGoal)
|
||||||
unlock(&mheap_.lock)
|
unlock(&mheap_.lock)
|
||||||
})
|
})
|
||||||
|
@ -830,3 +830,46 @@ func clobberfree(x unsafe.Pointer, size uintptr) {
|
|||||||
*(*uint32)(add(x, i)) = 0xdeadbeef
|
*(*uint32)(add(x, i)) = 0xdeadbeef
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// gcPaceSweeper updates the sweeper's pacing parameters.
|
||||||
|
//
|
||||||
|
// Must be called whenever the GC's pacing is updated.
|
||||||
|
//
|
||||||
|
// The world must be stopped, or mheap_.lock must be held.
|
||||||
|
func gcPaceSweeper(trigger uint64) {
|
||||||
|
assertWorldStoppedOrLockHeld(&mheap_.lock)
|
||||||
|
|
||||||
|
// Update sweep pacing.
|
||||||
|
if isSweepDone() {
|
||||||
|
mheap_.sweepPagesPerByte = 0
|
||||||
|
} else {
|
||||||
|
// Concurrent sweep needs to sweep all of the in-use
|
||||||
|
// pages by the time the allocated heap reaches the GC
|
||||||
|
// trigger. Compute the ratio of in-use pages to sweep
|
||||||
|
// per byte allocated, accounting for the fact that
|
||||||
|
// some might already be swept.
|
||||||
|
heapLiveBasis := atomic.Load64(&gcController.heapLive)
|
||||||
|
heapDistance := int64(trigger) - int64(heapLiveBasis)
|
||||||
|
// Add a little margin so rounding errors and
|
||||||
|
// concurrent sweep are less likely to leave pages
|
||||||
|
// unswept when GC starts.
|
||||||
|
heapDistance -= 1024 * 1024
|
||||||
|
if heapDistance < _PageSize {
|
||||||
|
// Avoid setting the sweep ratio extremely high
|
||||||
|
heapDistance = _PageSize
|
||||||
|
}
|
||||||
|
pagesSwept := mheap_.pagesSwept.Load()
|
||||||
|
pagesInUse := mheap_.pagesInUse.Load()
|
||||||
|
sweepDistancePages := int64(pagesInUse) - int64(pagesSwept)
|
||||||
|
if sweepDistancePages <= 0 {
|
||||||
|
mheap_.sweepPagesPerByte = 0
|
||||||
|
} else {
|
||||||
|
mheap_.sweepPagesPerByte = float64(sweepDistancePages) / float64(heapDistance)
|
||||||
|
mheap_.sweepHeapLiveBasis = heapLiveBasis
|
||||||
|
// Write pagesSweptBasis last, since this
|
||||||
|
// signals concurrent sweeps to recompute
|
||||||
|
// their debt.
|
||||||
|
mheap_.pagesSweptBasis.Store(pagesSwept)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user