]> Cypherpunks repositories - gostls13.git/commitdiff
runtime: consolidate "out of GC work" checks
authorAustin Clements <austin@google.com>
Mon, 19 Oct 2015 17:35:25 +0000 (13:35 -0400)
committerAustin Clements <austin@google.com>
Fri, 30 Oct 2015 22:46:22 +0000 (22:46 +0000)
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>

src/runtime/mgc.go
src/runtime/mgcmark.go

index 8bba5268535e8b407cbce411f8e7a23dd3d26fcd..de054dd340608e1e2e61c35968247d0f72e4e7ff 100644 (file)
@@ -613,7 +613,7 @@ func (c *gcControllerState) findRunnableGCWorker(_p_ *p) *g {
                // else for a while, so kick everything out of its run
                // queue.
        } else {
-               if _p_.gcw.wbuf == 0 && work.full == 0 {
+               if !gcMarkWorkAvailable(_p_) {
                        // No work to be done right now. This can
                        // happen at the end of the mark phase when
                        // there are still assists tapering off. Don't
@@ -1383,7 +1383,7 @@ func gcBgMarkWorker(p *p) {
                                        "work.nwait=", incnwait, "work.nproc=", 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
@@ -1414,9 +1414,10 @@ func gcBgMarkWorker(p *p) {
 }
 
 // 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 {
-       if !p.gcw.empty() {
+       if p != nil && !p.gcw.empty() {
                return true
        }
        if atomicload64(&work.full) != 0 {
index 4ec428d9144f30000dafb958e7d0a3456c1d9cc7..04267dbdb0f4f404fd5ec6c4b293e21c8563e2bf 100644 (file)
@@ -386,7 +386,7 @@ retry:
                        throw("work.nwait > work.nproc")
                }
 
-               if incnwait == work.nproc && work.full == 0 {
+               if incnwait == work.nproc && !gcMarkWorkAvailable(nil) {
                        // This has reached a background completion
                        // point.
                        if gcBlackenPromptly {