safety commit

This commit is contained in:
rajames
2026-10-19 06:35:46 -04:00
parent 63434f3762
commit 5707b07abf
12 changed files with 122 additions and 75 deletions
+24
View File
@@ -3,6 +3,7 @@
* Nothing here uses the C library: the bare-metal kernel links this file.
*/
#include "v4/manage.h"
#include "v4/message.h"
const char *const v4_manage_words[V4_MANAGE_WORDS] = {
"NODE-ME", "NODE-BORN", "NODE-WIRE", "NODE-UNWIRE", "NODE-SLEEP", "NODE-WAKE", "NODE-KILL", "NODE-PARITY",
@@ -45,6 +46,28 @@ static int mine(const v4_manage *m, const v4_manage_entry *asker, unsigned place
const v4_manage_entry *e = by_place(m, place);
return asker && e && (e == asker || e->parent == asker->number);
}
/* THE KERNEL TELLS A NODE'S GOING (MESH.md 9a, ruled 2026-10-16). Every live node that has a parent, and is
* wired to it, is put a GONE about `gone` on the wire from its parent, as if its parent had sent it: so the
* node believes it, its parent being its centre (7b.4). No node hands a GONE on. A wire with no room for it
* is not waited for: that node is not told (as an answer whose way back is full, 7d.6). */
static void tell_gone(const v4_manage *m, v4_cell gone)
{
unsigned k, port;
v4_cell hd[V4_WIRE_HEADER], text[1];
for (k = 0; k < m->reg_cap; k++) {
const v4_manage_entry *c = &m->reg[k], *p;
if (c->number == 0 || c->parent == 0 || !(p = by_number(m, c->parent))) continue;
for (port = 0; port < V4_PORTS; port++) {
const v4_wire *w = &m->f->place[c->place].wire[port];
if (w->kind != V4_WIRE_NODE || w->node != p->place || !w->rx) continue;
hd[0] = c->number; hd[1] = p->number; hd[2] = V4_MSG_GONE; hd[3] = 16; hd[4] = 0; hd[5] = 0; hd[6] = 4;
text[0] = gone;
(void)v4_wire_put(w->rx, hd, text);
break;
}
}
}
/* error 12 on the node that asked: a store to NODE-ERROR raises it (D-18) */
static int refuse(v4_node *n) { v4_node_store(n, n->error_reg, 12); return 1; }
@@ -117,6 +140,7 @@ int v4_manage_serve(const v4_manage *m, unsigned place, v4_cell request)
* parent, so a node born later under it inherits nothing (the final review of step 7) */
for (k = 0; k < m->reg_cap; k++) if (m->reg[k].number != 0 && m->reg[k].parent == gone_number) m->reg[k].parent = me->number;
if (was && m->gone) m->gone(m->self, gone_place, was);
tell_gone(m, gone_number);
}
return 1;
case V4_REQ_NODE_PARITY: { /* ( place number -- ) */