feat(v4.0.0): five nodes from nothing -- Hera asks for nodes, births and joins them
MESH.md step 5, in the fabric under test; the products are still one node each until steps 8 and 9. manage.c: what Hera asks of whoever holds the fabric, eleven requests by KERNEL-WORD -- NODE-ME -BORN -WIRE -UNWIRE -SLEEP -WAKE -KILL -PARITY and CAPSULE-OPEN -CELL -LINE. Nucleus: PORT!, SEND-ON, AWAIT, (SEAL). capsules/v4/hera.4th: BIRTH and UNIT, the unit rule in FORTH and nowhere else. The dictionary hash moves to the engine (v4_image_dict_hash). test_host_unit.c, 34 checks, 64-bit: Hera is born empty, takes the nucleus through her port, FORTH-79, POST and her capsule; 10 UNIT; four nodes are born, each takes the nucleus and FORTH-79 through its port from Hera and passes POST 538/538; four parities, one dictionary hash; they talk, and a message between two corners not wired goes by Hera. All v4 tests at both widths and under ASan+UBSan. hosted-check on three ISAs. Bare metal: logs/20261006-143934 (amd64), -144204 (aarch64), -144601 (riscv64). Open, recorded in MESH.md: not run at 32 bits; a node that never answers leaves Hera waiting; the capsules are read from files in the test, not from the baked directory. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
f9c034cadd
commit
348eed7fa1
@@ -65,6 +65,12 @@ extern const v4_image v4_capsule_image;
|
||||
* back to, and FORGET will not go below it. */
|
||||
void v4_image_seal(v4_node *n, const v4_image *im);
|
||||
|
||||
/* The dictionary hash of a node started from `im`: FNV-1a over its memory
|
||||
* below HERE, a cell at a time, low byte first, and then LATEST. It does
|
||||
* not depend on the machine: every build of one commit, with one cell
|
||||
* width, gives the same hash for the same dictionary. */
|
||||
uint64_t v4_image_dict_hash(const v4_node *n, const v4_image *im);
|
||||
|
||||
/* A node newly born (node.h), with the registers the nucleus expects of the
|
||||
* node it runs on -- and `disk`, `blocks` blocks of 1024 bytes, as its block
|
||||
* storage, or none if `disk` is 0. Its memory is empty and it is blocked
|
||||
|
||||
@@ -0,0 +1,81 @@
|
||||
/* manage.h -- what Hera asks of whoever holds the fabric.
|
||||
* docs/v4.0.0/MESH.md section 9.
|
||||
*
|
||||
* Hera decides which nodes exist and are awake (MESH.md ruling 7). She is
|
||||
* a node like any other and cannot make one: she asks, by a write to the
|
||||
* port where her requests go (ENGINE.md 3.3), and the write blocks her until
|
||||
* she is answered. Each request is a word on her, made with KERNEL-WORD
|
||||
* (v4/capsule/compile.v4); its arguments are what it finds on her data
|
||||
* stack and its results are what is left there.
|
||||
*
|
||||
* These are the requests, in order. The n-th is request `first + n`, where
|
||||
* `first` is whatever number the host gives the first of them:
|
||||
*
|
||||
* NODE-ME ( -- place ) the place of the node that asks
|
||||
* NODE-BORN ( -- place | -1 ) a node is born, empty, listening at
|
||||
* its ports; -1: there is no room
|
||||
* NODE-WIRE ( a pa b pb -- flag ) port pa of the node at a is wired
|
||||
* to port pb of the node at b
|
||||
* NODE-UNWIRE ( a pa -- ) what is on that port is cut
|
||||
* NODE-SLEEP ( place -- ) it executes nothing until woken
|
||||
* NODE-WAKE ( place -- )
|
||||
* NODE-KILL ( place -- ) it is removed, whatever it was doing
|
||||
* NODE-PARITY ( place number -- ) the host records the node's parity:
|
||||
* its number and its dictionary hash
|
||||
* CAPSULE-OPEN ( baddr u -- flag ) the capsule of that name is found
|
||||
* and checked, and is read from its
|
||||
* start; 0: there is none, or it is
|
||||
* not what it says it is
|
||||
* CAPSULE-CELL ( -- w flag ) the next cell of a capsule of F18
|
||||
* code; 0 0 when there are no more
|
||||
* CAPSULE-LINE ( baddr -- u | -1 ) the next line of a capsule of
|
||||
* FORTH blocks, put at baddr: at
|
||||
* most 64 characters; -1 at its end
|
||||
*
|
||||
* A place is where a node is in the fabric (fabric.h); it is the host's
|
||||
* name for the node. A node's number, which messages are addressed by, is
|
||||
* the nodes' own affair: Hera gives a newborn its number by telling it.
|
||||
*
|
||||
* Only the node the host has wired to this is answered, so only Hera's
|
||||
* requests are honoured. The unit rule (MESH.md ruling 5) is not here: it
|
||||
* is what Hera does with these, in her capsule.
|
||||
*
|
||||
* Nothing here uses the C library: the bare-metal kernel links this file.
|
||||
*/
|
||||
#ifndef V4_MANAGE_H
|
||||
#define V4_MANAGE_H
|
||||
|
||||
#include "v4/fabric.h"
|
||||
|
||||
#define V4_MANAGE_WORDS 11
|
||||
extern const char *const v4_manage_words[V4_MANAGE_WORDS];
|
||||
#define V4_MANAGE_LINE 64 /* the most characters in a line of a block */
|
||||
|
||||
typedef struct {
|
||||
v4_fabric *f;
|
||||
|
||||
/* A node is born: the host finds it room, adds it to the fabric and
|
||||
* gives it what a node's hardware gives it. Its place, or -1. */
|
||||
int (*born)(void *self);
|
||||
/* The node that was at `place` has been removed: its room is free. */
|
||||
void (*gone)(void *self, unsigned place, v4_fabric_node *was);
|
||||
/* The capsule called `name`, `len` characters: found, its hash and
|
||||
* signature checked, and to be read from its start. 1, or 0. */
|
||||
int (*open)(void *self, const char *name, unsigned len);
|
||||
/* The next cell of the open capsule: 1 with it in *w, 0 at its end. */
|
||||
int (*cell)(void *self, v4_cell *w);
|
||||
/* The next line of the open capsule that is part of a block, into
|
||||
* `text`, at most V4_MANAGE_LINE characters: its length, or -1. */
|
||||
int (*line)(void *self, char *text);
|
||||
/* The node at `place`, which Hera calls `number`: record its parity. */
|
||||
void (*parity)(void *self, unsigned place, v4_cell number, const v4_node *n);
|
||||
void *self;
|
||||
} v4_manage;
|
||||
|
||||
/* The node at `place` has written request `n` (0 is NODE-ME) to the port
|
||||
* its requests go to. Its arguments are taken from its data stack and its
|
||||
* results left there. Returns 1; 0 if `n` is not one of the requests, and
|
||||
* then nothing has been done. */
|
||||
int v4_manage_serve(const v4_manage *m, unsigned place, unsigned n);
|
||||
|
||||
#endif /* V4_MANAGE_H */
|
||||
Reference in New Issue
Block a user