fix(v4.0.0): step 6d after its review -- no error in the middle of the messages waiting, no offer left standing
Ruled 2026-10-08: A, B, C, D and the guard for a half message. Each with a scene in test_host_mesh.c that failed first. A. The words of a message after its first are written from the passes over the messages waiting by (!W): an offer and a wait for that offer only (a new engine address). A reader removed in mid-message makes no error; the rest is let go and counted. Before, the error left the messages waiting in pieces and the node going round for ever. B. A store to the wait withdraws every offer; (GATE1) and (PAY-SET) do it first. Before, text begun after a node went round without sleeping could go to the port of an older offer: text for one node was done by another. C. What a finished text printed is put with the messages waiting, as how it ended is. With no room either is let go and counted; neither is begun as a message from (FINISH) any more, where a stuck node on the way held the whole node. D. Only what a sender is owed from an earlier text -- its output, how it ended -- holds that sender's next text back; a GONE does not; and what cannot be noted holds nothing. A node's own messages keep the order they were made in. - A message half taken in when its writer is removed is let go ((MQ-MEND)), not kept as if whole. - Smaller: a refused line no longer ends a waiting text 'Interrupted'; a node's own queued messages may be passed on by 16 nodes, not 15; no value is left on the stack when a port goes in mid-refusal. make -C v4 test and sanitize at both widths, hosted-check. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
380f1cc6ec
commit
2cf37aab4f
+8
-6
@@ -99,6 +99,7 @@ void v4_node_store(v4_node *n, v4_cell addr, v4_cell value)
|
||||
n->offers |= 1u << k;
|
||||
return;
|
||||
}
|
||||
if (port == (int)V4_PORT_WAIT) { n->offers = 0; return; } /* a store to the wait: every offer is withdrawn */
|
||||
if (port >= 0) { v4_node_fault(n, V4_FAULT_ADDRESS, addr); return; } /* "any", "which port" and the rest are not written to */
|
||||
}
|
||||
/* The stack registers: a store empties the stack. -1 when not attached. */
|
||||
@@ -128,7 +129,7 @@ v4_cell v4_node_fetch(v4_node *n, v4_cell addr)
|
||||
if (port == (int)V4_PORTS + 1) return (v4_cell)n->last_from;
|
||||
if (port == (int)V4_PORTS + 2) return (v4_cell)n->writers;
|
||||
if (port == (int)V4_PORTS + 3) return (v4_cell)n->readers;
|
||||
if (port == (int)V4_PORT_WAIT) {
|
||||
if (port == (int)V4_PORT_WAIT || port == (int)V4_PORT_WAIT1) {
|
||||
/* the wait: the word that came, or 0 for an offer taken */
|
||||
if (!n->given) return 0;
|
||||
n->given = 0;
|
||||
@@ -206,18 +207,19 @@ void v4_node_port_status(v4_node *n, unsigned writers, unsigned readers)
|
||||
|
||||
int v4_node_port_index(const v4_node *n, v4_cell addr)
|
||||
{
|
||||
if (n->port < 0 || addr < n->port || addr > n->port + (v4_cell)V4_PORT_WAIT) return -1;
|
||||
if (n->port < 0 || addr < n->port || addr > n->port + (v4_cell)V4_PORT_WAIT1) return -1;
|
||||
return (int)(addr - n->port);
|
||||
}
|
||||
|
||||
int v4_node_read_ready(v4_node *n, v4_cell addr)
|
||||
{
|
||||
int port = v4_node_port_index(n, addr);
|
||||
if (port < 0 || (port > (int)V4_PORT_ANY && port != (int)V4_PORT_WAIT)) return 1;
|
||||
if (port < 0 || (port > (int)V4_PORT_ANY && port != (int)V4_PORT_WAIT && port != (int)V4_PORT_WAIT1)) return 1;
|
||||
if (n->given && (port >= (int)V4_PORT_ANY || (unsigned)port == n->given_port)) return 1;
|
||||
n->reading = 1;
|
||||
n->waiting = port == (int)V4_PORT_WAIT; /* the wait is a read of any port, with offers standing */
|
||||
n->read_port = n->waiting ? V4_PORT_ANY : (unsigned)port;
|
||||
n->waiting = port >= (int)V4_PORT_WAIT; /* the wait is a read of any port, with offers standing; */
|
||||
n->read_port = port == (int)V4_PORT_WAIT ? V4_PORT_ANY /* the wait for an offer only reads no port at all */
|
||||
: (unsigned)port;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -288,7 +290,7 @@ int v4_node_port_gone(v4_node *n, v4_cell code)
|
||||
return 1;
|
||||
}
|
||||
if (n->asking) n->asking = 0;
|
||||
else if (n->reading && !n->given && n->read_port != V4_PORT_ANY) n->reading = 0;
|
||||
else if (n->reading && !n->given && n->read_port < V4_PORTS) n->reading = 0;
|
||||
else return 0;
|
||||
v4_node_store(n, n->error_reg, code); /* raises it: P is the node's handler now */
|
||||
return 1;
|
||||
|
||||
Reference in New Issue
Block a user