starkernel: item 4.2 -- Hermes native on the Stadium (complete)
Migrates Hermes's message/channel lifecycle onto the Stadium's unified heat/capacity economy: MSG-ALLOC/FREE-NODE and CH-ALLOC/FREE-NODE now route entirely through stadium_admit()/stadium_evict(), replacing the old local free-list + independent heat-field mechanism. Eight kernel-only STADIUM-* FORTH primitives (ADMIT, EVICT, RES@, RES-PULL, RES-PUSH, HEAT@, HEAT!, WORD-HEAT), VM.stadium_vm_id threaded through all three vm_core.c dispatch sites (replacing item 4.1's hardcoded vm_uuid_hera()), and the stadium_owner[idx] fix so evict-credit lands in the VM that actually admitted a patron, not whoever owned cell 0. This session's own contribution, on top of that pre-existing implementation: found and fixed two bugs blocking the item's own K≡1.0 conservation self-check (HERMES-K was reading 0, not 65536): - Q.SLOT admission-heat fix (capsules/hermes/init.4th): MSG-SEND/ CH-ACCEPT admitted with Q.1 (the entire fleet-wide "1.0" unit) per item, a leftover from before the Stadium migration when each message/channel had its own unconstrained heat field. Instantly drained the shared, finite reservoir. - Reservoir floor for word-execution admission (stadium_words.c): stadium_word_dispatch() (item 4.1) pulls STADIUM_WORD_HEAT_QUANTUM on every word dispatch, not just first admission -- exhausts a VM's entire reservoir in ~32 dispatches, starving any application-level economy sharing that VM's reservoir before it gets a chance to pull anything. word_dispatch_pull() now clamps word-execution's own pulls to leave a Q48_ONE/3 floor (same fair-share figure COMMON-CH's own floor already uses); application-level pulls are unaffected. - STADIUM-WORD-HEAT primitive + stadium_words_resident_heat(): the floor deliberately leaves word-execution residents holding real heat, invisible to HERMES-K's original formula (MSG+CH+reservoir, no term for word patrons). Adding this term closes K to exactly 65536 on all three architectures. Also rules on two open scope questions in FABRIC.md: MBR-ALLOC/ MBR-FREE-NODE stay off the Stadium (membership records have no heat field, never did -- the acceptance bullet's inclusion of them was a completeness gesture predating a check of the actual layout), and records the effort number (12 implementation files, +759/-120 lines). Verified: all three architectures boot clean, full self-test passes, Stadium conservation closes exactly (resident_sum + reservoir = Q48_ONE) at both the C/Stadium level and the FORTH-level HERMES-K check. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 5
parent
0a7f144367
commit
5a28458b21
@@ -165,6 +165,30 @@ static void print_uint(const char *label, uint64_t value) {
|
||||
console_println(buf);
|
||||
}
|
||||
|
||||
#ifdef STARFORTH_ENABLE_VM
|
||||
/**
|
||||
* @brief Verify a known word is still reachable in a VM's dictionary.
|
||||
*
|
||||
* Diagnostic-only: confirms @c vm_find_word() can still walk the chain
|
||||
* from @c vm->latest to a word defined early in Hermes's capsule
|
||||
* (MSG-COOL-ALL, block 4108). Added after item 4.2's self-test bisection
|
||||
* found an amd64-only in-place corruption of an existing dictionary entry
|
||||
* during MSG-DELIVER-ALL -- here/latest stay unchanged (no reallocation),
|
||||
* so a lookup is a cheap signal. NOTE: an earlier version of this comment
|
||||
* attributed the corruption to GDB perturbing execution timing; that is
|
||||
* unconfirmed and more likely just a parity/dict-hash boot-gate failure
|
||||
* triggered by the debugger session itself (a software breakpoint's 0xCC
|
||||
* patch landing in memory the loader then overwrote) -- don't propagate
|
||||
* "timing-sensitive" as an established finding.
|
||||
*/
|
||||
static void hermes_dict_check(VM *hermes_vm, const char *checkpoint) {
|
||||
DictEntry *e = vm_find_word(hermes_vm, "MSG-COOL-ALL", 12);
|
||||
console_puts(" Dict-check ");
|
||||
console_puts(checkpoint);
|
||||
console_println(e ? ": OK" : ": FAIL (MSG-COOL-ALL unreachable)");
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Print a boot-information summary from the UEFI memory map to the console.
|
||||
*
|
||||
@@ -648,6 +672,101 @@ static void kernel_main_deep(BootInfo *boot_info) {
|
||||
}
|
||||
}
|
||||
|
||||
/* item 4.2 self-test: a REAL birth (not synthetic, unlike 4.1a's --
|
||||
* this exercises capsules/hermes/init.4th's actual migrated code),
|
||||
* exercised then killed again so the resting boot state stays
|
||||
* Hera-alone, per item 0.1's intent. Diagnostic only -- production
|
||||
* boot still never auto-births Hermes (init.4th's BIRTH stays
|
||||
* commented out). */
|
||||
console_println("Hermes 4.2 migration self-test: birthing...");
|
||||
vm_interpret(mama, "S\" Hermes\" BIRTH");
|
||||
{
|
||||
VMRegistryEntry entry;
|
||||
if (capsule_vm_find_by_name_nocase("Hermes", &entry) == 0 &&
|
||||
entry.state == VM_STATE_LIVE) {
|
||||
VM *hermes_vm = (VM *)entry.vm_ptr;
|
||||
console_println("Hermes 4.2 self-test: exercising migrated words...");
|
||||
hermes_dict_check(hermes_vm, "at self-test start");
|
||||
hermes_vm->error = 0;
|
||||
vm_interpret(hermes_vm, "CD-INIT");
|
||||
print_uint(" DBG err after CD-INIT=", (uint64_t)hermes_vm->error);
|
||||
hermes_dict_check(hermes_vm, "after CD-INIT");
|
||||
hermes_vm->error = 0;
|
||||
vm_interpret(hermes_vm, "HERMES-MSG-TEST . CR");
|
||||
print_uint(" DBG err after MSG-TEST=", (uint64_t)hermes_vm->error);
|
||||
hermes_dict_check(hermes_vm, "after MSG-TEST");
|
||||
hermes_vm->error = 0;
|
||||
vm_interpret(hermes_vm, "HERMES-STATUS");
|
||||
print_uint(" DBG err after STATUS=", (uint64_t)hermes_vm->error);
|
||||
hermes_dict_check(hermes_vm, "after STATUS");
|
||||
hermes_vm->error = 0;
|
||||
vm_interpret(hermes_vm, "MSG-DELIVER-ALL");
|
||||
print_uint(" DBG err after DELIVER-ALL=", (uint64_t)hermes_vm->error);
|
||||
hermes_dict_check(hermes_vm, "after DELIVER-ALL");
|
||||
hermes_vm->error = 0;
|
||||
vm_interpret(hermes_vm, "MSG-REDELIVER-NACKED");
|
||||
print_uint(" DBG err after REDELIVER=", (uint64_t)hermes_vm->error);
|
||||
hermes_vm->error = 0;
|
||||
vm_interpret(hermes_vm, "MSG-COOL-ALL");
|
||||
print_uint(" DBG err after MSG-COOL-ALL=", (uint64_t)hermes_vm->error);
|
||||
hermes_vm->error = 0;
|
||||
vm_interpret(hermes_vm, "MSG-REAP");
|
||||
print_uint(" DBG err after MSG-REAP=", (uint64_t)hermes_vm->error);
|
||||
hermes_vm->error = 0;
|
||||
vm_interpret(hermes_vm, "CH-COOL-ALL CH-REAP-SAFE");
|
||||
print_uint(" DBG err after CH-COOL/REAP=", (uint64_t)hermes_vm->error);
|
||||
hermes_vm->error = 0;
|
||||
vm_interpret(hermes_vm, "Q.1 3 / COMMON-CH @ CH-HEAT!");
|
||||
print_uint(" DBG err after CH-HEAT!=", (uint64_t)hermes_vm->error);
|
||||
hermes_vm->error = 0;
|
||||
vm_interpret(hermes_vm, "HERMES-STATUS");
|
||||
print_uint(" DBG err after TICK=", (uint64_t)hermes_vm->error);
|
||||
hermes_vm->error = 0;
|
||||
console_puts("Hermes 4.2 self-test: HERMES-K=");
|
||||
vm_interpret(hermes_vm, "HERMES-K .");
|
||||
console_println("");
|
||||
print_uint(" DBG err after HERMES-K=", (uint64_t)hermes_vm->error);
|
||||
/* Side-by-side with the Stadium's own view, same checkpoint --
|
||||
* if these two disagree, HERMES-K's FORTH-side arena scan is
|
||||
* seeing different residents than stadium_resident_sum()'s
|
||||
* ownership+bitmap view (a real, separate finding, not the
|
||||
* Q.SLOT admission-heat fix's job to explain). */
|
||||
print_uint(" DBG stadium_resident_sum(Hermes)=", stadium_resident_sum(entry.vm_id));
|
||||
print_uint(" DBG stadium_reservoir_peek(Hermes)=", stadium_reservoir_peek(entry.vm_id));
|
||||
/* item 4.2 Done-when: "a resident cell's evict-credit landing
|
||||
* in the correct VM's reservoir ... not just asserted from
|
||||
* reading the code" -- explicitly evict the common channel
|
||||
* (CH-FREE-NODE -> STADIUM-EVICT), a known resident from
|
||||
* CD-INIT's own COMMON-INIT, same credit path stadium_admit()'s
|
||||
* density-fallback eviction uses. resident_sum dropping and
|
||||
* reservoir rising by the same amount is the proof: the freed
|
||||
* cell's heat landed back in Hermes's own reservoir, not lost
|
||||
* or credited to Hera. */
|
||||
console_println("Hermes 4.2 self-test: before eviction:");
|
||||
print_uint(" Hermes resident_sum=", stadium_resident_sum(entry.vm_id));
|
||||
print_uint(" Hermes reservoir=", stadium_reservoir_peek(entry.vm_id));
|
||||
console_println("Hermes 4.2 self-test: forcing an explicit eviction (COMMON-CH)...");
|
||||
hermes_vm->error = 0;
|
||||
vm_interpret(hermes_vm, "COMMON-CH @ . CR");
|
||||
print_uint(" DBG err after COMMON-CH@=", (uint64_t)hermes_vm->error);
|
||||
hermes_vm->error = 0;
|
||||
vm_interpret(hermes_vm, "COMMON-CH @ CH-FREE-NODE");
|
||||
print_uint(" DBG err after CH-FREE-NODE=", (uint64_t)hermes_vm->error);
|
||||
console_println("Hermes 4.2 self-test: after eviction:");
|
||||
print_uint(" Hermes resident_sum=", stadium_resident_sum(entry.vm_id));
|
||||
print_uint(" Hermes reservoir=", stadium_reservoir_peek(entry.vm_id));
|
||||
/* item 4.2 Done-when: both VMs' conservation checks close
|
||||
* independently -- Hermes's own resident+reservoir sum first,
|
||||
* then Hera's again (unaffected by Hermes's activity above). */
|
||||
stadium_words_print_boot_diagnostics(entry.vm_id);
|
||||
vm_interpret(mama, "S\" Hermes\" KILL");
|
||||
console_println("Hermes 4.2 self-test: killed, resting state restored");
|
||||
stadium_words_print_boot_diagnostics(vm_uuid_hera());
|
||||
} else {
|
||||
console_println("Hermes 4.2 self-test: birth registry lookup FAILED");
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Runtime --doe flag: inject "EXEC-DOE BYE" if requested via boot args.
|
||||
* Checked before SK_STARTUP_FORTH so a runtime --doe takes precedence.
|
||||
|
||||
Reference in New Issue
Block a user