]> Cypherpunks repositories - gostls13.git/commitdiff
runtime: fix check for pending GC work
authorAustin Clements <austin@google.com>
Fri, 24 Apr 2015 00:00:10 +0000 (20:00 -0400)
committerAustin Clements <austin@google.com>
Fri, 24 Apr 2015 20:10:10 +0000 (20:10 +0000)
When findRunnable considers running a fractional mark worker, it first
checks if there's any work to be done; if there isn't there's no point
in running the worker because it will just reschedule immediately.
However, currently findRunnable just checks work.full and
work.partial, whereas getfull can *also* draw work from m.currentwbuf.
As a result, findRunnable may not start a worker even though there
actually is work.

This problem manifests itself in occasional failures of the
test/init1.go test. This test is unusual because it performs a large
amount of allocation without executing any write barriers, which means
there's nothing to force the pointers in currentwbuf out to the
work.partial/full lists where findRunnable can see them.

This change fixes this problem by making findRunnable also check for a
currentwbuf. This aligns findRunnable with trygetfull's notion of
whether or not there's work.

Change-Id: Ic76d22b7b5d040bc4f58a6b5975e9217650e66c4
Reviewed-on: https://go-review.googlesource.com/9299
Reviewed-by: Russ Cox <rsc@golang.org>
src/runtime/mgc.go

index 497c20f0ea5a581314ac50dc51e3084f418cde1c..353610d50c791bd06f8cadf152f7adaa1c0a0e71 100644 (file)
@@ -501,7 +501,7 @@ func (c *gcControllerState) findRunnable(_p_ *p) *g {
                // else for a while, so kick everything out of its run
                // queue.
        } else {
-               if work.full == 0 && work.partial == 0 {
+               if _p_.m.ptr().currentwbuf == 0 && work.full == 0 && work.partial == 0 {
                        // 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