1
0
mirror of https://github.com/golang/go synced 2024-09-25 15:20:13 -06:00

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>
This commit is contained in:
Austin Clements 2015-04-22 16:35:45 -04:00
parent e870f06c3f
commit 4e32718d3e

View 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.