]> Cypherpunks repositories - gostls13.git/commitdiff
runtime: don't clear gcscanvalid in casfrom_Gscanstatus
authorAustin Clements <austin@google.com>
Fri, 11 Mar 2016 19:08:10 +0000 (14:08 -0500)
committerAustin Clements <austin@google.com>
Tue, 26 Apr 2016 23:40:10 +0000 (23:40 +0000)
Currently we clear gcscanvalid in both casgstatus and
casfrom_Gscanstatus if the new status is _Grunning. This is very
important to do in casgstatus. However, this is potentially wrong in
casfrom_Gscanstatus because in this case the caller doesn't own gp and
hence the write is racy. Unlike the other _Gscan statuses, during
_Gscanrunning, the G is still running. This does not indicate that
it's transitioning into a running state. The scan simply hasn't
happened yet, so it's neither valid nor invalid.

Conveniently, this also means clearing gcscanvalid is unnecessary in
this case because the G was already in _Grunning, so we can simply
remove this code. What will happen instead is that the G will be
preempted to scan itself, that scan will set gcscanvalid to true, and
then the G will return to _Grunning via casgstatus, clearing
gcscanvalid.

This fix will become necessary shortly when we start keeping track of
the set of G's with dirty stacks, since it will no longer be
idempotent to simply set gcscanvalid to false.

Change-Id: I688c82e6fbf00d5dbbbff49efa66acb99ee86785
Reviewed-on: https://go-review.googlesource.com/20669
Reviewed-by: Rick Hudson <rlh@golang.org>
Run-TryBot: Austin Clements <austin@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>

src/runtime/proc.go
src/runtime/stack.go

index d5acbee0a76fa0a68b6ec03d98475427731b412c..dcdc7bedb8c466ee5edd2209302ef90df0d5a53b 100644 (file)
@@ -681,9 +681,6 @@ func casfrom_Gscanstatus(gp *g, oldval, newval uint32) {
                dumpgstatus(gp)
                throw("casfrom_Gscanstatus: gp->status is not in scan state")
        }
-       if newval == _Grunning {
-               gp.gcscanvalid = false
-       }
 }
 
 // This will return false if the gp is not in the expected status and the cas fails.
index dcb1b06dbd5a9aeb917c17310ecdfdde04cbeb5d..c4b1fb862e9ad0634c3a0a99d79ae22d71c4eedf 100644 (file)
@@ -1016,6 +1016,7 @@ func newstack() {
                        gp.preemptscan = false
                        gp.preempt = false
                        casfrom_Gscanstatus(gp, _Gscanwaiting, _Gwaiting)
+                       // This clears gcscanvalid.
                        casgstatus(gp, _Gwaiting, _Grunning)
                        gp.stackguard0 = gp.stack.lo + _StackGuard
                        gogo(&gp.sched) // never return