aboutsummaryrefslogtreecommitdiff
path: root/src/runtime
diff options
context:
space:
mode:
Diffstat (limited to 'src/runtime')
-rw-r--r--src/runtime/proc1.go12
-rw-r--r--src/runtime/runtime2.go1
2 files changed, 13 insertions, 0 deletions
diff --git a/src/runtime/proc1.go b/src/runtime/proc1.go
index fccc2ac70f..788f4fd3b4 100644
--- a/src/runtime/proc1.go
+++ b/src/runtime/proc1.go
@@ -414,7 +414,13 @@ func scang(gp *g) {
// the goroutine until we're done.
if castogscanstatus(gp, s, s|_Gscan) {
if !gp.gcscandone {
+ // Coordinate with traceback
+ // in sigprof.
+ for !cas(&gp.stackLock, 0, 1) {
+ osyield()
+ }
scanstack(gp)
+ atomicstore(&gp.stackLock, 0)
gp.gcscandone = true
}
restartg(gp)
@@ -2477,6 +2483,11 @@ func sigprof(pc, sp, lr uintptr, gp *g, mp *m) {
// Profiling runs concurrently with GC, so it must not allocate.
mp.mallocing++
+ // Coordinate with stack barrier insertion in scanstack.
+ for !cas(&gp.stackLock, 0, 1) {
+ osyield()
+ }
+
// Define that a "user g" is a user-created goroutine, and a "system g"
// is one that is m->g0 or m->gsignal.
//
@@ -2580,6 +2591,7 @@ func sigprof(pc, sp, lr uintptr, gp *g, mp *m) {
}
}
}
+ atomicstore(&gp.stackLock, 0)
if prof.hz != 0 {
// Simple cas-lock to coordinate with setcpuprofilerate.
diff --git a/src/runtime/runtime2.go b/src/runtime/runtime2.go
index 0132766dd0..dc600ae578 100644
--- a/src/runtime/runtime2.go
+++ b/src/runtime/runtime2.go
@@ -230,6 +230,7 @@ type g struct {
stkbarPos uintptr // index of lowest stack barrier not hit
param unsafe.Pointer // passed parameter on wakeup
atomicstatus uint32
+ stackLock uint32 // sigprof/scang lock; TODO: fold in to atomicstatus
goid int64
waitsince int64 // approx time when the g become blocked
waitreason string // if status==Gwaiting