diff --git a/capsules/v4/nucleus-64.f18 b/capsules/v4/nucleus-64.f18 index b615b42e..6a9e18e8 100644 Binary files a/capsules/v4/nucleus-64.f18 and b/capsules/v4/nucleus-64.f18 differ diff --git a/docs/v4.0.0/MESH.md b/docs/v4.0.0/MESH.md index fddaae50..a63665c3 100644 --- a/docs/v4.0.0/MESH.md +++ b/docs/v4.0.0/MESH.md @@ -1256,6 +1256,37 @@ Each is tested, committed and pushed before the next. `hosted-check`, lint; three bare-metal boots, `logs/20261008-011558` (amd64), `-011833` (aarch64), `-012159` (riscv64). On all six: POST 538 of 538, `word_count=317`, `dict_hash=0x6a39c0bb9d183418`. + - **The review (2026-10-08) found the step not sound as built.** One + finding is mended, the rest are open and the claims of 7b and 7c that + "a stuck node holds up no other" are not yet true in the cases below. + - *Mended.* A line that left 29 values on the stack hung the node for + ever, on the products too: the passes over the messages waiting + that now follow every text need four cells, and a stack fault in + the middle of one left the messages in pieces. Such a text now + ends "Stack overflow", as it did before step 6d + (`test_host_quit.c`; `hosted-check`). The boots above were made + before this and do not show it. + - *Open: a node removed while a message is being passed on to it* + leaves the node passing it on going round for ever: the error + comes in the middle of writing the message out of the messages + waiting, and leaves them in pieces. + - *Open: offers left standing.* When a node lets a message go and + then begins text without having slept, what it had offered is + still offered, and the text's own message can go to the wrong + port. The review saw text meant for one node done by another. + - *Open: what a finished text printed* is still begun as a message + from text is, and if the way to the console is through a stuck + node the node is held and cannot be typed to. + - *Open: with more than eight messages of its own waiting* (answers, + or the GONEs of `KILL`) a node begins no text at all; on Hera that + cannot be undone from the console. + - *Open, smaller:* an error while a refusal is being written leaves + a value on the stack; with no room at all, how text ended is + begun as a message and can be held by a stuck sender; a line that + was itself refused for want of room can still end a waiting text + "Interrupted"; a message a node makes itself may be passed on by + 15 nodes, not 16; the flood's figures in 7a are stale (278 arrive + now) and `(LOST)` counts some messages more than once. 7. **A second unit; scaling while running; sleep, wake and kill by command.** diff --git a/v4/Makefile b/v4/Makefile index 55260251..3621a245 100644 --- a/v4/Makefile +++ b/v4/Makefile @@ -202,6 +202,8 @@ hosted-check: $(foreach i,$(HOSTED_ISAS),$(BINDIR)/boot-$(i).txt) $(BINDIR)/star @grep -q '^ok> No one on that port$$' $(BINDIR)/noone-amd64.txt && grep -q '^ok> 3 ok$$' $(BINDIR)/noone-amd64.txt || { echo "hosted-check: a write to a port with no one on it was not an error the node came back from"; cat $(BINDIR)/noone-amd64.txt | tail -4; exit 1; } @printf '5 AWAIT\n1 2 + .\n7 8 * .\n' | $(BINDIR)/starforth4-amd64 > $(BINDIR)/await-amd64.txt 2>&1; true @grep -q '^ok> Interrupted$$' $(BINDIR)/await-amd64.txt && grep -q '^ok> 3 ok$$' $(BINDIR)/await-amd64.txt && grep -q '^ok> 56 ok$$' $(BINDIR)/await-amd64.txt || { echo "hosted-check: a line typed while the node waited did not break the wait and then run"; tail -6 $(BINDIR)/await-amd64.txt; exit 1; } + @printf '1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29\n1 2 + .\n' | $(BINDIR)/starforth4-amd64 > $(BINDIR)/deep-amd64.txt 2>&1; true + @grep -q '^ok> Stack overflow$$' $(BINDIR)/deep-amd64.txt && grep -q '^ok> 3 ok$$' $(BINDIR)/deep-amd64.txt || { echo "hosted-check: a line that left 29 values on the stack was not an error the node came back from"; tail -4 $(BINDIR)/deep-amd64.txt; exit 1; } @$(BINDIR)/starforth4-postfail < /dev/null > $(BINDIR)/postfail.txt; test $$? -ne 0 || { echo "hosted-check: a boot with a failing case did not fail"; exit 1; } @grep -q '^POST FAIL: fail.wrong out<5 5 $$' $(BINDIR)/postfail.txt || { echo "hosted-check: the failing case was not named"; cat $(BINDIR)/postfail.txt; exit 1; } @grep -q '^POST FAIL: fail.many out= V4_DATA_DEPTH, "the prompt and the interpreter take no more than four cells of the stack"); + /* one more than may wait: the line ends in an error that says so, and the node goes on (found by the review of step 6d) */ + { + char line[4 * V4_DATA_DEPTH + 16]; + size_t at = 0; + unsigned m; + const char *r; + boot_bare(); + for (m = 0; m < most + 1; m++) at += (size_t)snprintf(line + at, sizeof line - at, "1 "); + snprintf(line + at, sizeof line - at, "\n"); + r = say(line); + CHECK(strstr(r, "Stack overflow") != NULL && strstr(r, " ERROR\nok> ") != NULL, "a line that leaves one value more than may wait ends in an error that says so: \"%s\"", r); + CHECK(strcmp(say("1 2 + .\n"), "3 ok\nok> ") == 0, "and the next line is done as usual"); + for (m = 0; m < 2000 && !node_idle(); m++) (void)v4_exec_step_word(&n, &es, &h); /* it finishes what it was doing when its answer went */ + CHECK(n.mem[MQ_COUNT] == 0 && node_idle(), "with nothing left among the messages waiting, and the node at its ports"); + } } /* ---- how much of the data stack a line has ---- */