Repository navigation
Conversation
…P_NORESERVE - When `!hasScheduler` (`-scheduler=threads`), `sleepTicks` previously waited on and cleared `signalFutex`, racing with `signalWatcher` and `signal_recv`. Wait on a local futex in `sleepTicks` when `!hasScheduler`, and wait directly on `signalFutex` in `signal_recv` instead of calling `task.Pause()` (which is a no-op under `-scheduler=threads`). - Pass `MAP_NORESERVE` when reserving the 1 GiB virtual heap in `allocateHeap()` on Linux and Darwin so strict overcommit settings do not reject untouched virtual address space.
|
Thanks for this. The MAP_NORESERVE change looks right to me. The flag values match Linux (0x4000) and Darwin (0x40). I think signal_recv under -scheduler=threads has a lost wakeup. signalWatcher also does signalFutex.Swap(0), so it competes with signal_recv for the futex.
The window is tiny, so I couldn't hit it naturally in 200k ping-pong iterations. With a 200µs busy-wait between the Load and the Wait, a single signal.Notify + kill(getpid(), SIGUSR1) hangs in 3 of 3 runs. With the watcher disabled, it passes. A fix is to give signal_recv its own futex that only it clears: and in tinygo_signal_handler, after the existing wake: The handler sets the receivedSignals bit before it sets this futex. signal_recv stores 0 before it loads receivedSignals. If the load sees 0, the handler's store of 1 comes after the store of 0, and nothing else clears it, so Wait(0) returns immediately. With this change and the same 200µs delay, 5 of 5 runs pass. |
!hasScheduler(-scheduler=threads),sleepTickspreviously waited on and clearedsignalFutex, racing withsignalWatcherandsignal_recv. Wait on a local futex insleepTickswhen!hasScheduler, and wait directly onsignalFutexinsignal_recvinstead of callingtask.Pause()(which is a no-op under-scheduler=threads).MAP_NORESERVEwhen reserving the 1 GiB virtual heap inallocateHeap()on Linux and Darwin so strict overcommit settings do not reject untouched virtual address space.