mirror of
https://github.com/tinygo-org/tinygo.git
synced 2026-08-09 21:43:40 +00:00
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.
This commit is contained in:
committed by
Ron Evans
parent
213d10838f
commit
7a9c649268
@@ -43,6 +43,12 @@ func gcMarkReachable() {
|
||||
gcPauseCore(i)
|
||||
}
|
||||
|
||||
// Busy-wait until all the other cores are ready.
|
||||
for gcScanState.Load() != numCPU {
|
||||
spinLoopWait()
|
||||
}
|
||||
gcScanState.Store(0)
|
||||
|
||||
// Scan the stack(s) of the current core.
|
||||
scanCurrentStack()
|
||||
if !task.OnSystemStack() {
|
||||
@@ -53,13 +59,6 @@ func gcMarkReachable() {
|
||||
// Scan globals.
|
||||
findGlobals(markRoots)
|
||||
|
||||
// Busy-wait until all the other cores are ready. They certainly should be,
|
||||
// after the scanning we did above.
|
||||
for gcScanState.Load() != numCPU {
|
||||
spinLoopWait()
|
||||
}
|
||||
gcScanState.Store(0)
|
||||
|
||||
// Signal each core in turn that they can scan the stack.
|
||||
for i := uint32(0); i < numCPU; i++ {
|
||||
if i == core {
|
||||
|
||||
Reference in New Issue
Block a user