osyield()
}
- if prof.hz != 0 { // implies cpuprof.log != nil
+ if prof.hz.Load() != 0 { // implies cpuprof.log != nil
if p.numExtra > 0 || p.lostExtra > 0 || p.lostAtomic > 0 {
p.addExtra()
}
var prof struct {
signalLock atomic.Uint32
- hz int32
+
+ // Must hold signalLock to write. Reads may be lock-free, but
+ // signalLock should be taken to synchronize with changes.
+ hz atomic.Int32
}
func _System() { _System() }
//
//go:nowritebarrierrec
func sigprof(pc, sp, lr uintptr, gp *g, mp *m) {
- if prof.hz == 0 {
+ if prof.hz.Load() == 0 {
return
}
}
}
- if prof.hz != 0 {
+ if prof.hz.Load() != 0 {
// Note: it can happen on Windows that we interrupted a system thread
// with no g, so gp could nil. The other nil checks are done out of
// caution, but not expected to be nil in practice.
for !prof.signalLock.CompareAndSwap(0, 1) {
osyield()
}
- if prof.hz != hz {
+ if prof.hz.Load() != hz {
setProcessCPUProfiler(hz)
- prof.hz = hz
+ prof.hz.Store(hz)
}
prof.signalLock.Store(0)
//go:nosplit
//go:nowritebarrierrec
func sigprofNonGo(sig uint32, info *siginfo, ctx unsafe.Pointer) {
- if prof.hz != 0 {
+ if prof.hz.Load() != 0 {
c := &sigctxt{info, ctx}
// Some platforms (Linux) have per-thread timers, which we use in
// combination with the process-wide timer. Avoid double-counting.
//go:nosplit
//go:nowritebarrierrec
func sigprofNonGoPC(pc uintptr) {
- if prof.hz != 0 {
+ if prof.hz.Load() != 0 {
stk := []uintptr{
pc,
abi.FuncPCABIInternal(_ExternalCode) + sys.PCQuantum,