]> Cypherpunks.ru repositories - gostls13.git/commitdiff
runtime: convert prof.hz to atomic type
authorMichael Pratt <mpratt@google.com>
Fri, 29 Jul 2022 18:48:48 +0000 (14:48 -0400)
committerMichael Pratt <mpratt@google.com>
Fri, 12 Aug 2022 01:53:44 +0000 (01:53 +0000)
This converts several unsynchronized reads (reads without holding
prof.signalLock) into atomic reads.

For #53821.
For #52912.

Change-Id: I421b96a22fbe26d699bcc21010c8a9e0f4efc276
Reviewed-on: https://go-review.googlesource.com/c/go/+/420196
Reviewed-by: Austin Clements <austin@google.com>
Run-TryBot: Michael Pratt <mpratt@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>

src/runtime/cpuprof.go
src/runtime/proc.go
src/runtime/signal_unix.go

index 221e021a3762abffeb594dd65e785e7ae2e8cbd6..6ef374eaa429ad9ae9368688fbc1b94dd618cd32 100644 (file)
@@ -110,7 +110,7 @@ func (p *cpuProfile) add(tagPtr *unsafe.Pointer, stk []uintptr) {
                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()
                }
index a673e4507121ce0eb844940a5558a650350dc20d..04484da53f10b2f6798414a4b202a03bea06920f 100644 (file)
@@ -4475,7 +4475,10 @@ func mcount() int32 {
 
 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() }
@@ -4490,7 +4493,7 @@ func _VDSO()                      { _VDSO() }
 //
 //go:nowritebarrierrec
 func sigprof(pc, sp, lr uintptr, gp *g, mp *m) {
-       if prof.hz == 0 {
+       if prof.hz.Load() == 0 {
                return
        }
 
@@ -4587,7 +4590,7 @@ func sigprof(pc, sp, lr uintptr, gp *g, mp *m) {
                }
        }
 
-       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.
@@ -4631,9 +4634,9 @@ func setcpuprofilerate(hz int32) {
        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)
 
index 545fe6abce6d0d74d2da78da0256b62d7cf99522..66a4650b5819449370debeaac20bd541da746114 100644 (file)
@@ -502,7 +502,7 @@ var sigprofCallersUse uint32
 //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.
@@ -525,7 +525,7 @@ func sigprofNonGo(sig uint32, info *siginfo, ctx unsafe.Pointer) {
 //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,