Skip to content

Commit 804338c

Browse files
committed
fix(gc): pause all cores before scanning stack and globals.
In gcMarkReachable, busy-wait for other cores to enter the interrupt handler and pause before scanning the GC core's stack or globals. Prevents data race where a running core relocates heap references to globals during mark phase.
1 parent 6737fec commit 804338c

1 file changed

Lines changed: 6 additions & 7 deletions

File tree

src/runtime/gc_stack_cores.go

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,12 @@ func gcMarkReachable() {
4343
gcPauseCore(i)
4444
}
4545

46+
// Busy-wait until all the other cores are ready.
47+
for gcScanState.Load() != numCPU {
48+
spinLoopWait()
49+
}
50+
gcScanState.Store(0)
51+
4652
// Scan the stack(s) of the current core.
4753
scanCurrentStack()
4854
if !task.OnSystemStack() {
@@ -53,13 +59,6 @@ func gcMarkReachable() {
5359
// Scan globals.
5460
findGlobals(markRoots)
5561

56-
// Busy-wait until all the other cores are ready. They certainly should be,
57-
// after the scanning we did above.
58-
for gcScanState.Load() != numCPU {
59-
spinLoopWait()
60-
}
61-
gcScanState.Store(0)
62-
6362
// Signal each core in turn that they can scan the stack.
6463
for i := uint32(0); i < numCPU; i++ {
6564
if i == core {

0 commit comments

Comments
 (0)