]> Cypherpunks repositories - gostls13.git/commitdiff
runtime: document non-obvious requirement on sudog.elem
authorAustin Clements <austin@google.com>
Mon, 15 Feb 2016 21:50:12 +0000 (16:50 -0500)
committerAustin Clements <austin@google.com>
Thu, 25 Feb 2016 23:37:17 +0000 (23:37 +0000)
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>

src/runtime/chan.go
src/runtime/select.go

index 063c5ce391d861c4eb1199765c54d9eea0c4a8d3..f6f3ce4d90ec275f1deaf0fc3176048df4d2d3fd 100644 (file)
@@ -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
index b6c3fea001db858c2b17621c6d280ab56a2988f3..b315dde6c616f3858027540320189d280d4cacae 100644 (file)
@@ -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 {