]> Cypherpunks repositories - gostls13.git/commitdiff
runtime: fix transient _Gwaiting states in newstack
authorAustin Clements <austin@google.com>
Thu, 25 Feb 2016 20:37:40 +0000 (15:37 -0500)
committerAustin Clements <austin@google.com>
Wed, 16 Mar 2016 20:13:12 +0000 (20:13 +0000)
With concurrent stack shrinking, the stack can move the instant after
a G enters _Gwaiting. There are only two places that put a G into
_Gwaiting: gopark and newstack. We fixed uses of gopark. This commit
fixes newstack by simplifying its G transitions and, in particular,
eliminating or narrowing the transient _Gwaiting states it passes
through so it's clear nothing in the G is accessed while in _Gwaiting.

For #12967.

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

src/runtime/stack.go

index d37bc7d08b362811cc01768b91ae83d0d8a74128..6450094ef7168234689cefe671c8e3f56f1934ce 100644 (file)
@@ -869,11 +869,6 @@ func newstack() {
                }
        }
 
-       // The goroutine must be executing in order to call newstack,
-       // so it must be Grunning (or Gscanrunning).
-       casgstatus(gp, _Grunning, _Gwaiting)
-       gp.waitreason = "stack growth"
-
        if gp.stack.lo == 0 {
                throw("missing stack in newstack")
        }
@@ -908,6 +903,8 @@ func newstack() {
                if thisg.m.p == 0 && thisg.m.locks == 0 {
                        throw("runtime: g is running but p is not")
                }
+               // Synchronize with scang.
+               casgstatus(gp, _Grunning, _Gwaiting)
                if gp.preemptscan {
                        for !castogscanstatus(gp, _Gwaiting, _Gscanwaiting) {
                                // Likely to be racing with the GC as
@@ -941,7 +938,9 @@ func newstack() {
                throw("stack overflow")
        }
 
-       casgstatus(gp, _Gwaiting, _Gcopystack)
+       // The goroutine must be executing in order to call newstack,
+       // so it must be Grunning (or Gscanrunning).
+       casgstatus(gp, _Grunning, _Gcopystack)
 
        // The concurrent GC will not scan the stack while we are doing the copy since
        // the gp is in a Gcopystack status.