Commit Graph

18 Commits

Author SHA1 Message Date
Matthew Hiles f6e502e121 UEFI: add support for tasks scheduler and make it default (#5553)
* add support for UEFI time and UEFI events; fix STOP \n -> \r\n conversion

* make it so both scheduler=none and scheduler=tasks works

* address pr comments
  - Renamed/shared the amd64 Win64 ABI task stack Go file for both Windows and UEFI.
  - Deleted the duplicate UEFI task stack Go file and old Windows-suffixed Go file.
  - Added task_stack_amd64_windows.S unconditionally to targets/uefi-amd64.json.
  - Removed the UEFI ExtraFiles() special case from compileopts/config.go.
  - Added a scheduler.none tinygo_task_exit stub.
  - Removed the custom UEFI sleep override so normal scheduler sleep queue is used.

* revert back to simpler return value for ExtraFiles()

* create uefi specific tasks_none file

* remove unused sleepSchedulerCustom stuff

* add back the uefi tag

* lib: restore macos-minimal-sdk pointer
2026-08-28 19:48:48 +02:00
Felipe Gené 31fff2c9a3 runtime: run syscall/js finalizers on wasm without a manual GC (#5545)
* runtime: run syscall/js finalizers on wasm without a manual GC

* runtime: address review feedback on finalizer idle GC

* runtime: clear a finished task's args pointer so its arguments are collectable

* runtime: skip the finalizer scan with a per-block registration bit

* runtime: guard the finalizer registration bitmap with gcLock

* testdata: cover finalizer invariants on every scheduler

* main_test: limit the finalizer scheduler variants to linux and darwin

* testdata: wait for the finalizer queue to drain before asserting

* testdata: make the finalizer counters atomic and wait for a known drain count

* runtime: add finalizer bookkeeping asserts under runtime_asserts

* runtime: address finalizer GC review feedback

* testdata: strengthen blocked stack finalizer test

* runtime: fix finalizer cleanup edge cases

* runtime: decouple wasm export scheduling from finalizers

* runtime: avoid redundant wakeups for re-entrant wasm exports

* runtime: simplify finalizer comments
2026-08-26 20:03:44 +02:00
Jake Bailey 16fc1ea2bb runtime: make fatal failures unrecoverable
Match the Go runtime by terminating for deadlocks, stack overflows,
runtime and GC invariants, invalid lock operations, and platform
initialization failures instead of routing them through panic/recover.

Keep language-level runtime errors and unsupported user operations
recoverable. Add crash coverage that verifies fatal errors bypass deferred
recover calls.
2026-07-25 07:14:00 +02:00
Matthew Hiles 9c2eafce6f targets: minimal uefi target support (#5452)
* runtime: split baremetal memory setup

* runtime: extract Windows PE globals scan helper

* compileopts,builder: add target linker flavor override

* machine,runtime,targets: add minimal uefi-amd64 target

* runtime,examples: add clean UEFI exit path test

* machine,x86: fix amd64 ABI stack handling

* machine/uefi: add CHAR16 conversion helpers

* machine/uefi: add loaded image protocol support

* runtime: add UEFI PE globals support

* machine,runtime,x86: add UEFI time and text output support

* machine,runtime,x86: add UEFI text and time support

* machine,runtime,examples: add UEFI text input support

* machine,examples: add UEFI graphics output support

* add rest of STOP methods (direct UEFI ABI only)

* runtime: fix UEFI sleep tick conversion

* machine/uefi: make text input waits cooperative

* address TestClangAttributes/uefi-amd64 failure

* address TestConfigLinkerFlavor bug

* uefi: move raw bindings to device package

* strip down implementation to bare minimum

* amd64: rename x86 package

* do git restore upstream/dev for src/net

* add smoketest for uefi-amd64; add required zeroSizeAllocPtr constant

* address PR issues: remove unused files; make putchar() insert '\r' before '\n'

* swap lines around
2026-07-23 14:34:18 +02:00
Jake Bailey 432ebe13ed runtime: make Goexit exit host threads
The threads scheduler handled runtime.Goexit using the generic deadlock
path, which parked the current pthread forever. Add a scheduler-specific
goexit hook so it can remove the current task and exit the pthread while
ordinary blocking deadlocks still block.

Track main goroutine Goexit so the last remaining goroutine reports the
expected deadlock instead of letting the process exit successfully.
Expand the crash coverage with the Goexit cases covered by Big Go's
runtime tests.
2026-07-11 11:53:33 +02:00
Ron Evans e569dcfe38 runtime: fix ticker not stopping when Stop races with its callback (#5487)
* runtime: fix ticker not stopping when Stop races with its callback

On the threads and cores schedulers, timer callbacks run concurrently
with user goroutines.

If Stop (or Reset) was called in the window after the node was popped
but before its callback re-added it, removeTimer would not find the
timer in the queue, so it would be re-added to timer anyway.

Track timers whose callback is currently running in a firing list, and
have removeTimer mark a firing timer as stopped so its callback does not
re-add it.

Also make the timers test drain robust: allow a possible in-flight tick
delivered concurrently with Stop to settle before draining the channel.

Signed-off-by: deadprogram <ron@hybridgroup.com>

* runtime: fix Stop/Reset semantics when racing a firing timer callback

Address review feedback on the ticker Stop-race fix. On the threads and
cores schedulers a timer callback runs concurrently with user goroutines,
which left several problems:

- removeTimer reported a firing timer as successfully removed, so
  Stop/Reset could return true even though the callback had already
  started (wrong semantics, notably for AfterFunc). firingTimerStop now
  returns a bool and removeTimer no longer hands the still-firing node
  back to resetTimer.

- The periodic advance (when += period) ran in timerCallback outside the
  scheduler timer lock. Move it into each scheduler's reAddTimer, under
  the lock and after the stopped check, so a concurrent Reset can't have
  its freshly-queued deadline corrupted.

- resetTimer now sets when/period after removeTimer for the same reason.

Add testdata/timer_stop_reset_race.go and TestTimerStopResetRace, which
reproduce the stop-while-firing and reset-while-firing races via the
runtime timer linkname hooks.

Signed-off-by: deadprogram <ron@hybridgroup.com>

* runtime: fix timer Stop/Reset race with firing periodic timers

Signed-off-by: deadprogram <ron@hybridgroup.com>

---------

Signed-off-by: deadprogram <ron@hybridgroup.com>
2026-07-06 20:14:53 +02:00
deadprogram 82deccac40 runtime: call initRand() before initHeap() during initialization.
The reason is that allocating without a heap is usually more visible
than using an uninitialized random generator which is subtle and may
lead to security vulnerabilities.

Based on suggestion from @eliasnaur

Signed-off-by: deadprogram <ron@hybridgroup.com>
2025-12-18 16:42:46 +00:00
Elias Naur 78914382c3 runtime: ensure time.Sleep(d) sleeps at least d
Account for the sleep queue base time in the computation of the wakeup
time.

Tested with the following program on pico2.

  func main() {
  	go func() {
  		for i := range 60 {
  			const delay = 20 * time.Millisecond
  			before := time.Now()
  			time.Sleep(delay)
  			if d := time.Since(before); true || d < delay {
  				log.Println(i, "actual", d, "delay", delay)
  			}
  		}
  	}()
  	time.Sleep(500 * time.Millisecond)
  	log.Println("******** done sleeping ********")
  	select {}
  }

Without this change, the program would print lines such as:

  17 actual 15.494ms delay 20ms
  18 actual 15.49ms delay 20ms
  19 actual 15.585ms delay 20ms
  20 actual 15.493ms delay 20ms
  21 actual 15.494ms delay 20ms
  22 actual 15.487ms delay 20ms
  23 actual 15.498ms delay 20ms
  ******** done sleeping ********
  24 actual 15.548ms delay 20ms
  25 actual 20.011ms delay 20ms
  26 actual 20.01ms delay 20ms
  27 actual 20.011ms delay 20ms
  28 actual 20.015ms delay 20ms

Note that while more than one sleeping goroutine is in the timer queue,
the sleep duration is 5ms short.
2025-08-08 01:32:42 +02:00
Ayke van Laethem 60f8a62978 all: add support for multicore scheduler
This commit adds support for a scheduler that runs a scheduler on all
available cores. It is meant to be used on baremetal systems with a
fixed number of cores, such as the RP2040.

The initial implementation adds support for multicore scheduling to the
riscv-qemu target as a convenient testing target. This means that this
new multicore scheduler is tested in CI, including a bunch of standard
library tests (`make tinygo-test-baremetal`). This should ensure the new
scheduler is reasonably well tested before trying to use it on
harder-to-debug targets like the RP2040.
2025-06-12 21:04:36 +02:00
Elias Naur 704489ed6d runtime: update comment
I forgot to change the comment in PR #4890.
2025-05-22 09:29:50 +02:00
Elias Naur 180662f038 runtime: avoid an allocation in (*time.Timer).Reset 2025-05-16 12:36:14 +02:00
Ayke van Laethem 612a38e363 wasm: don't block //go:wasmexport because of running goroutines
This fixes bug https://github.com/tinygo-org/tinygo/issues/4874.
2025-04-29 14:19:17 +02:00
Ayke van Laethem 02c5c4213c runtime: implement NumCPU for -scheduler=threads
For the threads scheduler, it makes sense to have NumCPU available.
For all other schedulers, the number of available CPUs is practically
limited to one by the scheduler (even though the system might have more
CPUs).
2025-04-13 14:59:19 +02:00
Ayke van Laethem 3f8a110e4a runtime: move mainExited boolean
This variable is only necessary on the cooperative and none scheduler.
It is not used on the threads scheduler.

The reason for moving is that the upcoming multicore baremetal scheduler
also needs mainExited but of a different type: an atomic variable
instead of a plain boolean.
2025-04-12 13:34:57 +02:00
Ayke van Laethem f9ed15f857 runtime: refactor timerQueue
Move common functions to scheduler.go. They will be used both from the
cooperative and from the threads scheduler.
2025-04-11 15:18:41 +02:00
Ayke van Laethem f4fd79f7be runtime: manually initialize xorshift state
This ensures:

 1. The xorshift state is initialized during interp.
 2. The xorshift state gets initialized to a real random number on
    hardware that supports it at runtime.

This fixes a big binary size regression from the previous commit. It's
still not perfect: most programs increase binary size by a few bytes.
But it's not nearly as bad as before.
2025-02-21 11:36:17 +01:00
Ayke van Laethem 6110f0bc1b runtime: make channels parallelism-safe 2024-12-16 17:58:00 +01:00
Ayke van Laethem d1fe02df23 runtime: move scheduler code around
This moves all scheduler code into a separate file that is only compiled
when there's a scheduler in use (the tasks or asyncify scheduler, which
are both cooperative). The main goal of this change is to make it easier
to add a new "scheduler" based on OS threads.

It also fixes a few subtle issues with `-gc=none`:

  - Gosched() panicked. This is now fixed to just return immediately
    (the only logical thing to do when there's only one goroutine).
  - Timers aren't supported without a scheduler, but the relevant code
    was still present and would happily add a timer to the queue. It
    just never ran. So now it exits with a runtime error, similar to any
    blocking operation.
2024-11-20 12:45:09 +01:00