Source File
select.go
Belonging Package
runtime
package runtime
import (
)
const debugSelect = false
:= 0
for := range {
:= &[]
for := range {
:= [[]].c
for > 0 && [[(-1)/2]].c.sortkey() < .sortkey() {
:= ( - 1) / 2
[] = []
=
}
[] = []
}
for := len() - 1; >= 0; -- {
:= []
:= [].c
[] = [0]
:= 0
for {
:= *2 + 1
if >= {
break
}
if +1 < && [[]].c.sortkey() < [[+1]].c.sortkey() {
++
}
if .sortkey() < [[]].c.sortkey() {
[] = []
=
continue
}
break
}
[] =
}
if debugSelect {
for := 0; +1 < len(); ++ {
if [[]].c.sortkey() > [[+1]].c.sortkey() {
print("i=", , " x=", [], " y=", [+1], "\n")
throw("select: broken sort")
}
}
}
var int
var *scase
var bool
var int64 = -1
var bool
for , := range {
= int()
= &[]
= .c
if >= {
= .sendq.dequeue()
if != nil {
goto
}
if .qcount > 0 {
goto
}
if .closed != 0 {
goto
}
} else {
if raceenabled {
racereadpc(.raceaddr(), (), chansendpc)
}
if .closed != 0 {
goto
}
= .recvq.dequeue()
if != nil {
goto
}
if .qcount < .dataqsiz {
goto
}
}
}
if ! {
selunlock(, )
= -1
goto
}
.elem = .elem
.releasetime = 0
if != 0 {
.releasetime = -1
}
atomic.Store8(&.parkingOnChan, 1)
gopark(selparkcommit, nil, waitReasonSelect, traceEvGoBlockSelect, 1)
.activeStackChans = false
sellock(, )
.selectDone = 0
= (*sudog)(.param)
.param = nil
= int()
=
= .success
if .releasetime > 0 {
= .releasetime
}
} else {
= .c
if int() < {
.sendq.dequeueSudoG()
} else {
.recvq.dequeueSudoG()
}
}
= .waitlink
.waitlink = nil
releaseSudog()
=
}
if == nil {
throw("selectgo: bad wakeup")
}
= .c
if debugSelect {
print("wait-return: cas0=", , " c=", , " cas=", , " send=", < , "\n")
}
if < {
if ! {
goto
}
} else {
=
}
if raceenabled {
if < {
raceReadObjectPC(.elemtype, .elem, (), chansendpc)
} else if .elem != nil {
raceWriteObjectPC(.elemtype, .elem, (), chanrecvpc)
}
}
if msanenabled {
if < {
msanread(.elem, .elemtype.size)
} else if .elem != nil {
msanwrite(.elem, .elemtype.size)
}
}
selunlock(, )
goto
if raceenabled {
if .elem != nil {
raceWriteObjectPC(.elemtype, .elem, (), chanrecvpc)
}
racenotify(, .recvx, nil)
}
if msanenabled && .elem != nil {
msanwrite(.elem, .elemtype.size)
}
= true
= chanbuf(, .recvx)
if .elem != nil {
typedmemmove(.elemtype, .elem, )
}
typedmemclr(.elemtype, )
.recvx++
if .recvx == .dataqsiz {
.recvx = 0
}
.qcount--
selunlock(, )
goto
if raceenabled {
racenotify(, .sendx, nil)
raceReadObjectPC(.elemtype, .elem, (), chansendpc)
}
if msanenabled {
msanread(.elem, .elemtype.size)
}
typedmemmove(.elemtype, chanbuf(, .sendx), .elem)
.sendx++
if .sendx == .dataqsiz {
.sendx = 0
}
.qcount++
selunlock(, )
goto
selunlock(, )
= false
if .elem != nil {
typedmemclr(.elemtype, .elem)
}
if raceenabled {
raceacquire(.raceaddr())
}
goto
if raceenabled {
raceReadObjectPC(.elemtype, .elem, (), chansendpc)
}
if msanenabled {
msanread(.elem, .elemtype.size)
}
send(, , .elem, func() { selunlock(, ) }, 2)
if debugSelect {
print("syncsend: cas0=", , " c=", , "\n")
}
goto
:
if > 0 {
blockevent(-, 1)
}
return ,
type selectDir int
const (
_ selectDir = iota
selectSend // case Chan <- Send
selectRecv // case <-Chan:
selectDefault // default
)
if + == 0 {
return , false
}
![]() |
The pages are generated with Golds v0.3.2-preview. (GOOS=darwin GOARCH=amd64) Golds is a Go 101 project developed by Tapir Liu. PR and bug reports are welcome and can be submitted to the issue list. Please follow @Go100and1 (reachable from the left QR code) to get the latest news of Golds. |