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
+7
-3
@@ -147,11 +147,15 @@ static unsigned hand_over_write(v4_fabric *f, unsigned a)
|
||||
static unsigned hand_over_read(v4_fabric *f, unsigned a)
|
||||
{
|
||||
v4_node *n = &f->place[a].node->n;
|
||||
unsigned first = n->read_port == V4_PORT_ANY ? 0 : n->read_port;
|
||||
unsigned last = n->read_port == V4_PORT_ANY ? V4_PORTS - 1 : n->read_port;
|
||||
unsigned first;
|
||||
unsigned last;
|
||||
unsigned k;
|
||||
v4_cell value;
|
||||
|
||||
if (n->read_port > V4_PORT_ANY) return 0; /* the wait for an offer only: it reads no port */
|
||||
first = n->read_port == V4_PORT_ANY ? 0 : n->read_port;
|
||||
last = n->read_port == V4_PORT_ANY ? V4_PORTS - 1 : n->read_port;
|
||||
|
||||
for (k = first; k <= last; k++) {
|
||||
const v4_wire *w = &f->place[a].wire[k];
|
||||
if (w->kind == V4_WIRE_DEVICE && w->device->give && w->device->give(w->device->self, &value)) {
|
||||
@@ -241,7 +245,7 @@ unsigned v4_fabric_step(v4_fabric *f)
|
||||
if (!awake(f, i)) continue;
|
||||
n = &f->place[i].node->n;
|
||||
if ((n->asking && f->place[i].wire[n->ask_port].kind == V4_WIRE_NONE)
|
||||
|| (n->reading && !n->given && n->read_port != V4_PORT_ANY && f->place[i].wire[n->read_port].kind == V4_WIRE_NONE))
|
||||
|| (n->reading && !n->given && n->read_port < V4_PORTS && f->place[i].wire[n->read_port].kind == V4_WIRE_NONE))
|
||||
done += (unsigned)v4_node_port_gone(n, f->gone_error);
|
||||
else if (v4_node_in_wait(n)) { /* an offer on a port with nothing on it */
|
||||
unsigned k;
|
||||
|
||||
Reference in New Issue
Block a user