Skip to content

Commit e4fc3bb

Browse files
aykevldeadprogram
authored andcommitted
compiler,runtime: fix new task-based scheduler
A bug was introduced in the previous commit that led to miscompilations in the time.Sleep function when the scheduler was disabled, because time.Sleep (implemented in the runtime) tried to switch to the scheduler stack. This commit restores the binary size of most examples to what it was before, but still reduces static RAM consumption (.bss) slightly. This gives me some confidence that it does indeed fix the introduced bug.
1 parent 542135c commit e4fc3bb

File tree

3 files changed

+11
-0
lines changed

3 files changed

+11
-0
lines changed

compiler/compiler.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ var functionsUsedInTransforms = []string{
3737
"runtime.alloc",
3838
"runtime.free",
3939
"runtime.sleepTask",
40+
"runtime.sleepCurrentTask",
4041
"runtime.setTaskStatePtr",
4142
"runtime.getTaskStatePtr",
4243
"runtime.activateTask",

compiler/goroutine-lowering.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,10 @@ func (c *Compiler) lowerTasks() error {
150150
zero := llvm.ConstInt(c.uintptrType, 0, false)
151151
c.createRuntimeCall("startGoroutine", []llvm.Value{realMainWrapper, zero}, "")
152152
c.createRuntimeCall("scheduler", nil, "")
153+
sleep := c.mod.NamedFunction("time.Sleep")
154+
if !sleep.IsNil() {
155+
sleep.ReplaceAllUsesWith(c.mod.NamedFunction("runtime.sleepCurrentTask"))
156+
}
153157
} else {
154158
// Program doesn't need a scheduler. Call main.main directly.
155159
c.builder.SetInsertPointBefore(mainCall)

src/runtime/scheduler_tasks.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,12 @@ func startGoroutine(fn, args uintptr) {
9898

9999
//go:linkname sleep time.Sleep
100100
func sleep(d int64) {
101+
sleepTicks(timeUnit(d / tickMicros))
102+
}
103+
104+
// sleepCurrentTask suspends the current goroutine. This is a compiler
105+
// intrinsic. It replaces calls to time.Sleep when a scheduler is in use.
106+
func sleepCurrentTask(d int64) {
101107
sleepTask(currentTask, d)
102108
swapTask(currentTask, &schedulerState)
103109
}

0 commit comments

Comments
 (0)