C malloc storage has explicit lifetime: it must remain allocated until
free even when no GC-visible pointer references it. Treating it as an
ordinary NoPtrs allocation breaks bare-metal C object graphs, while
conservatively scanning arbitrary C bytes creates false Go roots.
Add allocManual/freeManual so collectors can represent pointer-free,
explicitly managed storage. Block GC keeps these objects permanently
marked and releases their blocks on free; Boehm uses atomic uncollectable
allocations; leaking and custom collectors provide equivalent behavior.
Wasm keeps its allocation map only for validation and sizes, and WASIp2
realloc now copies min(oldSize, newSize).
Bump the Boehm library cache version because enabling atomic
uncollectable allocations changes its compiled flags and exported API.
Also handle zero-size and overflowing allocations, serialize allocation
registries, reject Go finalizers on manual storage, and add CGo regressions
for C pointer graphs, hidden until-free allocations, repeated free/reuse,
and allocation edge cases.
Use picolibc setjmp and longjmp to save and restore the complete
Xtensa register-window state at TinyGo panic checkpoints.
Provide the target configuration and window spill helper required by
picolibc. Increment its cache version because Xtensa archives now
include another source file.
* pinout yamls removed
* machine: implement default UART pin configuration for Embedfire boards
* flash command moved to chip level so VS Code plugin can select bare chip
* machine: add support for alternate pin mode configuration
* add build targets for embedfire on py32
* add support for embedfire target in GNUmakefile for py32
* lib/py32-svd: remove duplicate DBGMCU.IDCODE CODE field
Update submodule to fix duplicate SetIDCODE/GetIDCODE method
declarations in the generated py32f002bxx.go device file.
* update subproject commit reference in py32-svd
* refactor: update CPU frequency handling in machine and runtime packages
* refactor: replace ConfigureUARTPin function with direct pin configuration in UART setup
* SetAltFunc documentation for GPIO pin alternate functions
* refactor: improve UART write and flush error handling with timeout
* machine/py32: generalize UART driver to any USART
Add a per-instance setup func to the UART type so the driver is no longer
hardwired to USART1. DefaultUART stays USART1; add UART2 (USART2) in a
separately build-tagged file since py32f002x parts lack USART2. RX IRQ
handlers reference runtime-assigned vars to break the init cycle, and setup
is assigned in the var initializer so it runs before InitSerial.
Add the py32f003_32k_4k target (32K flash / 4K RAM).
* Add canonical PY32F002, F003, and F030 density targets
Use CMSIS/pyocd device names for target files and build tags. Add all F003 and F030 densities plus F002A/B, correct F002B to 24K flash and its own startup file, fix the F030x8 pyocd target, and update Embedfire inheritance.
* Add targets for all PY32 CMSIS devices
* Support all PY32 register layout variants
* machine/py32: use generated register definitions
* machine/py32: fix alternate-function documentation
* machine/py32: report the configured CPU frequency
* machine/py32: use unsafe.Add for GPIO ports
* machine/py32: bound and yield UART polling
* machine/py32: configure UART pins from UARTConfig
* build: use the current PY32 SVD repository URL
* test: cover PY32 UART register layouts
* machine/py32: restore dynamic CPU frequency tracking
* machine/py32: share the USART TX-ready bit
* targets/py32: scale system stacks with RAM
* machine/py32: keep clock state internal
* targets/py32: normalize generated metadata
* machine/py32: normalize GPIO configuration
* machine/py32: fix T020 UART setup
* machine/py32: reduce clock variant files
* machine/py32: clean up UART variants
* machine/py32: decouple UART clock capability
* lib/py32-svd: use organization repository
* runtime/py32: name 24MHz HSI encodings
* machine/py32: derive startup clock from capability
* machine/py32: use generated USART clock mask
* machine/py32: name T020 8-bit UART mode
* ci: include PY32 in sharded smoke tests
* runtime: remove PY32 HSI frequency workaround
* 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
* 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
Reading runtime.MemStats.NumGC is common enough in dependency code that its
absence is a compile error for programs that never look at the value. Rather
than add the field as a constant zero, track it:
- gc_blocks: count completed cycles in runGC, so collections triggered by an
allocation are counted as well as explicit runtime.GC() calls. The counter is
read and written under gcLock, like the other counters beside it.
- gc_boehm: report bdwgc's own gc_no from the prof_stats struct.
- gc_leaking: always 0, since that collector never completes a cycle.
In gcMarkReachable, busy-wait for other cores to enter the interrupt handler and pause before scanning the GC core's stack or globals. Prevents data race where a running core relocates heap references to globals during mark phase.
Using blocksPerStateByte instead of bytesPerBlock caused the old size to be underestimated for multi-block allocations, leading to data truncation on growing reallocations.
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.
Match the Go runtime by terminating instead of unwinding when an
allocator exhausts the heap. Recovering an OOM can leave allocator locks
held and cannot safely continue when the panic path itself needs memory.
Remove unused cpuIntUsed and cpuIntToPeripheral variables from
interrupt_esp32.go because these were declared but never read.
Fix _globals_end in the linker script to cover .data in addition to
.bss and .wifi_bss. Previously the GC scan range ended at
_wifi_bss_end, missing any heap pointers stored in initialized
globals (.data section). Extend to _edata so the conservative
collector sees all global root pointers.
Signed-off-by: deadprogram <ron@hybridgroup.com>
The shared timekeeping code assumes the TIMG0 timer counts at 40MHz,
but on the ESP32-C6 the timer clock defaults to the 40MHz XTAL, giving
a 20MHz tick with the /2 prescaler and making all delays run twice as
long. Select PLL_F80M (80MHz) and enable the timer group clock so the
25ns/tick assumption holds.
Signed-off-by: deadprogram <ron@hybridgroup.com>
Define the board's external crystal (HSE) frequency `xtalHz` in the
respective `board_*.go` files. Per-topology PLL tables (F1, F4, F7)
will compute the register dividers from it.
Moving this parameter to the board definition level cleanly isolates
board hardware characteristics from general MCU chip configurations,
eliminating the need for custom target build tags. Targets using
HSE-clocked STM32 chips must define `xtalHz` or fail to build.
STM32F4 and F7 share the same OTG FS IP but have no USB driver in
TinyGo. This adds a full device-mode driver covering CDC, HID, and
MSC with working examples.
- OTG FS has 4 physical EPs (0–3); virtual indices 4–7 fold onto
them via physEP() so the existing machine/usb API is unchanged
- F4 bypasses VBUS sensing via GCCFG.NOVBUSSENS; F7 uses the USB
voltage regulator + GOTGCTL B-valid override instead
- STM32F7 PLL_Q changed 2→9 to produce the 48 MHz clock required
by USB/RNG/SDMMC; CK48MSEL cleared to select main PLL as source
- HID and MSC descriptors remapped at init() to physical endpoint
addresses (EP2/EP1 for HID, EP2/EP3 for MSC)
- usb-storage example replaced machine.Flash with a FAT12 RAM disk
so the host mounts without reformatting
- MSC sendCSW sets queuedBytes before state transition to fix a
missed byte-count on the status phase
Treat panicState as a bitmask so a recovered panic during Goexit
can clear the panic bit while preserving the pending Goexit bit.
This removes the separate deferFrame Goexit field and restores the
previous defer frame size.
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.
Keep a pending Goexit separate from the active panic state so recovered
deferred panics do not cancel the original Goexit unwind. Goexit should
also ignore -panic=trap, since it is not a panic.
Wire testing.FailNow and SkipNow through runtime.Goexit, and run tests
and benchmarks in goroutines. This lets Goexit terminate the user
function without skipping test bookkeeping. Add Goexit/recover coverage
and enable crypto/ecdh in the Linux stdlib test list.
* upgrade net
* add some missing crypto and os API (#5488)
* add missing crypto API
* gofmt crypto/tls/common.go
* pull new net with unixsock formatted
* update net to latest main
* 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>
* all: clean up code with Go 1.24+ in mind
* all: more old go cleanup
* all: even remove rand_fastrand64
* runtime: revert rand changes
* runtime: re-drop rand_fastrand64
Instead of referring to an unused global, use a constant value. This is
safe even when using `-gc=none` (since no actual memory gets allocated)
which wasn't the case before. It should also reduce binary size by a few
bytes for most programs.
This adds a minimal esp32c6 implementation, currently only
supporting the examples/serial and examples/blinky1 programs.
It does correctly output the expected "Hello, World" via the
serial port, as well as blink the onboard LED.
In addition, it adds support for the PLIC based IRQ handling
as used on the ESP32C6 processor.
Some parts of this code are loosely based on PR #5252 and #5248
Signed-off-by: deadprogram <ron@hybridgroup.com>
This moves the objHeader from before an object body to after it.
On 32-bit systems with 16-byte alignment requirements (x86, ARM, RISC-V), we previously padded the header to a whole block.
This wastes up to 12 bytes, as on -gc=conservative the header is a single pointer.
With this change, no padding is required (beyond that from rounding the size up).
The "head" block in the metadata was moved to the end of the range to match the header location.
This changed the block loop directions throughout the GC logic.
The bit hacks used by sweep no longer work because there is no equivalent of addition that carries downwards.
However it is now possible to merge the sweep and free range list rebuild passes because their loop directions match.
There are two other places where we rebuilt the free ranges list: when initializing or growing the heap.
The former can be easily replaced with a single hardcoded range containing the entire heap.
In the latter case, I opted to only add the new space to the existing list.
These replacements allowed me to fully remove the buildFreeRanges function.
* gba: add bios interrupt flags
Adds a new GBA register for interrupt flags, the register is equivalent
to the IF register, but is intended for BIOS functions.
Acknowledging the interrupts with this register allows us to use BIOS
halt functions such as VBlankIntrWait and IntrWait, which we can use to
get rid of busy loops in the GBA code.
* fix formatting
---------
Co-authored-by: zoey <git@zoey.si>