- logs/20260925-112529/amd64/: O-D amd64 launch (12345 3 S" amd64" DOE, rows on), stopped via QMP after 81 min / 131,537 rows with no trial complete, so the row path could be fixed (row path A ruled). - FABRIC-3.10.8: Captain Bob, 2026-09-25: "until we close everything, do not do ant DoE eecution." MC-4's campaigns wait; stage evidence is the standard sequence plus probes. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
6.3 KiB
FABRIC-3.10.8.md — Multi-core: execution plan and log
Status: IN PROGRESS. Design and rulings are in FABRIC-3.10.0.md (ruled 2026-09-25, §7).
Multi-core runs ahead of O-D (MC-R6 as ruled); O-D relaunches afterwards with row path A.
Each stage:
- needs Captain Bob's explicit go;
- gets its own commit;
- gets its own three-architecture acceptance (
clean qemu; amd64, then aarch64, then riscv64; foreground; visible framebuffer; one at a time; coupled images reset before each).
Evidence is named before each stage runs.
The standing acceptance sequence, unchanged from FABRIC-3.9.8.md:
- a boot to
[zuse@Hera] ok>with zeroUNKNOWN WORD, faults and frame corruption; - the
dict_hashset identical across ISAs; - the Stage G interleave (A/B), byte-identical across ISAs while there is one worker core; by counts (A = 40, B = 40) once there are more (MC-R4);
- the O-A checks (observer precedence, console responsive under load);
- mint → WIREBIND →
USE→1 2 + .→3; - 0 bytes of idle log growth over 20 s.
No DoE execution until everything is closed (Captain Bob, 2026-09-25: "until we close everything, do not do ant DoE eecution."). MC-4's campaigns wait for that too. Stage evidence is the standard sequence plus probes, never a campaign.
Never make clean an ISA while its QEMU runs: it deletes that QEMU's QMP and serial
sockets (found 2026-09-25).
1. What MC-0 must cover (traced 2026-09-25)
Everything that would break if two cores ran kernel or VM code at the same moment.
Kernel subsystems (src/starkernel/), one lock each (MC-R2), except where noted:
| Subsystem | Shared state | Treatment |
|---|---|---|
kmalloc, pmm, vmm |
free lists, bitmaps, page tables | heap lock; PMM lock; VMM lock |
| kernel-Hermes | arena directory and segments, queue table, channel table, ledger, event counters | one lock |
| Stadium | reservoirs, cells, quotas, word rows | per-dispatch path partitioned by quota slot (a VM's own row and cells need no lock while it runs on its one core); reservoir arithmetic atomic; cross-slot operations (admission evicting another VM's cell, grants, audits) take the Stadium lock |
| VM registry, birth, kill, reap | registry list, names | registry lock; KILL refuses a VM running on another core |
| switch-signal table | slots, stamps, decision-due flag | compare-and-swap for claim/release (MC-3); lock for register/unregister |
| current VM, frame stack | g_switch_current_vm and friends |
move to the per-core block |
| console | UART, framebuffer VT100 state, line prefix state | one line lock |
| log region, DoE region, block subsystem | rings, block chain, caches | a lock each |
| heartbeat | tick counters | per-core counters (MC-3); one core until then |
Shared VM code (src/, vendored; runs inside every VM):
| File | Global | Treatment |
|---|---|---|
dictionary_management.c |
sf_fc_list/sf_fc_count/sf_fc_cap/sf_cached_latest: one dictionary lookup index for all VMs, rebuilt whenever a different VM's dictionary is searched |
move into VM (per-VM index). Also stops the rebuild thrash on every switch today. |
word_source/starforth_words.c |
g_prng_state: one PRNG stream for all VMs (accepted at Stage H) |
an atomic step, so the stream stays one stream (order is nondeterministic across cores anyway, MC-R4) |
physics_runtime.c |
g_runtime |
inventory in MC-0; per-VM or atomic |
word_source/dictionary_manipulation_words.c |
state_variable (STATE) |
inventory in MC-0; per-VM |
physics_hotwords_cache.c |
g_hotwords_cache |
retired under __STARKERNEL__ (item 4.1); confirm unused |
word_source/ttf_words.c |
font and raster cache | core 0 only (Hestia's framebuffer) |
2. Staged plan
| Stage | Change | Evidence (named in advance) |
|---|---|---|
| MC-0a | The per-core block, on one core. A per-core structure reached through each ISA's per-CPU register (GS base / TPIDR_EL1 / tp), set up for core 0 at boot. g_switch_current_vm moves into it. |
Standard sequence unchanged. A probe reads the per-core pointer from a normal kernel path and from an interrupt handler, and gets core 0's block both times on all three ISAs. |
| MC-0b | Real spinlocks. A kernel spinlock primitive (atomic exchange, interrupts masked while held on the owning core). sf_mutex_* stop being no-ops. The §1 kernel locks are added. |
Standard sequence unchanged. A probe counts every lock's acquisitions and releases through a boot and the standard sequence: counts balance, and no lock is held across a context switch or on return to the idle point. |
| MC-0c | Shared VM code made per-VM or atomic (§1, second table). The dictionary lookup index moves into VM. |
The dict_hash set unchanged (the index is not hashed). A probe: two VMs searched alternately never rebuild each other's index. Standard sequence. |
| MC-0d | Stadium's dispatch path partitioned (§1). | Standard sequence; conservation holds (stadium_conserved() on every VM, the ledger audit). A probe proves the dispatch path takes no shared lock. |
| MC-1 | Bring up the extra cores and park them halted, per ISA: amd64 (MADT, INIT-SIPI-SIPI, a position-independent trampoline below 1 MiB), aarch64 (DTB /cpus, PSCI CPU_ON), riscv64 (DTB harts, SBI HSM hart_start). QEMU gets -smp 2. |
The boot reports each core online with its own per-core block; the extra cores sit halted (0 idle growth, no spin); the standard sequence unchanged. |
| MC-2 | Observers get core-0 affinity. | With one worker core, behaviour identical to today. A probe shows no observer ever claimed off core 0. |
| MC-3 | Worker cores claim through the shared decision: running_on with compare-and-swap, per-core idle contexts, per-core beats, wake by inter-processor interrupt. |
Two workers genuinely overlapping in time on two cores. A probe counts double claims: 0. Conservation holds. G by counts. Idle worker cores halted (0 idle growth). |
| MC-4 | DoE with cores as a factor (after O-D): per-ISA campaigns at 1, 2 and 4 cores (MC-R5). | Per ISA and core count: 18 MU-TRIAL markers, fail=0, MU-CAMPAIGN: complete. |
Stop conditions (re-plan rather than push on):
dict_hashdiverges across ISAs;- conservation goes false;
- a lock held across a switch, or an unbalanced lock count;
- a double claim;
- an idle core spinning.
3. Execution log
(none yet)