ENGINE step 4 Phase 2 (plan docs/v4.0.0/plans/2026-11-13-engine-step4-phase2-word-accounts.md). Rulings, Captain Bob 2026-11-13: "ID field in the header"; "Per heartbeat tick"; the ACL "All of it in Phase 4". - The word ID, at xt-4 before the flags (ENGINE.md 3b). The system's words are numbered as they are assembled, by a new directive, #id, (and #ids, the count), in the C assembler (text.c) and in the machine ROM's (capsules/v4/rom), which counts in the system's own (NEXT-ID). (HEADER) numbers later words; FORGET gives back the IDs it frees, always the newest; COLD resets to (BOOT-ID); (SEAL) records it. All 313 system headers carry the cell. - The kernel's records (v4/mesh.h): (TELL-DEFINED) and (TELL-FORGOTTEN), requests -19/-20 on port 0, which the kernel puts in (WORD-DEFINED)/(WORD-FORGOTTEN) when it seals a node, and reads the system's own words once. A bit per address marks a word's xt (calls into the ROM or headerless code are not words); at call, the bit test and a count. v4_mesh_charge hands the owner the calls since. - The Stadium: stadium_words_charge -- N calls as N of stadium_word_dispatch's dispatches, shared by calls when the reservoir is short; sk_v4.c charges every node's words at the tick beside its opcodes, and stadium_word_forget before an ID is used again. - Tests first: test_text.c, test_host_dict.c, test_host_quit.c (numbering, FORGET, COLD), test_mesh_boot.c (44 checks), kernel/tests/test_stadium_words.c; qemu_session.py: Hera's words admitted after POST. - amd64: Stadium words: promotions=141 after POST, CONSERVED; POST 539/539; word_count=377; dict_hash 0xa854ba15b437d288 (the new cell); the boot 142 s against Phase 1's 153 s. - v4 test, test-32: all pass; v4-checks: 80 programs under the sanitizers, 0 failures; the hosted builds alike. docs/reference/v4-dictionary.tsv: the two new words; FABRIC-3 XLVIII.24. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017RzZgrf7V7Zk2iczBXDRbm
141 lines
8.1 KiB
C
141 lines
8.1 KiB
C
/* SPDX-License-Identifier: LicenseRef-Starship-1.0
|
|
* Copyright (c) 2023-2026 Robert A. James
|
|
*/
|
|
/* mesh.h -- the kernel's boot of the fabric: Hera born empty, given the
|
|
* system, and every node stepped together. docs/v4.0.0/MESH.md 9,
|
|
* MACHINE.md 3; #189, ENGINE step 4 Phase 1, Task 5b (Captain Bob,
|
|
* 2026-11-13: "Build it to proper spec").
|
|
*
|
|
* There is no scheduler (JUSTIFICATION.md 4: "There is no scheduler to
|
|
* write"): every awake node executes an instruction word at each step of
|
|
* the fabric (fabric.h), and a node with nothing to do waits at a port.
|
|
*
|
|
* THE BOOT, as v4/tests/test_host_unit.c does it on the host:
|
|
* 1. the nucleus: the machine's ROM assembles the system's source on a
|
|
* node of its own (v4/boot.h, v4_boot_assemble), and the system, as
|
|
* assembled, is a capsule of F18 cells -- a node that is born is given
|
|
* assembled code, never the source (Captain Bob, 2026-10-15);
|
|
* 2. Hera is born empty at place 0, with the machine's ROM: the kernel is
|
|
* on her port 0 -- it gives her the nucleus a cell at a time, and takes
|
|
* her requests: blocks, the kernel's words, the registry (manage.h) --
|
|
* and the console on her port 1, which speaks whole messages;
|
|
* 3. she is told she is node 10 and where the console is, entered in the
|
|
* registry, made the kernel's words, given FORTH-79, sealed, POSTed,
|
|
* given the kernel's capsules, and sealed;
|
|
* printing the same parity lines as v4_boot_run (boot.h).
|
|
*
|
|
* A NODE IS BORN (NODE-BORN): in storage the owner gives, with a mesh
|
|
* node's ROM, the kernel on its port 0 for its blocks; it is given the
|
|
* nucleus by whoever birthed it (centre.4th). NODE-KILL gives the storage
|
|
* back.
|
|
*
|
|
* Nothing here uses the C library. The owner supplies all the memory.
|
|
*/
|
|
#ifndef V4_MESH_H
|
|
#define V4_MESH_H
|
|
|
|
#include "v4/boot.h"
|
|
#include "v4/blocks.h"
|
|
#include "v4/fabric.h"
|
|
#include "v4/manage.h"
|
|
|
|
#define V4_MESH_HERA 10 /* Hera's number, as the host mesh numbers her */
|
|
#define V4_MESH_CONSOLE 1 /* the console's number as a sender, and her port to it */
|
|
#define V4_MESH_NUCLEUS_CELLS (2u * V4_NODE_WORDS + 64u)
|
|
|
|
/* A WORD'S ACCOUNTS (#189, Phase 2; ENGINE.md 3b): the kernel's record of a word on a node, joined to
|
|
* it by the word ID in its header. The node tells the kernel of each entry made and of entries gone
|
|
* (dict.f18, (TELL-DEFINED) and (TELL-FORGOTTEN): requests V4_REQ_WORD_DEFINED and _FORGOTTEN on port
|
|
* 0); the kernel reads the system's own once, when the node is sealed. At every `call` to a word
|
|
* its record counts one: `calls` (v3's execution_heat) and `since`, which the owner takes and clears
|
|
* when it charges the Stadium (v4_mesh_charge; Captain Bob, 2026-11-13: "Per heartbeat tick"). */
|
|
#define V4_MESH_WORD_IDS 1024u /* word IDs a record is kept for: v3's DICTIONARY_SIZE, the Stadium's bound */
|
|
#define V4_REQ_WORD_DEFINED (-19)
|
|
#define V4_REQ_WORD_FORGOTTEN (-20)
|
|
typedef struct {
|
|
v4_uheat_t calls; /* every call since the word was defined */
|
|
v4_uheat_t since; /* calls since the owner last charged them */
|
|
v4_cell xt; /* the word's xt; 0: no word has this ID */
|
|
} v4_mesh_account;
|
|
|
|
typedef struct v4_mesh v4_mesh;
|
|
struct v4_mesh {
|
|
/* ---- the owner's: set before v4_mesh_boot ---- */
|
|
v4_place *places; /* the fabric's room: `capacity` places */
|
|
unsigned capacity;
|
|
v4_wire_queue *queues; /* the wires' memory (fabric.h): two for every wire at once */
|
|
unsigned queue_count;
|
|
v4_manage_entry *reg; /* the registry: `capacity` entries */
|
|
v4_blocks *blocks; /* each place's block window, kept by the kernel: `capacity` of them */
|
|
v4_fabric_node *nucleus; /* where the ROM assembles the system: a node of its own */
|
|
v4_fabric_node *hera; /* Hera's storage */
|
|
v4_device *kernel; /* the kernel on each place's port 0: `capacity` of them */
|
|
/* storage for a node to be born, or 0: none; and given back */
|
|
v4_fabric_node *(*room)(void *self);
|
|
void (*unroom)(void *self, v4_fabric_node *x);
|
|
/* a node has been born at `place`, numbered `number` once it is told; is gone (may be 0) */
|
|
void (*born)(void *self, unsigned place);
|
|
void (*gone)(void *self, unsigned place);
|
|
/* a node the asker birthed has its system: its parity (may be 0) */
|
|
void (*parity)(void *self, unsigned place, v4_cell number, const v4_node *n);
|
|
/* the console, the keyboard, the kernel's words and capsules: as v4_boot's (boot.h) */
|
|
void (*out)(const char *text, unsigned len);
|
|
int (*key)(void);
|
|
const char *const *words;
|
|
unsigned word_count;
|
|
void (*serve)(v4_node *n, unsigned request);
|
|
const char *const *capsules;
|
|
unsigned capsule_count;
|
|
v4_image *im; /* the map's description (v4_map_image), which the boot completes */
|
|
/* the words' accounts: `capacity` x V4_MESH_WORD_IDS records, and `capacity` x V4_NODE_WORDS / 8
|
|
* bytes, a bit for each address of a node: set for a word's xt (0: none kept) */
|
|
v4_mesh_account *accounts;
|
|
unsigned char *is_word;
|
|
/* a word has gone, its ID free for the next: the owner forgets what it keeps by it (may be 0) */
|
|
void (*forgot)(void *self, unsigned place, v4_cell id);
|
|
void *self;
|
|
|
|
/* ---- the mesh's own ---- */
|
|
v4_fabric f;
|
|
v4_manage m;
|
|
unsigned hera_place;
|
|
v4_cell cells[V4_MESH_NUCLEUS_CELLS]; /* the nucleus as a capsule of F18 cells */
|
|
unsigned cell_count, given; /* how many; how many given to Hera */
|
|
unsigned reading_nucleus[64]; /* by place: the next nucleus cell a CAPSULE-CELL gives; 0: not open */
|
|
unsigned dones; /* how many texts have said how they ended, ever */
|
|
v4_cell done_from, done_how; /* the last of them: from which node, and how */
|
|
v4_cell owed_from; /* a node told texts that were left "waiting" ... */
|
|
unsigned owed; /* ... and how many of their ends are still to come */
|
|
};
|
|
|
|
/* The boot: the nucleus, Hera, her system, POST. 1, Hera asleep at her
|
|
* wires waiting for a line; or 0, the failure printed. */
|
|
int v4_mesh_boot(v4_mesh *ms);
|
|
|
|
/* Text for node `node`, from the console, and the fabric stepped until that node says how the text
|
|
* ended: what any node prints goes to `out`; returns how it ended (V4_TEXT_*), or
|
|
* V4_BOOT_LINE_STOPPED / _TOO_LONG / _REFUSED / _NO_INPUT (boot.h). Other nodes may run on after it
|
|
* returns (v4_mesh_step). V4_BOOT_LINE_WAITING: Hera is asleep awaiting an answer that has not come
|
|
* -- nothing else can run, or other nodes have run a long while and not given it; the next text from
|
|
* the console breaks the wait (MESH.md 7b.6), and if the answer comes first, `dones` says so. */
|
|
int v4_mesh_tell(v4_mesh *ms, v4_cell node, const char *text, unsigned len);
|
|
|
|
/* One step of the fabric, as the host's idle: every awake node executes an instruction word, and what
|
|
* comes back to the console is printed (or counted, for how a text ended: `dones`). Returns how many
|
|
* instructions were retired. The host calls it while it waits, whenever v4_mesh_busy says a node can
|
|
* run: every node steps together, between lines as during them. */
|
|
unsigned v4_mesh_step(v4_mesh *ms);
|
|
int v4_mesh_busy(const v4_mesh *ms);
|
|
|
|
/* A word's record on the node in `place`, by its xt: 0 if that is not a word's xt. */
|
|
const v4_mesh_account *v4_mesh_account_at(const v4_mesh *ms, unsigned place, v4_cell xt);
|
|
|
|
/* For each word on the node in `place` called since the last charge: `each(ctx, id, calls)`, and its
|
|
* count since is cleared. */
|
|
void v4_mesh_charge(v4_mesh *ms, unsigned place, void (*each)(void *ctx, v4_cell id, v4_uheat_t calls), void *ctx);
|
|
|
|
/* The node numbered `number`, or 0. */
|
|
v4_fabric_node *v4_mesh_node(const v4_mesh *ms, v4_cell number);
|
|
|
|
#endif
|