feat(v4): the kernel keeps a registry of nodes and checks who may ask (MESH.md 9a.4)
Any node may birth and wire its own; only Hera sleeps, wakes and kills, by number. Requests have fixed numbers, -6 to -18. NODE-BORN takes the number; NODE-KILL a number. test_manage.c: 41 checks at both widths. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
bf97f339f6
commit
d154342314
+83
-58
@@ -1,44 +1,43 @@
|
||||
/* manage.h -- what Hera asks of whoever holds the fabric.
|
||||
* docs/v4.0.0/MESH.md section 9.
|
||||
/* manage.h -- what a node asks of whoever holds the fabric about nodes and
|
||||
* capsules. docs/v4.0.0/MESH.md sections 9 and 9a.
|
||||
*
|
||||
* 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
|
||||
* (capsules/v4/sys/compile.f18); its arguments are what it finds on her data
|
||||
* stack and its results are what is left there.
|
||||
* Births follow v3 (MESH.md 9): any node may birth, on its own ports, and is
|
||||
* its child's parent; only Hera may put a node to sleep, wake it or remove
|
||||
* it. The kernel keeps a registry of the live nodes -- each one's number,
|
||||
* place and parent -- as v3's kernel keeps its registry of VMs, and checks
|
||||
* every request against it. A request that is refused is error 12 on the
|
||||
* node that asked, and changes nothing.
|
||||
*
|
||||
* 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:
|
||||
* Each request is a word on the node made with KERNEL-WORD (capsules/v4/
|
||||
* centre.4th, hera.4th), whose number is fixed, below the block requests'
|
||||
* (v4/blocks.h):
|
||||
*
|
||||
* 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
|
||||
* -6 NODE-ME ( -- place ) any node
|
||||
* -7 NODE-BORN ( number -- place | -1 ) any node in the registry: a node
|
||||
* is born, empty, and entered with
|
||||
* the asker as its parent; a number
|
||||
* that is live, or below 1, is
|
||||
* refused; -1: no room
|
||||
* -8 NODE-WIRE ( a pa b pb -- flag ) a and b each the asker or a node
|
||||
* it birthed
|
||||
* -9 NODE-UNWIRE ( a pa -- ) a the asker or a node it birthed
|
||||
* -10 NODE-SLEEP ( number -- ) Hera
|
||||
* -11 NODE-WAKE ( number -- ) Hera
|
||||
* -12 NODE-KILL ( number -- ) Hera; not herself; a number not
|
||||
* live does nothing. The node's
|
||||
* children are not removed, as v3.
|
||||
* -13 NODE-PARITY ( place number -- ) for a node the asker birthed,
|
||||
* under the number it was born as
|
||||
* -14 CAPSULE-OPEN ( baddr u -- flag ) any node in the registry: the
|
||||
* capsule is found, checked and
|
||||
* read from its start by that node
|
||||
* -15 CAPSULE-CELL ( -- w flag ) the next cell of the asker's
|
||||
* -16 CAPSULE-LINE ( baddr -- u | -1 ) the next line of the asker's
|
||||
* -17 NODE-CHILD ( number i -- child | 0 ) any node: the i-th live child
|
||||
* -18 NODE-PLACE ( number -- place | -1 ) any node
|
||||
*
|
||||
* 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.
|
||||
* A place is where a node is in the fabric (fabric.h): the host's name for
|
||||
* it. A number is the nodes' own name for it, which messages go by.
|
||||
*
|
||||
* Nothing here uses the C library: the bare-metal kernel links this file.
|
||||
*/
|
||||
@@ -47,35 +46,61 @@
|
||||
|
||||
#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 */
|
||||
#define V4_REQ_NODE_ME (-6)
|
||||
#define V4_REQ_NODE_BORN (-7)
|
||||
#define V4_REQ_NODE_WIRE (-8)
|
||||
#define V4_REQ_NODE_UNWIRE (-9)
|
||||
#define V4_REQ_NODE_SLEEP (-10)
|
||||
#define V4_REQ_NODE_WAKE (-11)
|
||||
#define V4_REQ_NODE_KILL (-12)
|
||||
#define V4_REQ_NODE_PARITY (-13)
|
||||
#define V4_REQ_CAPSULE_OPEN (-14)
|
||||
#define V4_REQ_CAPSULE_CELL (-15)
|
||||
#define V4_REQ_CAPSULE_LINE (-16)
|
||||
#define V4_REQ_NODE_CHILD (-17)
|
||||
#define V4_REQ_NODE_PLACE (-18)
|
||||
|
||||
#define V4_MANAGE_WORDS 13 /* -6 down to -18 */
|
||||
extern const char *const v4_manage_words[V4_MANAGE_WORDS]; /* [k] is request -6 - k */
|
||||
#define V4_MANAGE_LINE 64 /* the most characters in a line of a block */
|
||||
|
||||
/* A live node: number 0 marks a free entry. */
|
||||
typedef struct {
|
||||
v4_cell number;
|
||||
v4_cell parent; /* the number of the node that birthed it; 0: none */
|
||||
unsigned place;
|
||||
} v4_manage_entry;
|
||||
|
||||
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. */
|
||||
v4_fabric *f;
|
||||
v4_manage_entry *reg; /* the registry: room the owner gives */
|
||||
unsigned reg_cap;
|
||||
unsigned hera; /* Hera's place: the one node that may sleep, wake and kill */
|
||||
/* 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. */
|
||||
/* For the node at `asker`: the capsule called `name`, found, its hash
|
||||
* and signature checked, and to be read from its start. 1, or 0. */
|
||||
int (*open)(void *self, unsigned asker, const char *name, unsigned len);
|
||||
/* The next cell of the capsule `asker` has open: 1 with it in *w, 0 at its end. */
|
||||
int (*cell)(void *self, unsigned asker, v4_cell *w);
|
||||
/* The next line of it that is part of a block, at most V4_MANAGE_LINE characters: its length, or -1. */
|
||||
int (*line)(void *self, unsigned asker, char *text);
|
||||
/* The node at `place`, numbered `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);
|
||||
/* Enter a node made by the owner -- Hera -- in the registry. 1; 0 if the
|
||||
* number is below 1, already live, or there is no room. */
|
||||
int v4_manage_enter(const v4_manage *m, v4_cell number, unsigned place, v4_cell parent);
|
||||
|
||||
/* The node at `place` has written `request` to the port its requests go to.
|
||||
* 0 if it is not one of these, and nothing is done; otherwise 1: it was
|
||||
* served, its arguments taken from the node's data stack and its results
|
||||
* left there, or it was refused and error 12 raised on the node. */
|
||||
int v4_manage_serve(const v4_manage *m, unsigned place, v4_cell request);
|
||||
|
||||
#endif /* V4_MANAGE_H */
|
||||
|
||||
Reference in New Issue
Block a user