runtime: convert m.preemptGen to atomic type

Updates #53821

Change-Id: I134dac3b1eb35f2da00e5ef8f4c264f08d4f65b6
Reviewed-on: https://go-review.googlesource.com/c/go/+/423887
Reviewed-by: Keith Randall <khr@google.com>
Reviewed-by: Michael Pratt <mpratt@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Run-TryBot: Cuong Manh Le <cuong.manhle.vn@gmail.com>
Auto-Submit: Cuong Manh Le <cuong.manhle.vn@gmail.com>
This commit is contained in:
Cuong Manh Le 2022-08-17 17:36:12 +07:00
parent 7e7ecf5cbb
commit bc805795bd
4 changed files with 9 additions and 10 deletions

View file

@ -1326,7 +1326,7 @@ func preemptM(mp *m) {
if !atomic.Cas(&mp.preemptExtLock, 0, 1) {
// External code is running. Fail the preemption
// attempt.
atomic.Xadd(&mp.preemptGen, 1)
mp.preemptGen.Add(1)
return
}
@ -1336,7 +1336,7 @@ func preemptM(mp *m) {
// The M hasn't been minit'd yet (or was just unminit'd).
unlock(&mp.threadLock)
atomic.Store(&mp.preemptExtLock, 0)
atomic.Xadd(&mp.preemptGen, 1)
mp.preemptGen.Add(1)
return
}
var thread uintptr
@ -1366,7 +1366,7 @@ func preemptM(mp *m) {
atomic.Store(&mp.preemptExtLock, 0)
// The thread no longer exists. This shouldn't be
// possible, but just acknowledge the request.
atomic.Xadd(&mp.preemptGen, 1)
mp.preemptGen.Add(1)
return
}
@ -1431,7 +1431,7 @@ func preemptM(mp *m) {
atomic.Store(&mp.preemptExtLock, 0)
// Acknowledge the preemption.
atomic.Xadd(&mp.preemptGen, 1)
mp.preemptGen.Add(1)
stdcall1(_ResumeThread, thread)
stdcall1(_CloseHandle, thread)

View file

@ -55,7 +55,6 @@ package runtime
import (
"internal/abi"
"internal/goarch"
"runtime/internal/atomic"
)
type suspendGState struct {
@ -192,7 +191,7 @@ func suspendG(gp *g) suspendGState {
case _Grunning:
// Optimization: if there is already a pending preemption request
// (from the previous loop iteration), don't bother with the atomics.
if gp.preemptStop && gp.preempt && gp.stackguard0 == stackPreempt && asyncM == gp.m && atomic.Load(&asyncM.preemptGen) == asyncGen {
if gp.preemptStop && gp.preempt && gp.stackguard0 == stackPreempt && asyncM == gp.m && asyncM.preemptGen.Load() == asyncGen {
break
}
@ -208,7 +207,7 @@ func suspendG(gp *g) suspendGState {
// Prepare for asynchronous preemption.
asyncM2 := gp.m
asyncGen2 := atomic.Load(&asyncM2.preemptGen)
asyncGen2 := asyncM2.preemptGen.Load()
needAsync := asyncM != asyncM2 || asyncGen != asyncGen2
asyncM = asyncM2
asyncGen = asyncGen2

View file

@ -583,8 +583,8 @@ type m struct {
// preemptGen counts the number of completed preemption
// signals. This is used to detect when a preemption is
// requested, but fails. Accessed atomically.
preemptGen uint32
// requested, but fails.
preemptGen atomic.Uint32
// Whether this is a pending preemption signal on this M.
signalPending atomic.Uint32

View file

@ -349,7 +349,7 @@ func doSigPreempt(gp *g, ctxt *sigctxt) {
}
// Acknowledge the preemption.
atomic.Xadd(&gp.m.preemptGen, 1)
gp.m.preemptGen.Add(1)
gp.m.signalPending.Store(0)
if GOOS == "darwin" || GOOS == "ios" {