Skip to content

Commit f7d8502

Browse files
aykevldeadprogram
authored andcommitted
runtime: don't try to interrupt other cores before they are started
The GC shouldn't try to interrupt other cores before they are started. For example, it would be possible for the GC to run in a package initializer (which is currently run on a single core). That would suggest questionable program design, but it is something that should work. So this commit makes sure the GC only tries to scan the stack of other cores when those other cores have in fact started.
1 parent e395c94 commit f7d8502

File tree

2 files changed

+27
-0
lines changed

2 files changed

+27
-0
lines changed

src/runtime/gc_stack_cores.go

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,24 @@ var gcScanState atomic.Uint32
1414
// Start GC scan by pausing the world (all other cores) and scanning their
1515
// stacks. It doesn't resume the world.
1616
func gcMarkReachable() {
17+
// If the other cores haven't started yet (for example, when a GC cycle
18+
// happens during init()), we only need to scan the stack of the current
19+
// core.
20+
if !secondaryCoresStarted {
21+
// Scan the stack(s) of the current core.
22+
scanCurrentStack()
23+
if !task.OnSystemStack() {
24+
// Mark system stack.
25+
markRoots(task.SystemStack(), stackTop)
26+
}
27+
28+
// Scan globals.
29+
findGlobals(markRoots)
30+
31+
// Nothing more to do: the other cores haven't started yet.
32+
return
33+
}
34+
1735
core := currentCPU()
1836

1937
// Interrupt all other cores.
@@ -81,6 +99,11 @@ func scanstack(sp uintptr) {
8199

82100
// Resume the world after a call to gcMarkReachable.
83101
func gcResumeWorld() {
102+
if !secondaryCoresStarted {
103+
// Nothing to do: the world wasn't stopped in gcMarkReachable.
104+
return
105+
}
106+
84107
// Signal each core that they can resume.
85108
hartID := currentCPU()
86109
for i := uint32(0); i < numCPU; i++ {

src/runtime/scheduler_cores.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,9 @@ const hasParallelism = true
1414

1515
var mainExited atomic.Uint32
1616

17+
// True after the secondary cores have started.
18+
var secondaryCoresStarted bool
19+
1720
// Which task is running on a given core (or nil if there is no task running on
1821
// the core).
1922
var cpuTasks [numCPU]*task.Task
@@ -141,6 +144,7 @@ func run() {
141144

142145
// After package initializers have finished, start all the other cores.
143146
startSecondaryCores()
147+
secondaryCoresStarted = true
144148

145149
// Run main.main.
146150
callMain()

0 commit comments

Comments
 (0)