mirror of
https://github.com/golang/go
synced 2024-11-19 06:24:41 -07:00
runtime: consolidate gcworkdone/gcscanvalid clearing loops
Previously, we had three loops in the garbage collector that all cleared the per-G GC flags. Consolidate these into one function. This one function is designed to work in a concurrent setting. As a result, it's slightly more expensive than the loops it replaces during STW phases, but these happen at most twice per GC. Change-Id: Id1ec0074fd58865eb0112b8a0547b267802d0df1 Reviewed-on: https://go-review.googlesource.com/5881 Reviewed-by: Russ Cox <rsc@golang.org> Reviewed-by: Rick Hudson <rlh@golang.org>
This commit is contained in:
parent
37b8597178
commit
b3d791c7bb
@ -339,13 +339,9 @@ func gc(mode int) {
|
|||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
// For non-concurrent GC (mode != gcBackgroundMode)
|
// For non-concurrent GC (mode != gcBackgroundMode)
|
||||||
// The g stacks have not been scanned so set gcscanvalid
|
// The g stacks have not been scanned so clear g state
|
||||||
// such that mark termination scans all stacks.
|
// such that mark termination scans all stacks.
|
||||||
// No races here since we are in a STW phase.
|
gcResetGState()
|
||||||
for _, gp := range allgs {
|
|
||||||
gp.gcworkdone = false // set to true in gcphasework
|
|
||||||
gp.gcscanvalid = false // stack has not been scanned
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
startTime := nanotime()
|
startTime := nanotime()
|
||||||
@ -384,11 +380,7 @@ func gc(mode int) {
|
|||||||
// The g stacks have been scanned so
|
// The g stacks have been scanned so
|
||||||
// they have gcscanvalid==true and gcworkdone==true.
|
// they have gcscanvalid==true and gcworkdone==true.
|
||||||
// Reset these so that all stacks will be rescanned.
|
// Reset these so that all stacks will be rescanned.
|
||||||
// No races here since we are in a STW phase.
|
gcResetGState()
|
||||||
for _, gp := range allgs {
|
|
||||||
gp.gcworkdone = false // set to true in gcphasework
|
|
||||||
gp.gcscanvalid = false // stack has not been scanned
|
|
||||||
}
|
|
||||||
finishsweep_m()
|
finishsweep_m()
|
||||||
gcMark(startTime)
|
gcMark(startTime)
|
||||||
gcSweep(mode)
|
gcSweep(mode)
|
||||||
@ -606,6 +598,22 @@ func gcCopySpans() {
|
|||||||
unlock(&mheap_.lock)
|
unlock(&mheap_.lock)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// gcResetGState resets the GC state of all G's and returns the length
|
||||||
|
// of allgs.
|
||||||
|
func gcResetGState() int {
|
||||||
|
// This may be called during a concurrent phase, so make sure
|
||||||
|
// allgs doesn't change.
|
||||||
|
lock(&allglock)
|
||||||
|
local_allglen := allglen
|
||||||
|
for i := uintptr(0); i < local_allglen; i++ {
|
||||||
|
gp := allgs[i]
|
||||||
|
gp.gcworkdone = false // set to true in gcphasework
|
||||||
|
gp.gcscanvalid = false // stack has not been scanned
|
||||||
|
}
|
||||||
|
unlock(&allglock)
|
||||||
|
return int(local_allglen)
|
||||||
|
}
|
||||||
|
|
||||||
// Hooks for other packages
|
// Hooks for other packages
|
||||||
|
|
||||||
var poolcleanup func()
|
var poolcleanup func()
|
||||||
|
@ -27,14 +27,7 @@ func gcscan_m() {
|
|||||||
// At the bottom we will want to return this p back to the scheduler.
|
// At the bottom we will want to return this p back to the scheduler.
|
||||||
|
|
||||||
// Prepare flag indicating that the scan has not been completed.
|
// Prepare flag indicating that the scan has not been completed.
|
||||||
lock(&allglock)
|
local_allglen := gcResetGState()
|
||||||
local_allglen := allglen
|
|
||||||
for i := uintptr(0); i < local_allglen; i++ {
|
|
||||||
gp := allgs[i]
|
|
||||||
gp.gcworkdone = false // set to true in gcphasework
|
|
||||||
gp.gcscanvalid = false // stack has not been scanned
|
|
||||||
}
|
|
||||||
unlock(&allglock)
|
|
||||||
|
|
||||||
work.nwait = 0
|
work.nwait = 0
|
||||||
work.ndone = 0
|
work.ndone = 0
|
||||||
@ -45,7 +38,7 @@ func gcscan_m() {
|
|||||||
|
|
||||||
lock(&allglock)
|
lock(&allglock)
|
||||||
// Check that gc work is done.
|
// Check that gc work is done.
|
||||||
for i := uintptr(0); i < local_allglen; i++ {
|
for i := 0; i < local_allglen; i++ {
|
||||||
gp := allgs[i]
|
gp := allgs[i]
|
||||||
if !gp.gcworkdone {
|
if !gp.gcworkdone {
|
||||||
throw("scan missed a g")
|
throw("scan missed a g")
|
||||||
|
Loading…
Reference in New Issue
Block a user