For #53821.
Change-Id: I93409f377881a3c029b41b0f1fbcef5e21091f2f
Reviewed-on: https://go-review.googlesource.com/c/go/+/419438
Reviewed-by: Austin Clements <austin@google.com>
Run-TryBot: Michael Pratt <mpratt@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
// that the exit condition for the _GCoff phase has been met. The exit
// condition should be tested when allocating.
func (t gcTrigger) test() bool {
- if !memstats.enablegc || panicking != 0 || gcphase != _GCoff {
+ if !memstats.enablegc || panicking.Load() != 0 || gcphase != _GCoff {
return false
}
switch t.kind {
var runningPanicDefers atomic.Uint32
// panicking is non-zero when crashing the program for an unrecovered panic.
-// panicking is incremented and decremented atomically.
-var panicking uint32
+var panicking atomic.Uint32
// paniclk is held while printing the panic information and stack trace,
// so that two concurrent panics don't overlap their output.
case 0:
// Setting dying >0 has the side-effect of disabling this G's writebuf.
gp.m.dying = 1
- atomic.Xadd(&panicking, 1)
+ panicking.Add(1)
lock(&paniclk)
if debug.schedtrace > 0 || debug.scheddetail > 0 {
schedtrace(true)
}
unlock(&paniclk)
- if atomic.Xadd(&panicking, -1) != 0 {
+ if panicking.Add(-1) != 0 {
// Some other m is panicking too.
// Let it print what it needs to print.
// Wait forever without chewing up cpu.
import (
"internal/goarch"
- "runtime/internal/atomic"
"unsafe"
)
func recordForPanic(b []byte) {
printlock()
- if atomic.Load(&panicking) == 0 {
+ if panicking.Load() == 0 {
// Not actively crashing: maintain circular buffer of print output.
for i := 0; i < len(b); {
n := copy(printBacklog[printBacklogIndex:], b[i:])
Gosched()
}
}
- if atomic.Load(&panicking) != 0 {
+ if panicking.Load() != 0 {
gopark(nil, nil, waitReasonPanicWait, traceEvGoStop, 1)
}
// freezetheworld will cause all running threads to block.
// And runtime will essentially enter into deadlock state,
// except that there is a thread that will call exit soon.
- if panicking > 0 {
+ if panicking.Load() > 0 {
return
}
func winthrow(info *exceptionrecord, r *context, gp *g) {
g0 := getg()
- if panicking != 0 { // traceback already printed
+ if panicking.Load() != 0 { // traceback already printed
exit(2)
}
- panicking = 1
+ panicking.Store(1)
// In case we're handling a g0 stack overflow, blow away the
// g0 stack bounds so we have room to print the traceback. If
}
if !f.valid() {
- if strict && panicking == 0 {
+ if strict && panicking.Load() == 0 {
println("runtime: no module data for", hex(f.entry()))
throw("no module data")
}
// If there was a table, it should have covered all program counters.
// If not, something is wrong.
- if panicking != 0 || !strict {
+ if panicking.Load() != 0 || !strict {
return -1, 0
}
// callCgoSymbolizer calls the cgoSymbolizer function.
func callCgoSymbolizer(arg *cgoSymbolizerArg) {
call := cgocall
- if panicking > 0 || getg().m.curg != getg() {
+ if panicking.Load() > 0 || getg().m.curg != getg() {
// We do not want to call into the scheduler when panicking
// or when on the system stack.
call = asmcgocall
return
}
call := cgocall
- if panicking > 0 || getg().m.curg != getg() {
+ if panicking.Load() > 0 || getg().m.curg != getg() {
// We do not want to call into the scheduler when panicking
// or when on the system stack.
call = asmcgocall