github.com/tinygo-org/tinygo@v0.31.3-0.20240404173401-90b0bf646c27/src/internal/task/task_stack_arm64.go (about) 1 //go:build scheduler.tasks && arm64 2 3 package task 4 5 import "unsafe" 6 7 var systemStack uintptr 8 9 // calleeSavedRegs is the list of registers that must be saved and restored when 10 // switching between tasks. Also see task_stack_arm64.S that relies on the exact 11 // layout of this struct. 12 type calleeSavedRegs struct { 13 x19 uintptr 14 x20 uintptr 15 x21 uintptr 16 x22 uintptr 17 x23 uintptr 18 x24 uintptr 19 x25 uintptr 20 x26 uintptr 21 x27 uintptr 22 x28 uintptr 23 x29 uintptr 24 pc uintptr // aka x30 aka LR 25 26 d8 uintptr 27 d9 uintptr 28 d10 uintptr 29 d11 uintptr 30 d12 uintptr 31 d13 uintptr 32 d14 uintptr 33 d15 uintptr 34 } 35 36 // archInit runs architecture-specific setup for the goroutine startup. 37 func (s *state) archInit(r *calleeSavedRegs, fn uintptr, args unsafe.Pointer) { 38 // Store the initial sp for the startTask function (implemented in assembly). 39 s.sp = uintptr(unsafe.Pointer(r)) 40 41 // Initialize the registers. 42 // These will be popped off of the stack on the first resume of the goroutine. 43 44 // Start the function at tinygo_startTask (defined in src/internal/task/task_stack_arm64.S). 45 // This assembly code calls a function (passed in x19) with a single argument 46 // (passed in x20). After the function returns, it calls Pause(). 47 r.pc = uintptr(unsafe.Pointer(&startTask)) 48 49 // Pass the function to call in x19. 50 // This function is a compiler-generated wrapper which loads arguments out of a struct pointer. 51 // See createGoroutineStartWrapper (defined in compiler/goroutine.go) for more information. 52 r.x19 = fn 53 54 // Pass the pointer to the arguments struct in x20. 55 r.x20 = uintptr(args) 56 } 57 58 func (s *state) resume() { 59 swapTask(s.sp, &systemStack) 60 } 61 62 func (s *state) pause() { 63 newStack := systemStack 64 systemStack = 0 65 swapTask(newStack, &s.sp) 66 } 67 68 // SystemStack returns the system stack pointer when called from a task stack. 69 // When called from the system stack, it returns 0. 70 func SystemStack() uintptr { 71 return systemStack 72 }