From 3c2a21ff13c53b93db50cfb37b186d6200e2ceec Mon Sep 17 00:00:00 2001 From: Austin Clements Date: Thu, 25 Feb 2016 15:37:40 -0500 Subject: [PATCH] runtime: fix transient _Gwaiting states in newstack 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 Run-TryBot: Austin Clements TryBot-Result: Gobot Gobot --- src/runtime/stack.go | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/runtime/stack.go b/src/runtime/stack.go index d37bc7d08b..6450094ef7 100644 --- a/src/runtime/stack.go +++ b/src/runtime/stack.go @@ -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. -- 2.48.1