summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAustin Clements <austin@google.com>2016-02-15 16:50:12 -0500
committerAustin Clements <austin@google.com>2016-02-25 23:37:17 +0000
commit1e91e2a25a0058cc25b3836b59a0954c6c75a62c (patch)
tree46ceeacaa14a26b6052078eff830e74b7e0176b5 /src
parent39f2bd737bb0b9446b4d241aa76fcb87d7e77278 (diff)
downloadgo-git-1e91e2a25a0058cc25b3836b59a0954c6c75a62c.tar.gz
runtime: document non-obvious requirement on sudog.elem
The channel code must not allow stack splits between when it assigns a potential stack pointer to sudog.elem (or sudog.selectdone) and when it makes the sudog visible to copystack by putting it on the g.waiting list. We do get this right everywhere, but add a comment about this subtlety for future eyes. Change-Id: I941da150437167acff37b0e56983c793f40fcf79 Reviewed-on: https://go-review.googlesource.com/19632 Reviewed-by: Rick Hudson <rlh@golang.org> Run-TryBot: Austin Clements <austin@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org>
Diffstat (limited to 'src')
-rw-r--r--src/runtime/chan.go4
-rw-r--r--src/runtime/select.go2
2 files changed, 6 insertions, 0 deletions
diff --git a/src/runtime/chan.go b/src/runtime/chan.go
index 063c5ce391..f6f3ce4d90 100644
--- a/src/runtime/chan.go
+++ b/src/runtime/chan.go
@@ -203,6 +203,8 @@ func chansend(t *chantype, c *hchan, ep unsafe.Pointer, block bool, callerpc uin
if t0 != 0 {
mysg.releasetime = -1
}
+ // No stack splits between assigning elem and enqueuing mysg
+ // on gp.waiting where copystack can find it.
mysg.elem = ep
mysg.waitlink = nil
mysg.g = gp
@@ -460,6 +462,8 @@ func chanrecv(t *chantype, c *hchan, ep unsafe.Pointer, block bool) (selected, r
if t0 != 0 {
mysg.releasetime = -1
}
+ // No stack splits between assigning elem and enqueuing mysg
+ // on gp.waiting where copystack can find it.
mysg.elem = ep
mysg.waitlink = nil
gp.waiting = mysg
diff --git a/src/runtime/select.go b/src/runtime/select.go
index b6c3fea001..b315dde6c6 100644
--- a/src/runtime/select.go
+++ b/src/runtime/select.go
@@ -370,6 +370,8 @@ loop:
sg.g = gp
// Note: selectdone is adjusted for stack copies in stack1.go:adjustsudogs
sg.selectdone = (*uint32)(noescape(unsafe.Pointer(&done)))
+ // No stack splits between assigning elem and enqueuing
+ // sg on gp.waiting where copystack can find it.
sg.elem = cas.elem
sg.releasetime = 0
if t0 != 0 {