1
0
mirror of https://github.com/golang/go synced 2024-11-18 09:54:57 -07:00

runtime: join selectgo and selectgoImpl

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>
This commit is contained in:
Austin Clements 2017-03-07 15:36:49 -05:00
parent 5e4a958351
commit d50f892abc
2 changed files with 10 additions and 16 deletions

View 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

View 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