Commit Graph
9 Commits
Author SHA1 Message Date
smarm-agent 2f011f6ce4 fix(rfc-004): gate spinning on max_spinners>0, killing wake-nobody futex_wake at N=1
`spinning` was `spin_budget_cycles > 0` alone. At N=1 the pool-size cap is 0, so
spinning was enabled while no scheduler could ever enlist: n_spinning pinned at 0,
so the enqueue submit-rule guard (n_spinning==0) fired a wake-nobody futex_wake on
every push. Now gated on `budget > 0 && max_spinners > 0`; a debug_assert guards
the invariant against regression. No behavioural change (a 0-cap runtime never
parks on the futex either way) — single_thread_spinning_is_inert and the AllDone
liveness test (shutdown_releases_pinned_parked_siblings) still pass.

switch_cost N=1 (1-core sandbox): p50 ~466ns -> ~186ns. The wake-nobody syscall
was ~60% of the round-trip in wall-clock terms; the handoff's "~12%" was perf
self-time, not latency share. ROADMAP per-switch section updated to fold in the
N=1 spike correction (shim hypothesis is many-core only). Dropped the throwaway
budget_probe bench (switch_cost reproduces every state via .spin_budget_cycles/
.max_spinners and with percentiles).
2026-06-14 20:01:02 +00:00
smarm-agent debcb4e33b docs: per-switch N=1 local profile — shims are ~1% at N=1; cost is schedule_loop + run-queue + a hot-path futex_wake (revises handoff shim hypothesis to a many-core one) 2026-06-14 18:58:26 +00:00
smarm-agent 683f2ed02d bench: add switch_cost local-mode per-switch microbench (rdtsc+wall, RFC per-switch spike) 2026-06-14 18:56:16 +00:00
smarm-agent 4c1e5f19f1 RFC 004: default spin_budget_cycles=2000 (DEFAULT_SPIN_BUDGET_CYCLES, ~0.5us @3.7GHz), gate spinner cap on pool size (n<=1:0, 2..=4:n, n>=5:0) replacing N/2. From spin_sweep fork-join knee: ~4x p50 win at n<=4, pure cost at n>=8. Budget inert on large pools via 0 cap; explicit max_spinners() still overrides. 2026-06-14 18:27:39 +00:00
smarm-agent 7fcc9f2ec5 benches: document spin_sweep in README (catalog + RFC 004 section, knobs, 1-core caveat); add vs-tokio summary to sweep.py. print_results emits a human 'vs tokio' block + greppable VSTOKIO,<bench>,<smarm_label>,<smarm_us>,<tokio_label>,<tokio_us>,<ratio>,<winner> lines, paired like-for-like by thread count (single vs current_thread; multi vs multi; multi_thread_scaling per matching count). ratio = tokio/smarm so >1 = smarm faster. Also gitignore __pycache__/*.pyc. 2026-06-14 08:01:51 +00:00
smarm-agent 7ec453920b RFC 004 bench: spin_sweep measurement tool. Latency (p50/p90/p99/min/max, pooled across runs) vs idle-CPU (cores-busy via getrusage RUSAGE_SELF) over spin_budget_cycles x max_spinners x threads. Four workloads: remote-wake (latency target), fork-join, half-load (cost target), pure-idle (floor check). Env-knobbed SMARM_SPIN_*, greppable SPINCSV lines. Smoke-runs clean on 1 core (no hang); 1-core correctly shows the spinner-starves-producer pathology, real curve needs the many-core box. 2026-06-14 07:52:21 +00:00
smarm-agent 87416f903a RFC 004 chunk 3: spinning-worker regression tests. Watchdog-timeout harness turns a lost wakeup into a failed assertion. Key test shutdown_releases_pinned_parked_siblings pins siblings in futex_wait while live>0 — verified to FAIL (15s timeout) when the AllDone broadcast is gutted, pass when restored. Also covers bounce/fanout (park+hot-spinner), N=1 cap=0 inertness, budget-0 opt-out, repeated lifecycles. 2026-06-14 07:05:29 +00:00
smarm-agent 2ab82ac032 RFC 004 chunk 2: spin-then-park idle policy — submit rule (Dekker-paired wake), CAS-capped spinner enlistment, bounded spin on queue_len, futex park with lost-wakeup + shutdown guards, last-spinner handoff, AllDone broadcast. Gated on spin_budget_cycles>0; default-off path unchanged (full suite green). 2026-06-14 06:50:57 +00:00
smarm-agent d8b5c8db02 RFC 004 chunk 1: substrate — queue_len counter, n_spinning/park_seq/spinning state, spin_budget_cycles+max_spinners Config knobs, pub(crate) futex helpers. Behavioural no-op (feature off by default). 2026-06-14 06:47:16 +00:00