design-b D3 prep: pin fiber-on-context nesting and the foreign-stack refusal
Two scenarios, deliberately separate because they answer different questions that D3 depends on: - fiber_nests_in_context: can a libcontext-style fiber run nested inside a scheduler context at all? YES. Worth pinning explicitly — an earlier version of this scenario trapped `unreachable` and briefly looked like proof that nesting was impossible, which would have been a serious wrong turn for the plan. The real cause was the test's own bug: the host-side emscripten_fiber_t was zero-initialised, so the swap unwound into a null asyncify buffer. Nesting works; the scenario now proves it. - foreign_stack_refused: a yield from that nested fiber is REFUSED, and the host context and scheduler both survive it. The spec asserts foreignStackRefusals == 1, so the refusal path cannot silently stop being exercised. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TEHGiiXMShNXbBr7gSJ7iz
This commit is contained in:
parent
5a3dd44b23
commit
6e80827cec
2 changed files with 136 additions and 4 deletions
|
|
@ -22,6 +22,8 @@ const SCENARIOS = [
|
|||
'one_transition_in_flight',
|
||||
'registry_refusals',
|
||||
'deep_park_sizing',
|
||||
'fiber_nests_in_context',
|
||||
'foreign_stack_refused',
|
||||
'async_wake',
|
||||
];
|
||||
|
||||
|
|
@ -43,6 +45,7 @@ type Stats = {
|
|||
finished: number;
|
||||
transitions: number;
|
||||
refusals: number;
|
||||
foreignStackRefusals: number;
|
||||
running: number;
|
||||
transitionInFlight: boolean;
|
||||
readyQueued: number;
|
||||
|
|
@ -141,6 +144,16 @@ test.describe('Design B D1 — scheduler contexts', () => {
|
|||
// unknown id). Zero would mean those scenarios stopped provoking.
|
||||
expect(stats.refusals, 'illegal operations were refused and counted').toBeGreaterThan(0);
|
||||
|
||||
// --- the D3 blocker, pinned -------------------------------------------
|
||||
// A wait called from a fiber running ON TOP of a context (a KiCad tool
|
||||
// coroutine opening a dialog) must be refused, not allowed to yield
|
||||
// someone else's context — that would save the tool fiber's stack into the
|
||||
// host context's fiber struct. Exactly one scenario provokes it.
|
||||
expect(
|
||||
stats.foreignStackRefusals,
|
||||
'a yield from a foreign stack was refused rather than corrupting the host context',
|
||||
).toBe(1);
|
||||
|
||||
// --- sizing evidence (doc 20 risk 1: derive, don't inherit) ------------
|
||||
// The high-water mark is what a future buffer size must be justified by.
|
||||
// Assert it is both real (>0 — the parks did save frames) and comfortably
|
||||
|
|
|
|||
Loading…
Reference in a new issue