]> Cypherpunks repositories - gostls13.git/commitdiff
runtime: join selectgo and selectgoImpl
authorAustin Clements <austin@google.com>
Tue, 7 Mar 2017 20:36:49 +0000 (15:36 -0500)
committerAustin Clements <austin@google.com>
Tue, 7 Mar 2017 21:19:38 +0000 (21:19 +0000)
Currently selectgo is just a wrapper around selectgoImpl. This keeps
the hard-coded frame skip counts for tracing the same between the
channel implementation and the select implementation.

However, this is fragile and confusing, so pass a skip parameter to
send and recv, join selectgo and selectgoImpl into one function, and
use decrease all of the skips in selectgo by one.

Change-Id: I11b8cbb7d805b55f5dc6ab4875ac7dde79412ff2
Reviewed-on: https://go-review.googlesource.com/37860
Run-TryBot: Austin Clements <austin@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
src/runtime/chan.go
src/runtime/select.go

index b54a46cd2b46b974b254399408989f322b7005dd..e74cd8b93d8d1347ef07150463cef301cede9f9e 100644 (file)
@@ -183,7 +183,7 @@ func chansend(t *chantype, c *hchan, ep unsafe.Pointer, block bool, callerpc uin
        if sg := c.recvq.dequeue(); sg != nil {
                // Found a waiting receiver. We pass the value we want to send
                // directly to the receiver, bypassing the channel buffer (if any).
-               send(c, sg, ep, func() { unlock(&c.lock) })
+               send(c, sg, ep, func() { unlock(&c.lock) }, 3)
                return true
        }
 
@@ -254,7 +254,7 @@ func chansend(t *chantype, c *hchan, ep unsafe.Pointer, block bool, callerpc uin
 // Channel c must be empty and locked.  send unlocks c with unlockf.
 // sg must already be dequeued from c.
 // ep must be non-nil and point to the heap or the caller's stack.
-func send(c *hchan, sg *sudog, ep unsafe.Pointer, unlockf func()) {
+func send(c *hchan, sg *sudog, ep unsafe.Pointer, unlockf func(), skip int) {
        if raceenabled {
                if c.dataqsiz == 0 {
                        racesync(c, sg)
@@ -284,7 +284,7 @@ func send(c *hchan, sg *sudog, ep unsafe.Pointer, unlockf func()) {
        if sg.releasetime != 0 {
                sg.releasetime = cputicks()
        }
-       goready(gp, 4)
+       goready(gp, skip+1)
 }
 
 // Sends and receives on unbuffered or empty-buffered channels are the
@@ -464,7 +464,7 @@ func chanrecv(t *chantype, c *hchan, ep unsafe.Pointer, block bool) (selected, r
                // directly from sender. Otherwise, receive from head of queue
                // and add sender's value to the tail of the queue (both map to
                // the same buffer slot because the queue is full).
-               recv(c, sg, ep, func() { unlock(&c.lock) })
+               recv(c, sg, ep, func() { unlock(&c.lock) }, 3)
                return true, true
        }
 
@@ -540,7 +540,7 @@ func chanrecv(t *chantype, c *hchan, ep unsafe.Pointer, block bool) (selected, r
 // Channel c must be full and locked. recv unlocks c with unlockf.
 // sg must already be dequeued from c.
 // A non-nil ep must point to the heap or the caller's stack.
-func recv(c *hchan, sg *sudog, ep unsafe.Pointer, unlockf func()) {
+func recv(c *hchan, sg *sudog, ep unsafe.Pointer, unlockf func(), skip int) {
        if c.dataqsiz == 0 {
                if raceenabled {
                        racesync(c, sg)
@@ -580,7 +580,7 @@ func recv(c *hchan, sg *sudog, ep unsafe.Pointer, unlockf func()) {
        if sg.releasetime != 0 {
                sg.releasetime = cputicks()
        }
-       goready(gp, 4)
+       goready(gp, skip+1)
 }
 
 // compiler implements
index 03b699796f65103bbbc56dd8e73e6cd6c01c3073..715cee87500cf740a5a9c20c6e88af1e1f47c1dd 100644 (file)
@@ -199,13 +199,7 @@ func block() {
 //
 // selectgo returns the index of the chosen scase, which matches the
 // ordinal position of its respective select{recv,send,default} call.
-//go:nosplit
 func selectgo(sel *hselect) int {
-       return selectgoImpl(sel)
-}
-
-// Separate function to keep runtime/trace.TestTraceSymbolize happy.
-func selectgoImpl(sel *hselect) int {
        if debugSelect {
                print("select: sel=", sel, "\n")
        }
@@ -398,7 +392,7 @@ loop:
 
        // wait for someone to wake us up
        gp.param = nil
-       gopark(selparkcommit, nil, "select", traceEvGoBlockSelect, 2)
+       gopark(selparkcommit, nil, "select", traceEvGoBlockSelect, 1)
 
        // While we were asleep, some goroutine came along and completed
        // one of the cases in the select and woke us up (called ready).
@@ -592,7 +586,7 @@ bufsend:
 
 recv:
        // can receive from sleeping sender (sg)
-       recv(c, sg, cas.elem, func() { selunlock(scases, lockorder) })
+       recv(c, sg, cas.elem, func() { selunlock(scases, lockorder) }, 2)
        if debugSelect {
                print("syncrecv: sel=", sel, " c=", c, "\n")
        }
@@ -623,7 +617,7 @@ send:
        if msanenabled {
                msanread(cas.elem, c.elemtype.size)
        }
-       send(c, sg, cas.elem, func() { selunlock(scases, lockorder) })
+       send(c, sg, cas.elem, func() { selunlock(scases, lockorder) }, 2)
        if debugSelect {
                print("syncsend: sel=", sel, " c=", c, "\n")
        }
@@ -631,7 +625,7 @@ send:
 
 retc:
        if cas.releasetime > 0 {
-               blockevent(cas.releasetime-t0, 2)
+               blockevent(cas.releasetime-t0, 1)
        }
        return casi