1 //go:build scheduler.tasks
2 3 package task
4 5 import "runtime/interrupt"
6 7 // currentTask is the current running task, or nil if currently in the scheduler.
8 var currentTask *Task
9 10 // Current returns the current active task.
11 func Current() *Task {
12 return currentTask
13 }
14 15 // Pause suspends the current task and returns to the scheduler.
16 // This function may only be called when running on a goroutine stack, not when running on the system stack or in an interrupt.
17 func Pause() {
18 // Check whether the canary (the lowest address of the stack) is still
19 // valid. If it is not, a stack overflow has occurred.
20 if *currentTask.state.canaryPtr != stackCanary {
21 runtimePanic("goroutine stack overflow")
22 }
23 if interrupt.In() {
24 runtimePanic("blocked inside interrupt")
25 }
26 currentTask.state.pause()
27 }
28 29 // Resume the task until it pauses or completes.
30 // This may only be called from the scheduler.
31 func (t *Task) Resume() {
32 currentTask = t
33 t.gcData.swap()
34 t.state.resume()
35 t.gcData.swap()
36 currentTask = nil
37 }
38