diff --git a/src/internal/task/task_stack_cortexm.go b/src/internal/task/task_stack_cortexm.go index b91e5f041d..a7927d040b 100644 --- a/src/internal/task/task_stack_cortexm.go +++ b/src/internal/task/task_stack_cortexm.go @@ -1,4 +1,4 @@ -// +build scheduler.tasks, cortexm +// +build scheduler.tasks,cortexm package task diff --git a/src/runtime/gc_conservative.go b/src/runtime/gc_conservative.go index 41a27523e1..319e68b55e 100644 --- a/src/runtime/gc_conservative.go +++ b/src/runtime/gc_conservative.go @@ -180,7 +180,7 @@ func (b gcBlock) unmark() { // No memory may be allocated before this is called. That means the runtime and // any packages the runtime depends upon may not allocate memory during package // initialization. -func init() { +func initHeap() { totalSize := heapEnd - heapStart // Allocate some memory to keep 2 bits of information about every block. diff --git a/src/runtime/gc_leaking.go b/src/runtime/gc_leaking.go index fb0f9086ed..f5e3595174 100644 --- a/src/runtime/gc_leaking.go +++ b/src/runtime/gc_leaking.go @@ -45,3 +45,7 @@ func KeepAlive(x interface{}) { func SetFinalizer(obj interface{}, finalizer interface{}) { // Unimplemented. } + +func initHeap() { + // Nothing to initialize. +} diff --git a/src/runtime/gc_none.go b/src/runtime/gc_none.go index b7fc628de0..c69d2a2426 100644 --- a/src/runtime/gc_none.go +++ b/src/runtime/gc_none.go @@ -27,3 +27,7 @@ func KeepAlive(x interface{}) { func SetFinalizer(obj interface{}, finalizer interface{}) { // Unimplemented. } + +func initHeap() { + // Nothing to initialize. +} diff --git a/src/runtime/runtime_arm7tdmi.go b/src/runtime/runtime_arm7tdmi.go index cf2ff68183..d7629ad6da 100644 --- a/src/runtime/runtime_arm7tdmi.go +++ b/src/runtime/runtime_arm7tdmi.go @@ -30,20 +30,16 @@ var _sidata [0]byte //go:extern _edata var _edata [0]byte +func postinit() {} + // Entry point for Go. Initialize all packages and call main.main(). //go:export main func main() { // Initialize .data and .bss sections. preinit() - // Run initializers of all packages. - initAll() - - // Compiler-generated call to main.main(). - go callMain() - - // Run the scheduler. - scheduler() + // Run program. + run() } func preinit() { diff --git a/src/runtime/runtime_atsamd21.go b/src/runtime/runtime_atsamd21.go index a3aa6c9739..5c535cf1d2 100644 --- a/src/runtime/runtime_atsamd21.go +++ b/src/runtime/runtime_atsamd21.go @@ -13,12 +13,12 @@ import ( type timeUnit int64 +func postinit() {} + //go:export Reset_Handler func main() { preinit() - initAll() - go callMain() - scheduler() + run() abort() } diff --git a/src/runtime/runtime_atsamd51.go b/src/runtime/runtime_atsamd51.go index 23d91109c9..a605eee589 100644 --- a/src/runtime/runtime_atsamd51.go +++ b/src/runtime/runtime_atsamd51.go @@ -12,12 +12,12 @@ import ( type timeUnit int64 +func postinit() {} + //go:export Reset_Handler func main() { preinit() - initAll() - go callMain() - scheduler() + run() abort() } diff --git a/src/runtime/runtime_avr.go b/src/runtime/runtime_avr.go index 09f91f7ad6..09d4b5991b 100644 --- a/src/runtime/runtime_avr.go +++ b/src/runtime/runtime_avr.go @@ -39,9 +39,7 @@ var _ebss [0]byte //go:export main func main() { preinit() - initAll() - postinit() - callMain() + run() abort() } diff --git a/src/runtime/runtime_cortexm_qemu.go b/src/runtime/runtime_cortexm_qemu.go index 973c20ac2d..80365a7d28 100644 --- a/src/runtime/runtime_cortexm_qemu.go +++ b/src/runtime/runtime_cortexm_qemu.go @@ -17,12 +17,12 @@ const tickMicros = 1 var timestamp timeUnit +func postinit() {} + //go:export Reset_Handler func main() { preinit() - initAll() - go callMain() - scheduler() + run() arm.SemihostingCall(arm.SemihostingReportException, arm.SemihostingApplicationExit) abort() } diff --git a/src/runtime/runtime_fe310.go b/src/runtime/runtime_fe310.go index 88295c9c0e..62673ad352 100644 --- a/src/runtime/runtime_fe310.go +++ b/src/runtime/runtime_fe310.go @@ -31,6 +31,8 @@ var _sidata [0]byte //go:extern _edata var _edata [0]byte +func postinit() {} + //go:export main func main() { // Zero the PLIC enable bits on startup: they are not zeroed at reset. @@ -51,9 +53,7 @@ func main() { preinit() initPeripherals() - initAll() - go callMain() - scheduler() + run() abort() } diff --git a/src/runtime/runtime_nrf.go b/src/runtime/runtime_nrf.go index 9b01ded705..9cfa457a67 100644 --- a/src/runtime/runtime_nrf.go +++ b/src/runtime/runtime_nrf.go @@ -17,13 +17,13 @@ const tickMicros = 1024 * 32 //go:linkname systemInit SystemInit func systemInit() +func postinit() {} + //go:export Reset_Handler func main() { systemInit() preinit() - initAll() - go callMain() - scheduler() + run() abort() } diff --git a/src/runtime/runtime_stm32.go b/src/runtime/runtime_stm32.go index 11e686f06a..bd529cebd1 100644 --- a/src/runtime/runtime_stm32.go +++ b/src/runtime/runtime_stm32.go @@ -4,11 +4,11 @@ package runtime type timeUnit int64 +func postinit() {} + //go:export Reset_Handler func main() { preinit() - initAll() - go callMain() - scheduler() + run() abort() } diff --git a/src/runtime/runtime_unix.go b/src/runtime/runtime_unix.go index a88f243f73..daf934ea35 100644 --- a/src/runtime/runtime_unix.go +++ b/src/runtime/runtime_unix.go @@ -26,10 +26,7 @@ func clock_gettime(clk_id int32, ts *timespec) const heapSize = 1 * 1024 * 1024 // 1MB to start -var ( - heapStart = uintptr(malloc(heapSize)) - heapEnd = heapStart + heapSize -) +var heapStart, heapEnd uintptr type timeUnit int64 @@ -45,17 +42,15 @@ type timespec struct { const CLOCK_MONOTONIC_RAW = 4 +func postinit() {} + // Entry point for Go. Initialize all packages and call main.main(). //go:export main func main() int { - // Run initializers of all packages. - initAll() - - // Compiler-generated call to main.main(). - go callMain() + heapStart = uintptr(malloc(heapSize)) + heapEnd = heapStart + heapSize - // Run scheduler. - scheduler() + run() // For libc compatibility. return 0 diff --git a/src/runtime/runtime_wasm.go b/src/runtime/runtime_wasm.go index c01fa93265..8042161b10 100644 --- a/src/runtime/runtime_wasm.go +++ b/src/runtime/runtime_wasm.go @@ -18,11 +18,15 @@ type wasiIOVec struct { //export fd_write func fd_write(id uint32, iovs *wasiIOVec, iovs_len uint, nwritten *uint) (errno uint) +func postinit() {} + //export _start func _start() { - initAll() - go callMain() - scheduler() + // These need to be initialized early so that the heap can be initialized. + heapStart = uintptr(unsafe.Pointer(&heapStartSymbol)) + heapEnd = uintptr(wasm_memory_size(0) * wasmPageSize) + + run() } // Using global variables to avoid heap allocation. diff --git a/src/runtime/scheduler_any.go b/src/runtime/scheduler_any.go index d541dc6a3c..41a904535d 100644 --- a/src/runtime/scheduler_any.go +++ b/src/runtime/scheduler_any.go @@ -10,3 +10,15 @@ func sleep(duration int64) { addSleepTask(task.Current(), duration) task.Pause() } + +// run is called by the program entry point to execute the go program. +// With a scheduler, init and the main function are invoked in a goroutine before starting the scheduler. +func run() { + initHeap() + go func() { + initAll() + postinit() + callMain() + }() + scheduler() +} diff --git a/src/runtime/scheduler_none.go b/src/runtime/scheduler_none.go index 222867dd0a..d462ca15c5 100644 --- a/src/runtime/scheduler_none.go +++ b/src/runtime/scheduler_none.go @@ -12,3 +12,12 @@ func sleep(duration int64) { func getSystemStackPointer() uintptr { return getCurrentStackPointer() } + +// run is called by the program entry point to execute the go program. +// With the "none" scheduler, init and the main function are invoked directly. +func run() { + initHeap() + initAll() + postinit() + callMain() +}