fix(v4.0.0): a node blocked at a port with no one on it is given an error, not left there
A node writing to a node that was stuck, and was then killed, stayed blocked for ever: killing a stuck node could cost its neighbours. And on the hosted and bare-metal products a write to an empty port, 5 7 PORT!, ended the program with "the node stopped". Now a node that can take an error, blocked writing to or reading from one port that nothing is wired to -- nothing ever was, or what was there has been killed or the wire cut -- has error 18, No one on that port, raised on it and goes on. A bare node waits as on the fabric; so does a node whose neighbour is asleep, and one reading "any port". test_host_unit.c: Hera kills node 14 while node 12 is blocked writing to it. It failed first: 12 stayed blocked. test_fabric.c: a bare node still waits. hosted-check types 5 7 PORT! and goes on; it failed first too. make -C v4 test, sanitize and hosted-check pass; amd64, aarch64 and riscv64 boot, POST 538 of 538, dict_hash 0x5f0a949a6fc8ef2b on all six: logs/20261007-121743, -122008, -122337. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
18adf59091
commit
bc6deab3f5
@@ -380,6 +380,7 @@ int main(void)
|
||||
|
||||
/* ---- Hera is born empty, and takes in the nucleus ---- */
|
||||
v4_fabric_init(&f, places, PLACES);
|
||||
v4_fabric_gone_error(&f, V4_ERROR_NO_ONE);
|
||||
place = host_born(0);
|
||||
CHECK(place == 0, "a node is born");
|
||||
hera_place = (unsigned)place;
|
||||
@@ -498,6 +499,22 @@ int main(void)
|
||||
CHECK(strcmp(tell(10, "(LOST) @ ."), "0 ") == 0 && strcmp(tell(12, "(LOST) @ ."), "0 ") == 0, "and no message was let go");
|
||||
CHECK(waiting(10) && waiting(11) && waiting(12) && waiting(13) && waiting(14), "all five are waiting at their ports again");
|
||||
|
||||
/* ---- a node is killed while its neighbour is writing to it ---- */
|
||||
step_limit = 3000000ul;
|
||||
CHECK(strcmp(tell(14, ": SPIN BEGIN 0 UNTIL ; SPIN"), "(still running)") == 0, "node 14 is stuck in a loop that never ends");
|
||||
CHECK(strcmp(tell(12, ": TO14 S\" 65 EMIT\" 14 SEND ; TO14"), "(still running)") == 0 && node_numbered(12)->asking,
|
||||
"node 12, beside it, sends it text: 14 never reads, and 12 is blocked writing to it");
|
||||
{
|
||||
unsigned born = born_count;
|
||||
const char *r = tell(10, "(P4) @ NODE-KILL 65 EMIT");
|
||||
CHECK(strstr(printed, "A") != NULL && node_numbered(14) == NULL && born_count == born, "Hera kills node 14: \"%s\"", r);
|
||||
}
|
||||
CHECK(!node_numbered(12)->asking && !node_numbered(12)->stopped && waiting(12), "node 12 is no longer blocked: it is waiting at its ports");
|
||||
CHECK(strstr(printed, "No one on that port") != NULL, "what it was doing ended in an error, which said so: \"%s\"", printed);
|
||||
step_limit = 30000000ul;
|
||||
CHECK(strcmp(tell(12, "12 100 * ."), "1200 ") == 0 && strcmp(tell(13, "13 100 * ."), "1300 ") == 0 && strcmp(tell(10, "1 2 + ."), "3 ") == 0, "and everything else keeps running: \"%s\"", printed);
|
||||
CHECK(strstr(tell(12, ": AGAIN14 S\" 65 EMIT\" 14 SEND ; AGAIN14"), "No one on that port") != NULL && waiting(12), "a later write to where node 14 was is an error at once, not a wait: \"%s\"", printed);
|
||||
|
||||
printf(" %d checks, %d failures\n", checks, failures);
|
||||
return failures != 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user