gopc uintptr // pc of go statement that created this goroutine
startpc uintptr // pc of goroutine function
racectx uintptr
- waiting *sudog // sudog structures this g is waiting on (that have a valid elem ptr)
+ waiting *sudog // sudog structures this g is waiting on (that have a valid elem ptr); in lock order
// Per-G gcController state
sglist *sudog
sgnext *sudog
qp unsafe.Pointer
+ nextp **sudog
)
loop:
if gp.waiting != nil {
throw("gp.waiting != nil")
}
- for i := 0; i < int(sel.ncase); i++ {
- cas = &scases[pollorder[i]]
+ nextp = &gp.waiting
+ for _, casei := range lockorder {
+ cas = &scases[casei]
c = cas.c
sg := acquireSudog()
sg.g = gp
if t0 != 0 {
sg.releasetime = -1
}
- sg.waitlink = gp.waiting
sg.c = c
- gp.waiting = sg
+ // Construct waiting list in lock order.
+ *nextp = sg
+ nextp = &sg.waitlink
switch cas.kind {
case caseRecv:
// pass 3 - dequeue from unsuccessful chans
// otherwise they stack up on quiet channels
// record the successful case, if any.
- // We singly-linked up the SudoGs in case order, so when
- // iterating through the linked list they are in reverse order.
+ // We singly-linked up the SudoGs in lock order.
cas = nil
sglist = gp.waiting
// Clear all elem before unlinking from gp.waiting.
sg1.c = nil
}
gp.waiting = nil
- for i := int(sel.ncase) - 1; i >= 0; i-- {
- k = &scases[pollorder[i]]
+
+ for _, casei := range lockorder {
+ k = &scases[casei]
if sglist.releasetime > 0 {
k.releasetime = sglist.releasetime
}