aboutsummaryrefslogtreecommitdiff
path: root/src/runtime
diff options
context:
space:
mode:
authorMichael Anthony Knyszek <mknyszek@google.com>2021-04-11 18:37:52 +0000
committerMichael Knyszek <mknyszek@google.com>2021-10-29 18:23:03 +0000
commit413672fc84e0ced7531cdc7cf0e5db32061e8194 (patch)
tree7649ceb8e9411799fc5cf8db1473599aeef3cbf3 /src/runtime
parent353d5b6c536c7028eba058ba27014fae0206298a (diff)
downloadgo-413672fc84e0ced7531cdc7cf0e5db32061e8194.tar.xz
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>
Diffstat (limited to 'src/runtime')
-rw-r--r--src/runtime/mgc.go1
-rw-r--r--src/runtime/mgcpacer.go35
-rw-r--r--src/runtime/mgcsweep.go43
3 files changed, 45 insertions, 34 deletions
diff --git a/src/runtime/mgc.go b/src/runtime/mgc.go
index e7c023919c..b2ed18fe6a 100644
--- a/src/runtime/mgc.go
+++ b/src/runtime/mgc.go
@@ -971,6 +971,7 @@ func gcMarkTermination(nextTriggerRatio float64) {
// Update GC trigger and pacing for the next cycle.
gcController.commit(nextTriggerRatio)
+ gcPaceSweeper(gcController.trigger)
gcPaceScavenger(gcController.heapGoal, gcController.lastHeapGoal)
// Update timing memstats
diff --git a/src/runtime/mgcpacer.go b/src/runtime/mgcpacer.go
index 73fe6e15e4..980cb2f086 100644
--- a/src/runtime/mgcpacer.go
+++ b/src/runtime/mgcpacer.go
@@ -735,40 +735,6 @@ func (c *gcControllerState) commit(triggerRatio float64) {
if gcphase != _GCoff {
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
@@ -819,6 +785,7 @@ func setGCPercent(in int32) (out int32) {
systemstack(func() {
lock(&mheap_.lock)
out = gcController.setGCPercent(in)
+ gcPaceSweeper(gcController.trigger)
gcPaceScavenger(gcController.heapGoal, gcController.lastHeapGoal)
unlock(&mheap_.lock)
})
diff --git a/src/runtime/mgcsweep.go b/src/runtime/mgcsweep.go
index a431d8a2af..b06df32b20 100644
--- a/src/runtime/mgcsweep.go
+++ b/src/runtime/mgcsweep.go
@@ -830,3 +830,46 @@ func clobberfree(x unsafe.Pointer, size uintptr) {
*(*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)
+ }
+ }
+}