]> Cypherpunks repositories - gostls13.git/commitdiff
runtime: use timer for GC control revise rather than timeout
authorAustin Clements <austin@google.com>
Wed, 22 Apr 2015 20:35:45 +0000 (16:35 -0400)
committerAustin Clements <austin@google.com>
Fri, 24 Apr 2015 15:12:56 +0000 (15:12 +0000)
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>
src/runtime/mgc.go

index f3e5a67b60725228b69acf21fdf64b2c78d60986..3bc56893b963d2cadf10cd280d90b0d8daf36c9d 100644 (file)
@@ -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.