prompt cancellation via all-fibers registry + adoption guide
interruptTask now walks an intrusive all-live-fibers list, reaching
fibers parked on io readiness, futex, timers, or await alike — the
'cancel lands on next natural wakeup' gap is closed. new test: cancel
a fiber parked in netRead on a silent socket; must return promptly
with error.Canceled. 16/16 on Debug+ReleaseSafe x macos+linux.
docs: adoption-guide.md — general guide for swapping Io.Threaded for
zio.ZioBackend in any project (zlay as worked example): when to adopt,
the swap, what-runs-where table, the four domain rules, gotchas
(readSliceShort, close-as-wakeup, shutdown order), rollout discipline,
honest maturity status.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
prompt cancellation via all-fibers registry + adoption guide
interruptTask now walks an intrusive all-live-fibers list, reaching
fibers parked on io readiness, futex, timers, or await alike — the
'cancel lands on next natural wakeup' gap is closed. new test: cancel
a fiber parked in netRead on a silent socket; must return promptly
with error.Canceled. 16/16 on Debug+ReleaseSafe x macos+linux.
docs: adoption-guide.md — general guide for swapping Io.Threaded for
zio.ZioBackend in any project (zlay as worked example): when to adopt,
the swap, what-runs-where table, the four domain rules, gotchas
(readSliceShort, close-as-wakeup, shutdown order), rollout discipline,
honest maturity status.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
fiber scheduler v1 + live demo
zio.Sched: blocking-style io (read/writeAll/connectIp4/accept/sleepMs) for
fibers multiplexed on one os thread over the poller. one-shot event arming,
generation-tagged lazy timer heap, every park spurious-wakeup safe (io ops
retry; sleep re-parks until deadline; connect re-checks via getpeername),
finished fibers recycled through a free list so stale poller tokens can
never dereference freed memory.
two lessons banked along the way:
- fresh fiber frames must terminate the unwinder chain: fp=0 AND lr=0
(aarch64) / null return-address slot (x86_64). debug allocators capture
stack traces on alloc-from-fiber; a stale lr sent the unwinder into
garbage (segv at 0x8) only in tests that allocate on fiber stacks.
- never rely on closing an fd to wake a parked fiber — kqueue drops
filters on close and the wakeup is silently lost. shutdown paths use
timed waits (acceptTimeout / waitReadableTimeout) instead.
- x18 clobber is now os-conditional in the vendored switch: required
where allocatable (linux), warning-and-meaningless where reserved
(darwin/windows).
demo (bench/fiber_demo.zig, zig build demo): N tcp echo sessions, all
blocking-style, single thread. linux ReleaseSafe: 4,002 fibers,
~200k round-trips/s, os-threads=1.
10/10 tests, Debug + ReleaseSafe, macos + linux.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
fiber scheduler v1 + live demo
zio.Sched: blocking-style io (read/writeAll/connectIp4/accept/sleepMs) for
fibers multiplexed on one os thread over the poller. one-shot event arming,
generation-tagged lazy timer heap, every park spurious-wakeup safe (io ops
retry; sleep re-parks until deadline; connect re-checks via getpeername),
finished fibers recycled through a free list so stale poller tokens can
never dereference freed memory.
two lessons banked along the way:
- fresh fiber frames must terminate the unwinder chain: fp=0 AND lr=0
(aarch64) / null return-address slot (x86_64). debug allocators capture
stack traces on alloc-from-fiber; a stale lr sent the unwinder into
garbage (segv at 0x8) only in tests that allocate on fiber stacks.
- never rely on closing an fd to wake a parked fiber — kqueue drops
filters on close and the wakeup is silently lost. shutdown paths use
timed waits (acceptTimeout / waitReadableTimeout) instead.
- x18 clobber is now os-conditional in the vendored switch: required
where allocatable (linux), warning-and-meaningless where reserved
(darwin/windows).
demo (bench/fiber_demo.zig, zig build demo): N tcp echo sessions, all
blocking-style, single thread. linux ReleaseSafe: 4,002 fibers,
~200k round-trips/s, os-threads=1.
10/10 tests, Debug + ReleaseSafe, macos + linux.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>