mirror of
https://github.com/golang/go
synced 2024-11-23 14:50:07 -07:00
runtime: convert sig.{state,delivering} to atomic type
For #53821 Change-Id: I1c8df255ce9e2345d4fa45bd4d1761b73b9fa064 Reviewed-on: https://go-review.googlesource.com/c/go/+/425780 Reviewed-by: Michael Knyszek <mknyszek@google.com> Reviewed-by: Michael Pratt <mpratt@google.com> Run-TryBot: Michael Pratt <mpratt@google.com> TryBot-Result: Gopher Robot <gobot@golang.org>
This commit is contained in:
parent
a25a34abe9
commit
d01200e772
@ -54,8 +54,8 @@ var sig struct {
|
|||||||
wanted [(_NSIG + 31) / 32]uint32
|
wanted [(_NSIG + 31) / 32]uint32
|
||||||
ignored [(_NSIG + 31) / 32]uint32
|
ignored [(_NSIG + 31) / 32]uint32
|
||||||
recv [(_NSIG + 31) / 32]uint32
|
recv [(_NSIG + 31) / 32]uint32
|
||||||
state uint32
|
state atomic.Uint32
|
||||||
delivering uint32
|
delivering atomic.Uint32
|
||||||
inuse bool
|
inuse bool
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -74,11 +74,11 @@ func sigsend(s uint32) bool {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
atomic.Xadd(&sig.delivering, 1)
|
sig.delivering.Add(1)
|
||||||
// We are running in the signal handler; defer is not available.
|
// We are running in the signal handler; defer is not available.
|
||||||
|
|
||||||
if w := atomic.Load(&sig.wanted[s/32]); w&bit == 0 {
|
if w := atomic.Load(&sig.wanted[s/32]); w&bit == 0 {
|
||||||
atomic.Xadd(&sig.delivering, -1)
|
sig.delivering.Add(-1)
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -86,7 +86,7 @@ func sigsend(s uint32) bool {
|
|||||||
for {
|
for {
|
||||||
mask := sig.mask[s/32]
|
mask := sig.mask[s/32]
|
||||||
if mask&bit != 0 {
|
if mask&bit != 0 {
|
||||||
atomic.Xadd(&sig.delivering, -1)
|
sig.delivering.Add(-1)
|
||||||
return true // signal already in queue
|
return true // signal already in queue
|
||||||
}
|
}
|
||||||
if atomic.Cas(&sig.mask[s/32], mask, mask|bit) {
|
if atomic.Cas(&sig.mask[s/32], mask, mask|bit) {
|
||||||
@ -97,18 +97,18 @@ func sigsend(s uint32) bool {
|
|||||||
// Notify receiver that queue has new bit.
|
// Notify receiver that queue has new bit.
|
||||||
Send:
|
Send:
|
||||||
for {
|
for {
|
||||||
switch atomic.Load(&sig.state) {
|
switch sig.state.Load() {
|
||||||
default:
|
default:
|
||||||
throw("sigsend: inconsistent state")
|
throw("sigsend: inconsistent state")
|
||||||
case sigIdle:
|
case sigIdle:
|
||||||
if atomic.Cas(&sig.state, sigIdle, sigSending) {
|
if sig.state.CompareAndSwap(sigIdle, sigSending) {
|
||||||
break Send
|
break Send
|
||||||
}
|
}
|
||||||
case sigSending:
|
case sigSending:
|
||||||
// notification already pending
|
// notification already pending
|
||||||
break Send
|
break Send
|
||||||
case sigReceiving:
|
case sigReceiving:
|
||||||
if atomic.Cas(&sig.state, sigReceiving, sigIdle) {
|
if sig.state.CompareAndSwap(sigReceiving, sigIdle) {
|
||||||
if GOOS == "darwin" || GOOS == "ios" {
|
if GOOS == "darwin" || GOOS == "ios" {
|
||||||
sigNoteWakeup(&sig.note)
|
sigNoteWakeup(&sig.note)
|
||||||
break Send
|
break Send
|
||||||
@ -119,7 +119,7 @@ Send:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
atomic.Xadd(&sig.delivering, -1)
|
sig.delivering.Add(-1)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -140,11 +140,11 @@ func signal_recv() uint32 {
|
|||||||
// Wait for updates to be available from signal sender.
|
// Wait for updates to be available from signal sender.
|
||||||
Receive:
|
Receive:
|
||||||
for {
|
for {
|
||||||
switch atomic.Load(&sig.state) {
|
switch sig.state.Load() {
|
||||||
default:
|
default:
|
||||||
throw("signal_recv: inconsistent state")
|
throw("signal_recv: inconsistent state")
|
||||||
case sigIdle:
|
case sigIdle:
|
||||||
if atomic.Cas(&sig.state, sigIdle, sigReceiving) {
|
if sig.state.CompareAndSwap(sigIdle, sigReceiving) {
|
||||||
if GOOS == "darwin" || GOOS == "ios" {
|
if GOOS == "darwin" || GOOS == "ios" {
|
||||||
sigNoteSleep(&sig.note)
|
sigNoteSleep(&sig.note)
|
||||||
break Receive
|
break Receive
|
||||||
@ -154,7 +154,7 @@ func signal_recv() uint32 {
|
|||||||
break Receive
|
break Receive
|
||||||
}
|
}
|
||||||
case sigSending:
|
case sigSending:
|
||||||
if atomic.Cas(&sig.state, sigSending, sigIdle) {
|
if sig.state.CompareAndSwap(sigSending, sigIdle) {
|
||||||
break Receive
|
break Receive
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -182,14 +182,14 @@ func signalWaitUntilIdle() {
|
|||||||
// a signal, has read from sig.wanted, is now updating sig.mask,
|
// a signal, has read from sig.wanted, is now updating sig.mask,
|
||||||
// and has not yet woken up the processor thread. We need to wait
|
// and has not yet woken up the processor thread. We need to wait
|
||||||
// until all current signal deliveries have completed.
|
// until all current signal deliveries have completed.
|
||||||
for atomic.Load(&sig.delivering) != 0 {
|
for sig.delivering.Load() != 0 {
|
||||||
Gosched()
|
Gosched()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Although WaitUntilIdle seems like the right name for this
|
// Although WaitUntilIdle seems like the right name for this
|
||||||
// function, the state we are looking for is sigReceiving, not
|
// function, the state we are looking for is sigReceiving, not
|
||||||
// sigIdle. The sigIdle state is really more like sigProcessing.
|
// sigIdle. The sigIdle state is really more like sigProcessing.
|
||||||
for atomic.Load(&sig.state) != sigReceiving {
|
for sig.state.Load() != sigReceiving {
|
||||||
Gosched()
|
Gosched()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user