mirror of
https://github.com/tinygo-org/tinygo.git
synced 2026-08-04 11:07:46 +00:00
3767decf9e
This is not a scheduler in the runtime, instead every goroutine is mapped to a single OS thread - meaning 1:1 scheduling. While this may not perform well (or at all) for large numbers of threads, it greatly simplifies many things in the runtime. For example, blocking syscalls can be called directly instead of having to use epoll or similar. Also, we don't need to do anything special to call C code - the default stack is all we need.
45 lines
1.2 KiB
Go
45 lines
1.2 KiB
Go
//go:build (gc.conservative || gc.precise) && !tinygo.wasm && !scheduler.threads
|
|
|
|
package runtime
|
|
|
|
import "internal/task"
|
|
|
|
func gcMarkReachable() {
|
|
markStack()
|
|
findGlobals(markRoots)
|
|
}
|
|
|
|
// markStack marks all root pointers found on the stack.
|
|
//
|
|
// This implementation is conservative and relies on the stack top (provided by
|
|
// the linker) and getting the current stack pointer from a register. Also, it
|
|
// assumes a descending stack. Thus, it is not very portable.
|
|
func markStack() {
|
|
// Scan the current stack, and all current registers.
|
|
scanCurrentStack()
|
|
|
|
if !task.OnSystemStack() {
|
|
// Mark system stack.
|
|
markRoots(getSystemStackPointer(), stackTop)
|
|
}
|
|
}
|
|
|
|
//go:export tinygo_scanCurrentStack
|
|
func scanCurrentStack()
|
|
|
|
//go:export tinygo_scanstack
|
|
func scanstack(sp uintptr) {
|
|
// Mark current stack.
|
|
// This function is called by scanCurrentStack, after pushing all registers onto the stack.
|
|
// Callee-saved registers have been pushed onto stack by tinygo_localscan, so this will scan them too.
|
|
if task.OnSystemStack() {
|
|
// This is the system stack.
|
|
// Scan all words on the stack.
|
|
markRoots(sp, stackTop)
|
|
} else {
|
|
// This is a goroutine stack.
|
|
// It is an allocation, so scan it as if it were a value in a global.
|
|
markRoot(0, sp)
|
|
}
|
|
}
|