1
0
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:
cuiweixie 2022-08-26 11:16:52 +08:00 committed by Michael Knyszek
parent a25a34abe9
commit d01200e772

View File

@ -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()
} }
} }