fix(v4.0.0): step 6e review round 2 -- only the message looked at is taken, moved or dropped; the kernel's port has no queue in a fabric; an answer nobody awaits is not a loss
- Engine: a wire keeps whether the message at its mark is the one last looked at; a node's take, move and drop of any other answer 3 and write nothing (MESH.md 7d.3). A wire cut and made again between a look and a take no longer has a NACK done as text, or 256 cells written where one was looked for. - Engine: v4_fabric_wire_kernel wires a kernel to a port with no queues; a message for it is refused at once, error 18, on a mesh as on the products. - The result of a drop is looked at; a take that does not take has the message dropped, or gone past: nothing goes round. - An answer nobody waits for is let go uncounted; (LOST) counts what should have been delivered or acted on and was not. The flood's account is exact. - Error 18 from under a word that was printing empties the data stack, as a fault does: that word's own values are not left there. - Tests: the take and drop windows cut at every step, with and without another message put; a refusal owed to a stuck node whose wire is full. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
6a7d0aa27f
commit
f1419e739c
+12
-3
@@ -157,6 +157,15 @@ int v4_fabric_wire(v4_fabric *f, unsigned a, unsigned pa, unsigned b, unsigned p
|
||||
return 1;
|
||||
}
|
||||
|
||||
int v4_fabric_wire_kernel(v4_fabric *f, unsigned a, unsigned pa, const v4_device *device)
|
||||
{
|
||||
if (!there(f, a, pa) || !device) return 0;
|
||||
cut(f, a, pa);
|
||||
f->place[a].wire[pa].kind = V4_WIRE_DEVICE;
|
||||
f->place[a].wire[pa].device = device; /* and no queues: it takes no messages */
|
||||
return 1;
|
||||
}
|
||||
|
||||
int v4_fabric_wire_device(v4_fabric *f, unsigned a, unsigned pa, const v4_device *device)
|
||||
{
|
||||
if (!there(f, a, pa) || !device) return 0;
|
||||
@@ -346,7 +355,7 @@ static int operate(v4_fabric *f, unsigned id, v4_cell *how)
|
||||
break;
|
||||
case 2: /* take */
|
||||
if (!rx) { *how = V4_WIRE_NO_ONE; break; }
|
||||
if (rx->mark >= rx->used) { *how = V4_WIRE_NO_MESSAGE; break; }
|
||||
if (rx->mark >= rx->used || !rx->looked) { *how = V4_WIRE_NO_MESSAGE; break; } /* only the message last looked at (wire.h) */
|
||||
(void)v4_wire_look(rx, h);
|
||||
cells = v4_wire_cells(h[6]) - V4_WIRE_HEADER;
|
||||
if (!span_ok(n, a, V4_WIRE_HEADER) || !span_ok(n, b, cells)) { *how = V4_WIRE_NOT_A_MESSAGE; break; }
|
||||
@@ -354,12 +363,12 @@ static int operate(v4_fabric *f, unsigned id, v4_cell *how)
|
||||
break;
|
||||
case 3: /* move */
|
||||
if (!rx) { *how = V4_WIRE_NO_ONE; break; }
|
||||
if (rx->mark >= rx->used) { *how = V4_WIRE_NO_MESSAGE; break; }
|
||||
if (rx->mark >= rx->used || !rx->looked) { *how = V4_WIRE_NO_MESSAGE; break; }
|
||||
to = a >= 0 && a < (v4_cell)V4_PORTS ? going(f, id, (unsigned)a) : 0;
|
||||
*how = to ? v4_wire_move(rx, to) : V4_WIRE_NO_ONE;
|
||||
break;
|
||||
case 4: /* drop */
|
||||
*how = rx ? v4_wire_drop(rx) : V4_WIRE_NO_ONE;
|
||||
*how = !rx ? V4_WIRE_NO_ONE : rx->looked ? v4_wire_drop(rx) : V4_WIRE_NO_MESSAGE;
|
||||
break;
|
||||
case 5: /* put */
|
||||
if (!tx) { *how = V4_WIRE_NO_ONE; break; }
|
||||
|
||||
+6
-1
@@ -14,6 +14,7 @@ void v4_wire_reset(v4_wire_queue *q)
|
||||
q->mark = 0;
|
||||
q->arrived = 0;
|
||||
q->freed = 0;
|
||||
q->looked = 0;
|
||||
}
|
||||
|
||||
unsigned v4_wire_cells(v4_cell length)
|
||||
@@ -62,21 +63,24 @@ int v4_wire_put(v4_wire_queue *q, const v4_cell *header7, const v4_cell *text)
|
||||
|
||||
void v4_wire_first(v4_wire_queue *q)
|
||||
{
|
||||
q->looked = 0;
|
||||
q->mark = 0;
|
||||
}
|
||||
|
||||
int v4_wire_next(v4_wire_queue *q)
|
||||
{
|
||||
q->looked = 0;
|
||||
if (q->mark >= q->used) return V4_WIRE_NO_MESSAGE;
|
||||
q->mark += size_at(q, q->mark);
|
||||
return q->mark < q->used ? V4_WIRE_DONE : V4_WIRE_NO_MESSAGE;
|
||||
}
|
||||
|
||||
int v4_wire_look(const v4_wire_queue *q, v4_cell *header7)
|
||||
int v4_wire_look(v4_wire_queue *q, v4_cell *header7)
|
||||
{
|
||||
unsigned i;
|
||||
if (q->mark >= q->used) return V4_WIRE_NO_MESSAGE;
|
||||
for (i = 0; i < V4_WIRE_HEADER; i++) header7[i] = q->cell[slot(q, q->mark + i)];
|
||||
q->looked = 1;
|
||||
return V4_WIRE_DONE;
|
||||
}
|
||||
|
||||
@@ -91,6 +95,7 @@ static void remove_marked(v4_wire_queue *q)
|
||||
}
|
||||
q->used -= n;
|
||||
q->freed = 1;
|
||||
q->looked = 0;
|
||||
}
|
||||
|
||||
int v4_wire_take(v4_wire_queue *q, v4_cell *header7, v4_cell *text, unsigned text_cap)
|
||||
|
||||
Reference in New Issue
Block a user