Commit 4cca1cc0 authored by Austin Clements's avatar Austin Clements

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/16058Reviewed-by: default avatarRick Hudson <rlh@golang.org>
Run-TryBot: Austin Clements <austin@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
parent 7c167f27
...@@ -613,7 +613,7 @@ func (c *gcControllerState) findRunnableGCWorker(_p_ *p) *g { ...@@ -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) { ...@@ -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) { ...@@ -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 {
......
...@@ -386,7 +386,7 @@ retry: ...@@ -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 {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment