From c94f878e7ece17f7f5f7d837570f0076fce4619d Mon Sep 17 00:00:00 2001 From: agra Date: Sat, 27 Jun 2026 08:14:30 +0300 Subject: [PATCH] =?UTF-8?q?docs:=20PLAN-IO-UNIFY=20=E2=80=94=20Phase=202?= =?UTF-8?q?=20done=20(async/await=20colorblind)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- current/PLAN-IO-UNIFY.md | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/current/PLAN-IO-UNIFY.md b/current/PLAN-IO-UNIFY.md index bf940445..320bcaca 100644 --- a/current/PLAN-IO-UNIFY.md +++ b/current/PLAN-IO-UNIFY.md @@ -48,7 +48,20 @@ just with the scheduler now reachable as `context.io`. doc, stale `fib_dispatch` comment. - **Resolved design decisions:** D1 = direct `impl Io for Scheduler` (chosen). D2 = `now_ms` returns the virtual `clock_ms` (deterministic) — a real-clock variant is later. D4 = deferred to Phase 3. -- **Open for Phase 2:** +- **Phase 2 — `async`/`await` colorblind over the fiber Io. DONE** (`967aed67`, hardened `ada8d162`). + `async` heap-allocs a `*Future`, boxes a completion closure in a monomorphic `ThunkBox`, and submits + via `io.spawn_raw` (inline under `CBlockingIo`, a fiber under the scheduler); `await` parks via + `suspend_raw` until ready. Protocol changed to `suspend_raw(park: *ParkToken)` (write-back of the + awaiter). Workers are nullary (call-site capture). Migrated 1805/1806; adopted `push .{ … }`. Lock: + example 1824 (deferral visible: `1 2 10 20 123`). Review fixed: one-awaiter `await` guard; documented + the Future allocator-lifetime contract + that `cancel` doesn't stop an already-spawned worker (Phase 3). + - **Resolved D2 (ParkToken):** `suspend_raw(*ParkToken)` write-back (chosen over a registry). **ready() + liveness (CONCERN 6):** safe for single async/await (awaiter is suspended, not reaped, when readied); + `race` fan-in must still deregister (Phase 4). + - **Carried to convergence:** `async` should capture the scheduler's long-lived allocator (like + `sched.go`'s `own_allocator`) instead of the call-site `context.allocator` — needs a protocol + affordance; documented as a contract for now. +- **Open for later phases:** - **ParkToken↔fiber binding.** `ready(park)` needs `park.handle` = the awaiter `*Fiber`. The scheduler knows `self.current` at suspend; the cleanest is `suspend_raw(park: *ParkToken)` writing `park.handle = self.current` before parking (a small protocol change: the materializer installs