Commit e9f90ba2 authored by Keith Randall's avatar Keith Randall

Revert "runtime: simplify buffered channels."

Revert for now until #13169 is understood.

This reverts commit 8e496f1d.

Change-Id: Ib3eb2588824ef47a2b6eb9e377a24e5c817fcc81
Reviewed-on: https://go-review.googlesource.com/16716Reviewed-by: default avatarKeith Randall <khr@golang.org>
parent 26263354
This diff is collapsed.
...@@ -304,7 +304,7 @@ func selectgoImpl(sel *hselect) (uintptr, uint16) { ...@@ -304,7 +304,7 @@ func selectgoImpl(sel *hselect) (uintptr, uint16) {
k *scase k *scase
sglist *sudog sglist *sudog
sgnext *sudog sgnext *sudog
qp unsafe.Pointer futile byte
) )
loop: loop:
...@@ -317,12 +317,15 @@ loop: ...@@ -317,12 +317,15 @@ loop:
switch cas.kind { switch cas.kind {
case caseRecv: case caseRecv:
if c.dataqsiz > 0 {
if c.qcount > 0 {
goto asyncrecv
}
} else {
sg = c.sendq.dequeue() sg = c.sendq.dequeue()
if sg != nil { if sg != nil {
goto recv goto syncrecv
} }
if c.qcount > 0 {
goto bufrecv
} }
if c.closed != 0 { if c.closed != 0 {
goto rclose goto rclose
...@@ -335,12 +338,15 @@ loop: ...@@ -335,12 +338,15 @@ loop:
if c.closed != 0 { if c.closed != 0 {
goto sclose goto sclose
} }
if c.dataqsiz > 0 {
if c.qcount < c.dataqsiz {
goto asyncsend
}
} else {
sg = c.recvq.dequeue() sg = c.recvq.dequeue()
if sg != nil { if sg != nil {
goto send goto syncsend
} }
if c.qcount < c.dataqsiz {
goto bufsend
} }
case caseDefault: case caseDefault:
...@@ -357,9 +363,6 @@ loop: ...@@ -357,9 +363,6 @@ loop:
// pass 2 - enqueue on all chans // pass 2 - enqueue on all chans
gp = getg() gp = getg()
done = 0 done = 0
if gp.waiting != nil {
throw("gp.waiting != nil")
}
for i := 0; i < int(sel.ncase); i++ { for i := 0; i < int(sel.ncase); i++ {
cas = &scases[pollorder[i]] cas = &scases[pollorder[i]]
c = cas.c c = cas.c
...@@ -386,7 +389,7 @@ loop: ...@@ -386,7 +389,7 @@ loop:
// wait for someone to wake us up // wait for someone to wake us up
gp.param = nil gp.param = nil
gopark(selparkcommit, unsafe.Pointer(sel), "select", traceEvGoBlockSelect, 2) gopark(selparkcommit, unsafe.Pointer(sel), "select", traceEvGoBlockSelect|futile, 2)
// someone woke us up // someone woke us up
sellock(sel) sellock(sel)
...@@ -429,13 +432,16 @@ loop: ...@@ -429,13 +432,16 @@ loop:
} }
if cas == nil { if cas == nil {
// This can happen if we were woken up by a close(). futile = traceFutileWakeup
// TODO: figure that out explicitly so we don't need this loop.
goto loop goto loop
} }
c = cas.c c = cas.c
if c.dataqsiz > 0 {
throw("selectgo: shouldn't happen")
}
if debugSelect { if debugSelect {
print("wait-return: sel=", sel, " c=", c, " cas=", cas, " kind=", cas.kind, "\n") print("wait-return: sel=", sel, " c=", c, " cas=", cas, " kind=", cas.kind, "\n")
} }
...@@ -464,7 +470,7 @@ loop: ...@@ -464,7 +470,7 @@ loop:
selunlock(sel) selunlock(sel)
goto retc goto retc
bufrecv: asyncrecv:
// can receive from buffer // can receive from buffer
if raceenabled { if raceenabled {
if cas.elem != nil { if cas.elem != nil {
...@@ -479,20 +485,29 @@ bufrecv: ...@@ -479,20 +485,29 @@ bufrecv:
if cas.receivedp != nil { if cas.receivedp != nil {
*cas.receivedp = true *cas.receivedp = true
} }
qp = chanbuf(c, c.recvx)
if cas.elem != nil { if cas.elem != nil {
typedmemmove(c.elemtype, cas.elem, qp) typedmemmove(c.elemtype, cas.elem, chanbuf(c, c.recvx))
} }
memclr(qp, uintptr(c.elemsize)) memclr(chanbuf(c, c.recvx), uintptr(c.elemsize))
c.recvx++ c.recvx++
if c.recvx == c.dataqsiz { if c.recvx == c.dataqsiz {
c.recvx = 0 c.recvx = 0
} }
c.qcount-- c.qcount--
sg = c.sendq.dequeue()
if sg != nil {
gp = sg.g
selunlock(sel)
if sg.releasetime != 0 {
sg.releasetime = cputicks()
}
goready(gp, 3)
} else {
selunlock(sel) selunlock(sel)
}
goto retc goto retc
bufsend: asyncsend:
// can send to buffer // can send to buffer
if raceenabled { if raceenabled {
raceacquire(chanbuf(c, c.sendx)) raceacquire(chanbuf(c, c.sendx))
...@@ -508,18 +523,47 @@ bufsend: ...@@ -508,18 +523,47 @@ bufsend:
c.sendx = 0 c.sendx = 0
} }
c.qcount++ c.qcount++
sg = c.recvq.dequeue()
if sg != nil {
gp = sg.g
selunlock(sel) selunlock(sel)
if sg.releasetime != 0 {
sg.releasetime = cputicks()
}
goready(gp, 3)
} else {
selunlock(sel)
}
goto retc goto retc
recv: syncrecv:
// can receive from sleeping sender (sg) // can receive from sleeping sender (sg)
recv(c, sg, cas.elem, func() { selunlock(sel) }) if raceenabled {
if cas.elem != nil {
raceWriteObjectPC(c.elemtype, cas.elem, cas.pc, chanrecvpc)
}
racesync(c, sg)
}
if msanenabled && cas.elem != nil {
msanwrite(cas.elem, c.elemtype.size)
}
selunlock(sel)
if debugSelect { if debugSelect {
print("syncrecv: sel=", sel, " c=", c, "\n") print("syncrecv: sel=", sel, " c=", c, "\n")
} }
if cas.receivedp != nil { if cas.receivedp != nil {
*cas.receivedp = true *cas.receivedp = true
} }
if cas.elem != nil {
typedmemmove(c.elemtype, cas.elem, sg.elem)
}
sg.elem = nil
gp = sg.g
gp.param = unsafe.Pointer(sg)
if sg.releasetime != 0 {
sg.releasetime = cputicks()
}
goready(gp, 3)
goto retc goto retc
rclose: rclose:
...@@ -536,19 +580,29 @@ rclose: ...@@ -536,19 +580,29 @@ rclose:
} }
goto retc goto retc
send: syncsend:
// can send to a sleeping receiver (sg) // can send to sleeping receiver (sg)
if raceenabled { if raceenabled {
raceReadObjectPC(c.elemtype, cas.elem, cas.pc, chansendpc) raceReadObjectPC(c.elemtype, cas.elem, cas.pc, chansendpc)
racesync(c, sg)
} }
if msanenabled { if msanenabled {
msanread(cas.elem, c.elemtype.size) msanread(cas.elem, c.elemtype.size)
} }
send(c, sg, cas.elem, func() { selunlock(sel) }) selunlock(sel)
if debugSelect { if debugSelect {
print("syncsend: sel=", sel, " c=", c, "\n") print("syncsend: sel=", sel, " c=", c, "\n")
} }
goto retc if sg.elem != nil {
syncsend(c, sg, cas.elem)
}
sg.elem = nil
gp = sg.g
gp.param = unsafe.Pointer(sg)
if sg.releasetime != 0 {
sg.releasetime = cputicks()
}
goready(gp, 3)
retc: retc:
if cas.releasetime > 0 { if cas.releasetime > 0 {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment