feat(v4.0.0): a node looks before it writes; two neighbours no longer stop each other
MESH.md step 4, the fault found there, as ruled (section 7a): a node writes only to a neighbour that is reading, keeps what it takes in meanwhile, and loses and counts what it has no room for. Engine: two more addresses after a node's ports -- which ports have a neighbour waiting to write to it, which to read from it. Nucleus: (GATE) before every message; the messages waiting, a ring of 400 cells, dealt with when the node is idle. Of two neighbours the lower number may wait to write (ruled after it was built); NEIGHBOUR tells a node who is on each port. test_host_mesh.c, 44 checks: the case that stopped the nodes passes; six messages from each node to each at once all arrive; 800 at once, the nodes come to rest and every message arrived or was counted (287 arrived, 714 of all kinds let go). test_fabric.c: the two looks. Both widths, ASan+UBSan. POST: twelve cases handed HERE, a cell address on v4, to words that take a byte address, and so wrote into or read from the nucleus's code at cell HERE/4. Ruled: left out, marked OPEN, until HERE and the byte words are made to agree as its own step. POST is 538 cases. hosted-check on three ISAs, 538/538. Bare metal: logs/20261006-134817 (amd64), -135044 (aarch64), -135440 (riscv64). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
630d03fa4e
commit
f9c034cadd
@@ -331,6 +331,29 @@ int main(void)
|
||||
"a port that is not there, a node that is not there, a port to itself: refused");
|
||||
CHECK(v4_fabric_wire(&f, a, 1, a, 2), "but one port of a node may be wired to another of the same node");
|
||||
|
||||
/* ---- a node looks at its neighbours before it writes (MESH.md 7a) ---- */
|
||||
v4_fabric_init(&f, places, 4);
|
||||
a = loaded(0); LIT(PB + 0); O(BANG_B); LIT(5); O(STORE_B); wait_for_ever(); /* writes to its port 0 */
|
||||
c = loaded(1); LIT(PB + 1); O(BANG_B); O(FETCH_B); LIT(OUT); O(BANG_A); O(STORE_A); wait_for_ever(); /* reads its port 1 */
|
||||
for (i = 0; i < 10; i++) (void)v4_fabric_step(&f);
|
||||
CHECK(ND(a)->n.asking && ND(c)->n.reading, "one node is waiting to write and another to read");
|
||||
b = loaded(2);
|
||||
LIT(PB + (v4_cell)V4_PORTS + 2); O(BANG_B); O(FETCH_B); LIT(OUT); O(BANG_A); O(STORE_A);
|
||||
LIT(PB + (v4_cell)V4_PORTS + 3); O(BANG_B); O(FETCH_B); LIT(OUT + 1); O(BANG_A); O(STORE_A);
|
||||
wait_for_ever();
|
||||
CHECK(v4_fabric_wire(&f, b, 2, a, 0) && v4_fabric_wire(&f, b, 4, c, 1), "a third is wired to both");
|
||||
{
|
||||
static stream none;
|
||||
static v4_device sink;
|
||||
sink.take = stream_take; sink.give = 0; sink.self = &none;
|
||||
CHECK(v4_fabric_wire_device(&f, b, 6, &sink), "and to a device that takes what is written to it");
|
||||
}
|
||||
for (i = 0; i < 20; i++) (void)v4_fabric_step(&f);
|
||||
CHECK(ND(b)->n.mem[OUT] == (1 << 2), "it sees which of its ports has a neighbour waiting to write to it: %ld", (long)ND(b)->n.mem[OUT]);
|
||||
CHECK(ND(b)->n.mem[OUT + 1] == ((1 << 4) | (1 << 6)), "and which have one waiting to read from it, or a device: %ld", (long)ND(b)->n.mem[OUT + 1]);
|
||||
CHECK(ND(a)->n.asking && ND(a)->n.request == 5 && ND(c)->n.reading && ND(c)->n.mem[OUT] == 0, "looking takes nothing and gives nothing: both wait as they did");
|
||||
CHECK(!ND(b)->n.stopped && ND(b)->n.reading, "and the one that looked did not wait to look");
|
||||
|
||||
printf(" %d checks, %d failures\n", checks, failures);
|
||||
return failures != 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user