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:
parent
5e4a958351
commit
d50f892abc
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user