runtime: use timer for GC control revise rather than timeout
Currently, we use a note sleep with a timeout in a loop in func gc to
periodically revise the GC control variables. Replace this with a
fully blocking note sleep and use a periodic timer to trigger the
revise instead. This is a step toward replacing the note sleep in func
gc.
Change-Id: I2d562f6b9b2e5f0c28e9a54227e2c0f8a2603f63
Reviewed-on: https://go-review.googlesource.com/9290
Reviewed-by: Rick Hudson <rlh@golang.org>
Reviewed-by: Russ Cox <rsc@golang.org>
diff --git a/src/runtime/mgc.go b/src/runtime/mgc.go
index f3e5a67..3bc5689 100644
--- a/src/runtime/mgc.go
+++ b/src/runtime/mgc.go
@@ -298,6 +298,10 @@
// at the end of of each cycle.
triggerRatio float64
+ // reviseTimer is a timer that triggers periodic revision of
+ // control variables during the cycle.
+ reviseTimer timer
+
_ [_CacheLineSize]byte
// fractionalMarkWorkersNeeded is the number of fractional
@@ -344,10 +348,6 @@
c.fractionalMarkWorkersNeeded = 0
}
- // Compute initial values for controls that are updated
- // throughout the cycle.
- c.revise()
-
// Clear per-P state
for _, p := range &allp {
if p == nil {
@@ -356,7 +356,17 @@
p.gcAssistTime = 0
}
- return
+ // Compute initial values for controls that are updated
+ // throughout the cycle.
+ c.revise()
+
+ // Set up a timer to revise periodically
+ c.reviseTimer.f = func(interface{}, uintptr) {
+ gcController.revise()
+ }
+ c.reviseTimer.period = 10 * 1000 * 1000
+ c.reviseTimer.when = nanotime() + c.reviseTimer.period
+ addtimer(&c.reviseTimer)
}
// revise updates the assist ratio during the GC cycle to account for
@@ -408,6 +418,9 @@
// EWMA weight given to this cycle's scan work ratio.
const workRatioWeight = 0.75
+ // Stop the revise timer
+ deltimer(&c.reviseTimer)
+
// Compute next cycle trigger ratio. First, this computes the
// "error" for this cycle; that is, how far off the trigger
// was from what it should have been, accounting for both heap
@@ -768,9 +781,7 @@
if debug.gctrace > 0 {
tMark = nanotime()
}
- for !notetsleepg(&work.bgMarkNote, 10*1000*1000) {
- gcController.revise()
- }
+ notetsleepg(&work.bgMarkNote, -1)
noteclear(&work.bgMarkNote)
// Begin mark termination.