mirror of
https://github.com/tinygo-org/tinygo.git
synced 2026-08-18 11:33:59 +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)
|
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.
|
// Scan the stack(s) of the current core.
|
||||||
scanCurrentStack()
|
scanCurrentStack()
|
||||||
if !task.OnSystemStack() {
|
if !task.OnSystemStack() {
|
||||||
@@ -53,13 +59,6 @@ func gcMarkReachable() {
|
|||||||
// Scan globals.
|
// Scan globals.
|
||||||
findGlobals(markRoots)
|
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.
|
// Signal each core in turn that they can scan the stack.
|
||||||
for i := uint32(0); i < numCPU; i++ {
|
for i := uint32(0); i < numCPU; i++ {
|
||||||
if i == core {
|
if i == core {
|
||||||
|
|||||||
Reference in New Issue
Block a user