runtime: consolidate "out of GC work" checks

We already have gcMarkWorkAvailable, but the check for GC mark work is
open-coded in several places. Generalize gcMarkWorkAvailable slightly
and replace these open-coded checks with calls to gcMarkWorkAvailable.

In addition to cleaning up the code, this puts us in a better position
to make this check slightly more complicated.

Change-Id: I1b29883300ecd82a1bf6be193e9b4ee96582a860
Reviewed-on: https://go-review.googlesource.com/16058
Reviewed-by: Rick Hudson <rlh@golang.org>
Run-TryBot: Austin Clements <austin@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
This commit is contained in:
Austin Clements 2015-10-19 13:35:25 -04:00
parent 7c167f2708
commit 4cca1cc05e
2 changed files with 6 additions and 5 deletions

View File

@ -613,7 +613,7 @@ func (c *gcControllerState) findRunnableGCWorker(_p_ *p) *g {
// else for a while, so kick everything out of its run // else for a while, so kick everything out of its run
// queue. // queue.
} else { } else {
if _p_.gcw.wbuf == 0 && work.full == 0 { if !gcMarkWorkAvailable(_p_) {
// No work to be done right now. This can // No work to be done right now. This can
// happen at the end of the mark phase when // happen at the end of the mark phase when
// there are still assists tapering off. Don't // there are still assists tapering off. Don't
@ -1383,7 +1383,7 @@ func gcBgMarkWorker(p *p) {
"work.nwait=", incnwait, "work.nproc=", work.nproc) "work.nwait=", incnwait, "work.nproc=", work.nproc)
throw("work.nwait > work.nproc") throw("work.nwait > work.nproc")
} }
done = incnwait == work.nproc && work.full == 0 done = incnwait == work.nproc && !gcMarkWorkAvailable(nil)
} }
// If this worker reached a background mark completion // If this worker reached a background mark completion
@ -1414,9 +1414,10 @@ func gcBgMarkWorker(p *p) {
} }
// gcMarkWorkAvailable returns true if executing a mark worker // gcMarkWorkAvailable returns true if executing a mark worker
// on p is potentially useful. // on p is potentially useful. p may be nil, in which case it only
// checks the global sources of work.
func gcMarkWorkAvailable(p *p) bool { func gcMarkWorkAvailable(p *p) bool {
if !p.gcw.empty() { if p != nil && !p.gcw.empty() {
return true return true
} }
if atomicload64(&work.full) != 0 { if atomicload64(&work.full) != 0 {

View File

@ -386,7 +386,7 @@ retry:
throw("work.nwait > work.nproc") throw("work.nwait > work.nproc")
} }
if incnwait == work.nproc && work.full == 0 { if incnwait == work.nproc && !gcMarkWorkAvailable(nil) {
// This has reached a background completion // This has reached a background completion
// point. // point.
if gcBlackenPromptly { if gcBlackenPromptly {