Fix stadium_grant_quota() donor floor; rerun std79 DoE clean, 81/81 (FABRIC-3.md §XVII)
Build / build-amd64-iso (push) Waiting to run
Build / build-aarch64-iso (push) Waiting to run
Build / build-riscv64-img (push) Waiting to run

capsule_birth.c hardcoded every new VM's initial Stadium quota grant to split
from Hera specifically. Since a grant always halves whatever the donor
currently has, Hera's own free list converges toward empty after a bounded
number of grants — independent of whether the Stadium as a whole still had
spare capacity, since VMs she'd granted to earlier typically still held
nearly all of their own share untouched. Past that point every subsequent
VM birth's Stadium grant would be silently refused (soft-failed, non-fatal
by existing design), even with plenty of capacity sitting idle elsewhere.

Fixed by adding an O(1)-maintained free_count to StadiumVMQuota (incremented
in stadium_evict(), decremented at both of stadium_admit()'s free-list-pop
sites, set/adjusted in stadium_grant_quota()'s own split — this also let
grant_quota drop its old O(free-list length) counting walk in favor of an
O(1) read) and stadium_best_donor(), an O(live VM count) scan over quota
slots returning whichever in-use VM currently has the most free cells.
capsule_birth.c's birth path now splits from that VM instead of
unconditionally vm_uuid_hera().

Verified with another full rerun of the 3x9x3 std79 DoE campaign from
scratch — same discipline as the prior Stadium fix (any defect repair
reruns the whole DoE from the top) — one continuous boot per architecture,
all 9 identities simultaneously live throughout. 81/81 trials correct, 0
mismatches, DOE-RUN header sequence md5-identical to every prior run.
aarch64 ~280s total (vs ~290s for the O(ncells)-scan fix alone — confirms
no regression). Both known Stadium defects are now closed together on one
clean campaign rerun.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EXieurDfDSsDFdnSyusuWo
This commit is contained in:
Robert Allan James
2026-09-11 17:20:07 -04:00
co-authored by Claude Sonnet 5
parent 9eff122090
commit e51a8d229e
16 changed files with 57128 additions and 39 deletions
+45 -6
View File
@@ -2610,10 +2610,49 @@ exist in the whole stalled log) carried into that section's live write-up and in
`experiments/std79-doe/std79-doe.fth`'s own comment block and the
`project_std79_doe_complete.md` memory note; all three have been corrected to point here.
**Latent secondary issue, recorded not fixed (out of scope for this pass):** the free-list
halving in `stadium_grant_quota()` has no floor -- after enough successive VM births Hera's own
free list drops below 2 cells and every subsequent grant is silently refused (`half == 0` -> -1),
which `capsule_birth.c` currently treats as non-fatal. Same root mechanism as the fix above, a
different (silent-failure-to-birth, not stall) symptom, not yet a problem at any VM count actually
exercised so far.
**Latent secondary issue, recorded not fixed at the time (out of scope for that pass) -- now also
fixed, see §XVII below:** the free-list halving in `stadium_grant_quota()` has no floor -- after
enough successive VM births Hera's own free list drops below 2 cells and every subsequent grant
is silently refused (`half == 0` -> -1), which `capsule_birth.c` currently treats as non-fatal.
Same root mechanism as the fix above, a different (silent-failure-to-birth, not stall) symptom.
## XVII. stadium_grant_quota() donor-floor fix (2026-09-11/12)
§XVI's fix closed the O(stadium_ncells) scan; this follow-up closes the second, related defect
flagged there but not fixed at the time: `stadium_grant_quota()`'s split always came from Hera
specifically (`capsule_birth.c` hardcoded `stadium_grant_quota(vm_id, vm_uuid_hera())`), and
because the split halves whatever the donor currently has left, Hera's own free list converges
toward empty after a bounded number of grants -- independent of whether the Stadium as a whole
still has plenty of spare capacity, since VMs she granted to earlier typically still hold nearly
all of their own share untouched. Past that point every subsequent VM birth would have its
Stadium grant silently refused (soft-failed, non-fatal per the existing design), even though
capacity existed elsewhere in the system.
**Fix:** added `free_count` to `StadiumVMQuota` (`src/starkernel/vm/stadium.c`), an O(1)-maintained
length of each VM's own free list -- incremented in `stadium_evict()` when a cell returns to a
quota's free list, decremented at both of `stadium_admit()`'s free-list-pop sites, set/adjusted in
`stadium_grant_quota()`'s own split. This also let `stadium_grant_quota()` drop its old
O(from_vm_id's free-list length) counting walk in favor of an O(1) read.
Added `stadium_best_donor()` (`stadium.c`/`stadium.h`): an O(stadium_max_vm_count()) scan over
quota *slots* (bounded by live VM population, not cell count) returning whichever in-use VM
currently holds the most free cells. `capsule_birth.c`'s birth path now calls this instead of
hardcoding `vm_uuid_hera()`, falling back to Hera only if no VM holds a quota yet (should not
happen in practice, since `stadium_birth_hera()` always runs first).
**Verification:** another full rerun of the entire 3x9x3 std79 DoE campaign from scratch --
same discipline as §XVI ("any defect repair requires rerunning the DoE from the top") -- one
continuous boot per architecture, all 9 identities simultaneously live throughout:
`experiments/std79-doe/results-20260911-donor-floor-fix/`.
- amd64: ~161s total.
- aarch64: ~280s total (consistent with §XVI's ~290s -- confirms this fix didn't regress the
O(ncells) scan fix's performance).
- riscv64: ~162s total.
All three logs' `DOE-RUN,run_id,id_idx,id_label,rep` header sequences are md5-identical to each
other and to §XVI's run, and the canonical 28-number per-trial result string appears exactly 27
times in each log. **81/81 trials correct, 0 mismatches** -- both known Stadium defects (§XVI's
O(ncells) scan and this section's donor floor) are now closed, verified together on one clean
campaign rerun.