← board

The scheduler's default coroutine stack does not fit an ESP32

Measured (2026-09-24, HEAD after the windowed CoSwitch)

Setup. test/test_scheduler.pas (three Spawn calls), built with only --target=esp32s3 and booted under S3 QEMU (-m 4M, no PSRAM).

Result. It prints nothing and aborts:

pxx: out of memory (ESP-IDF heap exhausted)

The message is from builtinheap's ESP-IDF branch.

Control. The same three shapes pass on the real board with SpawnSized(..., 16384):

So the context switch is fine. The default stack size is the problem.

Not the ABI

The call0 build hits the same arithmetic. It only never ran on IDF, because IDF could not call a call0 object before 2026-09-24.

Resolution (2026-09-24, frankH)

The measurement changed the diagnosis. After CO_STK alone was cut to 32 KB, httpdemo still ran out of heap at the same SpawnSized GetMem. The bss line said why: a trivial scheduler program had 172,560 B of bss. That is the reactor table, which on ESP can only ever use slot 0.

High-water method. A scratch copy of scheduler.pas (never committed):

program where used given
test_scheduler_yields_deep_in_a_call_chain ESP-IDF S3 QEMU 3,832 B 16 KB
test_scheduler_yields_deep_in_a_call_chain qemu-xtensa windowed 3,952 B 16 KB
examples/net/httpdemo, larger coroutine qemu-xtensa windowed 18,064 B 192 KB
examples/net/httpdemo, smaller coroutine qemu-xtensa windowed 6,320 B 192 KB

Verified:

Not reached, and why: httpdemo on ESP-IDF.

Log