From: Austin Clements Date: Wed, 22 Apr 2015 20:35:45 +0000 (-0400) Subject: runtime: use timer for GC control revise rather than timeout X-Git-Tag: go1.5beta1~929 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=4e32718d3e478278d0f7e3d6910d563c35f40be0;p=gostls13.git 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 Reviewed-by: Russ Cox --- diff --git a/src/runtime/mgc.go b/src/runtime/mgc.go index f3e5a67b60..3bc56893b9 100644 --- a/src/runtime/mgc.go +++ b/src/runtime/mgc.go @@ -298,6 +298,10 @@ type gcControllerState struct { // 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 @@ func (c *gcControllerState) startCycle() { 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 @@ func (c *gcControllerState) startCycle() { 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 @@ func (c *gcControllerState) endCycle() { // 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 @@ func gc(mode int) { 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.