mirror of
https://github.com/golang/go
synced 2024-11-24 02:30:12 -07: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:
parent
e870f06c3f
commit
4e32718d3e
@ -298,6 +298,10 @@ type gcControllerState struct {
|
|||||||
// at the end of of each cycle.
|
// at the end of of each cycle.
|
||||||
triggerRatio float64
|
triggerRatio float64
|
||||||
|
|
||||||
|
// reviseTimer is a timer that triggers periodic revision of
|
||||||
|
// control variables during the cycle.
|
||||||
|
reviseTimer timer
|
||||||
|
|
||||||
_ [_CacheLineSize]byte
|
_ [_CacheLineSize]byte
|
||||||
|
|
||||||
// fractionalMarkWorkersNeeded is the number of fractional
|
// fractionalMarkWorkersNeeded is the number of fractional
|
||||||
@ -344,10 +348,6 @@ func (c *gcControllerState) startCycle() {
|
|||||||
c.fractionalMarkWorkersNeeded = 0
|
c.fractionalMarkWorkersNeeded = 0
|
||||||
}
|
}
|
||||||
|
|
||||||
// Compute initial values for controls that are updated
|
|
||||||
// throughout the cycle.
|
|
||||||
c.revise()
|
|
||||||
|
|
||||||
// Clear per-P state
|
// Clear per-P state
|
||||||
for _, p := range &allp {
|
for _, p := range &allp {
|
||||||
if p == nil {
|
if p == nil {
|
||||||
@ -356,7 +356,17 @@ func (c *gcControllerState) startCycle() {
|
|||||||
p.gcAssistTime = 0
|
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
|
// 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.
|
// EWMA weight given to this cycle's scan work ratio.
|
||||||
const workRatioWeight = 0.75
|
const workRatioWeight = 0.75
|
||||||
|
|
||||||
|
// Stop the revise timer
|
||||||
|
deltimer(&c.reviseTimer)
|
||||||
|
|
||||||
// Compute next cycle trigger ratio. First, this computes the
|
// Compute next cycle trigger ratio. First, this computes the
|
||||||
// "error" for this cycle; that is, how far off the trigger
|
// "error" for this cycle; that is, how far off the trigger
|
||||||
// was from what it should have been, accounting for both heap
|
// was from what it should have been, accounting for both heap
|
||||||
@ -768,9 +781,7 @@ func gc(mode int) {
|
|||||||
if debug.gctrace > 0 {
|
if debug.gctrace > 0 {
|
||||||
tMark = nanotime()
|
tMark = nanotime()
|
||||||
}
|
}
|
||||||
for !notetsleepg(&work.bgMarkNote, 10*1000*1000) {
|
notetsleepg(&work.bgMarkNote, -1)
|
||||||
gcController.revise()
|
|
||||||
}
|
|
||||||
noteclear(&work.bgMarkNote)
|
noteclear(&work.bgMarkNote)
|
||||||
|
|
||||||
// Begin mark termination.
|
// Begin mark termination.
|
||||||
|
Loading…
Reference in New Issue
Block a user