Commit Graph

4271 Commits

Author SHA1 Message Date
Elias Naur 2da9d26e21 machine/rp2: unexport machine-specific errors
Errors are part of API, and the exported rp2 errors seemed arbitrary.
For example, the very particular ErrRP2040I2CDisable was exported, but
errI2CWriteTimeout (which is defined on all platforms) is not.

While here, remove "RP2040" from an error name and make the messages
consistent and idiomatic.
2025-05-12 12:11:01 +02:00
Elias Naur d840971c42 machine: [rp2] discount scheduling delays in I2C timeouts (#4876)
The `gosched` call introduce arbitrary long delays in general, and in
TinyGo particular because the goroutine scheduler is cooperative and
doesn't preempt busy (e.g. compute-heavy) goroutines.

Before this change, the timeout logic would read, simplified:

  deadline := now() + timeout
  startTX()
	for !txDone() {
	   if now() > deadline { return timeoutError }
		 gosched() // (1)
	}
  startRx() // (2)
	for !rxDone() {
	   // (3)
	   if now() > deadline { return timeoutError }
		 gosched()
	}

What could happen in a busy system is:

- The gosched marked (1) would push now() to be > than deadline.
- startRx is called (2), but the call to rxDone immediately after would
report it not yet done.
- The check marked (3) would fail, even though only a miniscule amount
of time has passed between startRx and the check.

This change ensures that the timeout clock discounts time spent in
`gosched`. The logic now reads, around every call to `gosched`:

  deadline := now() + timeout
  startTX()
	for !txDone() {
	   if now() > deadline { return timeoutError }
		 before := now()
		 gosched()
		 deadline += now() - before
	}

I tested this change by simulating a busy goroutine:

	go func() {
		for {
      // Busy.
			before := time.Now()
			for time.Since(before) < 100*time.Millisecond {
			}
      // Sleep.
			time.Sleep(100 * time.Millisecond)
		}
	}()

and testing that I2C transfers would no longer time out.
2025-05-06 21:42:16 -03:00
Damian Gryski ba3b3e8938 runtime: stub runtime signal functions for os/signal on wasip1 2025-05-06 13:20:30 +02:00
Elias Naur c4ef38fbf9 go.*: upgrade golang.org/x/tools to v0.30.0, Go to 1.22
Fixes #4884 by upgrading the ssa package.

The fix is in v0.26.0, which also bumps the minimum Go to 1.22. The
latest x/tools module still depending on 1.22 is v0.30.0.
2025-05-06 10:05:20 +02:00
Ayke van Laethem edaf877056 machine: use pointer receiver in simulated PWM peripherals
I only discovered this issue after a while. All the baremetal PWM
implementations use pointers to a PWM instance, instead of the PWM
instance itself. For consistency (and because it's a better idea in
general), the simulated PWMs need to work the same.
2025-05-01 15:08:08 +02:00
Damian Gryski 45743406d0 os: handle relative and abs paths in Executable() 2025-05-01 10:53:49 +02:00
Damian Gryski 5428bfd270 runtime,os: add os.Executable() for Darwin 2025-05-01 10:53:49 +02:00
Ayke van Laethem 72b19555dc machine: add simulated PWM/timer peripherals
I will soon use these as part of the TinyGo tour, to explain the PWM
peripherals on common chips.
2025-04-30 19:44:34 +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
deadprogram 0c2ab895b7 targets: add target for Microbit v2 with SoftDevice S140 support for both peripheral and central
Signed-off-by: deadprogram <ron@hybridgroup.com>
2025-04-26 15:39:50 +00:00
deadprogram 8d5b7710cf fix: use OpenOCD flash method on microbit v2 when using Nordic Semi SoftDevice
Signed-off-by: deadprogram <ron@hybridgroup.com>
2025-04-26 15:39:39 +00:00
Ayke van Laethem de532643b1 main: add StartPos and EndPos to -json build output
This is useful for the TinyGo Playground: with this change it can show
the error span like in an IDE, instead of just the (single) error
position. Errors become a bit more readable as a result.
2025-04-24 09:24:52 +02:00
Ayke van Laethem c2765e9eca main: change -json flag to match upstream Go
This changes the -json flag for build/run/flash/gdb etc commands to not
print `compileopts.Config` but instead match upstream Go and print build
errors in a structured way.

For more details, see the proposal:
https://github.com/golang/go/issues/62067
2025-04-23 12:39:23 +02:00
Ayke van Laethem aa63f26f36 windows: use MSVCRT.DLL instead of UCRT on i386
This allows the binaries to run on Windows XP, without needing any extra
DLLs. Tested in an x86 Windows XP SP3 virtual machine.
2025-04-22 17:45:29 +02:00
Ayke van Laethem f542717992 windows: add windows/386 support 2025-04-22 17:45:29 +02:00
Ayke van Laethem 922ba6a4a3 all: add support for LLVM 20
This adds support for the 'go install' case, where we link against the
system LLVM (Homebrew, Linux distro version, etc). This does not have an
effect on `make`, which still uses LLVM 19 for now.

The main reason for doing this is because newer distros like Fedora 42
and Homebrew have switched to LLVM 20, so switching to this newer
version helps those people. (I'm one of those people, I'm on Fedora 42).

There are two small changes for WebAssembly included:

  * nontrapping-fptoint was enabled in the wasmbuiltin library used for
    wasm-unknown. This matches wasm-unknown which already had this
    enabled, so it doesn't add any new instructions.
  * bulk-memory was enabled in wasi-libc. This was previously enabled in
    all the other WebAssembly targets (wasm, wasip1, wasip2) so this
    does't add any new instructions. I think it was also enabled in the
    wasi-libc build before
    https://github.com/tinygo-org/tinygo/pull/4820 but I don't know for
    sure.
2025-04-22 16:31:19 +02:00
Michael Smith febb3906db machine/rp2: expose usb endpoint stall handling 2025-04-17 10:15:44 +02:00
Elias Naur 0f06f59c6e device/arm: clear pending interrupts before enabling them
Without this change, a pending interrupt would spuriously trigger
immediately after enabling. This happens if an interrupt is triggered
during flashing (e.g. by DMA), which survives the subsequent reset.

This behaviour matches e.g. `machine.irqSet` in machine_rp2_rp2350.go.

See 7f970a45, whose symptoms were likely caused by spurious interrupts.
2025-04-16 09:43:23 +02:00
Damian Gryski 0fdf08d14f add -nobounds (similar to -gcflags=-B) 2025-04-15 12:55:44 +02:00
Michael Smith 133e32c1c4 machine/rp2: merge common usb code (#4856)
* machine/rp2: merge common usb code
* chore: add note on noinline reason
2025-04-15 11:07:47 +02:00
Ayke van Laethem 41e501aaf4 runtime: move timeUnit to a single place
The timeUnit is now the same type everywhere. Move it to a single place
and add some documentation to it.
2025-04-15 09:23:23 +02:00
Ayke van Laethem abc373dc73 wasm: use int64 instead of float64 for the timeUnit
This makes wasm consistent with all the other targets, where timeUnit is
already int64.
2025-04-15 09:23:23 +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 25b83920b6 ci: try to fix race condition in testdata/goroutines.go
A race condition was possible because the 'acquire' goroutine might not
have started in 4 milliseconds which changed the ordering of the test.

This patch fixes it by making sure the goroutine has started (and locked
the mutex) before continuing with the test.
2025-04-12 18:35:56 +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 95ee572b4d internal/task: rename tinygo_pause to tinygo_task_exit
This is more descriptive: the call is to exit a task, not to pause it.
This also makes it more obvious that there's an optimization
opportunity: to free the stack explicitly after the goroutine returns
(or to keep it as a cache for the next stack allocation).
2025-04-12 13:34:57 +02:00
Ayke van Laethem 120d17c124 runtime: map every goroutine to a new OS thread
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.
2025-04-11 15:18:41 +02:00
Ayke van Laethem 193f91b870 sync: implement RWMutex using futexes
Somewhat surprisingly, this results in smaller code than the old code
with the cooperative (tasks) scheduler. Probably because the new RWMutex
is also simpler.
2025-04-11 15:18:41 +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 870f00222d runtime: make conservative and precise GC MT-safe
Using a global lock may be slow, but it is certainly simple and safe.
If this global lock becomes a bottleneck, we can of course look into
making the GC truly support multithreading.
2025-04-11 15:18:41 +02:00
Ayke van Laethem 5b243f652c internal/task: implement atomic primitives for preemptive scheduling 2025-04-11 15:18:41 +02:00
Ayke van Laethem 789b5c6b78 compileopts: add library version to cached library path
This may be a bit of a weird place to put the library path, but
otherwise it's difficult to get the pathname for the Config.CFlags
function. So I've put it here.

This should help to avoid stale library caches. The idea is to increment
it every time something changes to a library that means it needs to be
recompiled. It's a manual process.
2025-04-10 11:59:46 +02:00
Ayke van Laethem dcf609defb riscv-qemu: actually sleep in time.Sleep()
Instead of just incrementing the timestamp, this causes the system to
actually sleep when calling time.Sleep. The direct effect is that this
works as expected:

    $ tinygo run -target=riscv-qemu examples/serial
    hello world!
    hello world!
    hello world!
    [..etc]

This commit also adds a bare bones handler for exceptions (such as
invalid memory writes), since we're adding an interrupt handler anyway.

While this patch doesn't add that much functionality, having interrupt
support is going to be needed for multicore support on riscv-qemu. My
plan is to first add this support to riscv-qemu (based on the earlier
work I did for the RP2040 and demoed at FOSDEM 2025) and once the basics
are in place and fully tested we can extend this support to the RP2040.
Writing for QEMU first makes it much easier to debug any issues that
will come up.
2025-04-05 08:57:26 +02:00
Ayke van Laethem 4bce85dc09 riscv: define CSR constants and use them where possible 2025-04-05 08:57:26 +02:00
Caleb Champlin 8a73502f11 reflect: Add SliceOf, ArrayOf, StructOf, MapOf, FuncOf 2025-04-04 15:23:07 +02:00
Ayke van Laethem 632357ffb9 builder: build wasi-libc inside TinyGo
Instead of relying on a build when TinyGo is being built, do it like all
other libraries when it is needed.

This brings a few benefits:

  * No more running `make wasi-libc` on the command line as a special
    case for WebAssembly. The generic `git submodule update --init` step
    is now enough for wasi-libc.
  * It becomes much easier to customize the build per system. For
    example: include/exclude malloc as needed, disable/enable bulk
    memory operations per target, etc.
2025-04-04 13:14:04 +02:00
Ayke van Laethem 4c54aa20da builder: simplify bdwgc libc dependency
Header files are built immediately, not in a separate job, so no
dependency is needed here. All we need is a flag whether to add flags
for that given libc.
2025-04-04 13:14:04 +02:00
Ayke van Laethem 8486e07377 builder: don't use precompiled libraries
We used these libraries in the past, but stopped doing so a while ago.
This is a small cleanup to remove support for these entirely.
2025-04-04 13:14:04 +02:00
deadprogram 91e20a53e0 fix: display all of the current GC options for the -gc flag
Signed-off-by: deadprogram <ron@hybridgroup.com>
2025-04-01 13:54:37 +02:00
Ayke van Laethem 9e42c8459e Makefile: only detect ccache command when needed 2025-04-01 10:10:11 +02:00
Ayke van Laethem 627743432a Makefile: create random filename inside rule
Don't create the temporary name in advance (which needs a subprocess
call), only do that when needed inside the report-stdlib-tests-pass
rule.
2025-04-01 10:10:11 +02:00
Ayke van Laethem 5d92d4dc98 Makefile: don't set GOROOT
This *should* not be needed. Using the right `go` binary should do the
job. It might break if users have explicitly set GOROOT (in which case
they probably need to fix that).

This avoids a subprocess call inside `make`.
2025-04-01 10:10:11 +02:00
Ayke van Laethem 682b3a9523 Makefile: call uname at most once
Instead of calling it 5 times, call it only once on Unix-like systems
(Linux, MacOS) and avoid it entirely on Windows.

The main benefit of this is that it avoids a ton of overhead doing
subprocess calls, which are very slow on Windows (~0.2s on my system).
2025-04-01 10:10:11 +02:00
Ayke van Laethem fdf075a7f9 Makefile: only read NodeJS version when it is needed
Most make commands don't need to check for the NodeJS version, so only
do it when needed.

This avoids the following error on Windows for example when NodeJS is
not installed:

    /usr/bin/sh: line 1: node: command not found
    which: no node in (/c/Users/Ayke/bin:/clangarm64/bin:/usr/local/bin:/usr/bin:/usr/bin:/mingw64/bin:/usr/bin:/c/Users/Ayke/bin:/c/Users/Ayke/.vscode-server/cli/servers/Stable-e54c774e0add60467559eb0d1e229c6452cf8447/server/bin/remote-cli:/c/WINDOWS/system32:/c/WINDOWS:/c/WINDOWS/System32/Wbem:/c/WINDOWS/System32/WindowsPowerShell/v1.0:/c/WINDOWS/System32/OpenSSH:/cmd:/c/Users/Ayke/scoop/apps/mingw-mstorsjo-llvm-ucrt/current/bin:/c/Users/Ayke/scoop/apps/python/current/Scripts:/c/Users/Ayke/scoop/apps/python/current:/c/Users/Ayke/go/bin:/c/Users/Ayke/scoop/shims:/c/Users/Ayke/AppData/Local/Microsoft/WindowsApps:/usr/bin/vendor_perl:/usr/bin/core_perl)

Also, some users have been confused by the error message even though in
most cases it is harmless and can be ignored.
2025-03-25 18:58:08 +01:00
Ayke van Laethem 95a7d065ca darwin: support Boehm GC (and use by default)
This mostly required some updates to macos-minimal-sdk to add the needed
header files and symbols.
2025-03-25 12:33:13 +01:00
deadprogram c1c074f170 version: update to 0.38.0-dev
Signed-off-by: deadprogram <ron@hybridgroup.com>
2025-03-24 09:25:32 +01:00
Ayke van Laethem 429c01556b cgo: *actually* fix build warnings on Windows ARM
See: https://github.com/tinygo-org/tinygo/pull/4628

This removes the comment, which actually fixes the issue. #4628 was
incorrect.
2025-03-23 08:13:57 +01:00
Ayke van Laethem ee76822fe6 arm64: remove unnecessary .section directive
This directive caused the code to be put in a non-executable area on
Windows which caused a segmentation fault. This patch fixes the issue by
removing `.section` directives, fixing windows/arm64 support.
2025-03-23 07:23:24 +01:00
Ayke van Laethem b9bf0aa0da windows: add support for the Boehm-Demers-Weiser GC
A few small changes were needed to make this work. In particular, I
found a critical bug (see the previous commit) that needed to be fixed
to make this work on Windows.
2025-03-22 19:40:56 +01:00
Ayke van Laethem fd3976b5bb windows: fix wrong register for first parameter
I'm surprised this worked as long as it did, since it looks like the
goroutine stack did not get scanned. Or maybe the RCX register contained
the stack pointer by accident. In any case, it now uses the correct
register (RCX instead of RDI on Windows) for passing the stack pointer
as the first parameter.
2025-03-22 19:40:56 +01:00