docs(v4.0.0): the root causes behind the wait's faults, and the boots of the code that mends them
MESH.md 7c.7: the stacks doubled in scratch and each path measured -- the
size was never the cause; EMIT's overrun of the output buffer, and a
message's first word moving before there was room for the rest; what is
left for a second design; the depth sweep.
Three bare-metal boots of 0d91608f typing the deep-stack lines: POST 538
of 538, word_count=317, dict_hash=0x3629660aa2dc6823 on all six. Three
earlier amd64 boots of the same code, whose typed session was wrong, are
kept.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
0d91608f39
commit
8967c93241
@@ -646,6 +646,62 @@ every node present.
|
||||
Two guards from this are kept in `hosted-check`: a line that leaves 29
|
||||
values on the stack, and `WORDS` with 26 values on it.
|
||||
|
||||
### 7c.7 The root causes, found and mended in the code as it stands (2026-10-08)
|
||||
|
||||
Captain Bob asked for the root cause before deciding whether to make the
|
||||
stacks bigger. Both stacks were doubled in scratch copies of the code,
|
||||
of this code and of the wait's, and each path measured: the prompt and
|
||||
the interpreter need four cells of the data stack, printing six (the
|
||||
wait's code seven), and nine entries of the return stack, whatever the
|
||||
size. **The size was never the cause.** Doubling moved the faults from
|
||||
26 to 28 values to 58 to 60 and removed none. Two defects were, and both
|
||||
were in this code too:
|
||||
|
||||
1. **`EMIT` ran past the output buffer.** It stored its character and
|
||||
only then looked whether the buffer was *exactly* full. A flush that
|
||||
ended in a fault -- the stack too deep to begin a message -- left the
|
||||
buffer full; the fault's own message was then put past its end, and
|
||||
`(OUT^)` was never again at the end to be flushed. Here the 28 cells
|
||||
after the buffer happen to be unused and the longest error message is
|
||||
shorter, so nothing showed. The wait had moved the ports into those
|
||||
cells: the characters were stored into port addresses and the node
|
||||
blocked writing to a port. **That was the hang.** Mended: `EMIT` sends
|
||||
a buffer it finds full before it stores.
|
||||
2. **A message's first word moved before there was known to be room for
|
||||
the rest.** Once a first word is read or written both ends are
|
||||
committed. `AWAIT`, and `(GATE)` when a neighbour is writing, read one
|
||||
and then used stack that had not been tried: with 27 or 28 values on
|
||||
the stack, or 28 or 29 calls deep, a line typed during `AWAIT` was
|
||||
taken and never answered. Writing was safe only by the order things
|
||||
happened to be done in; the wait's code needed one cell more after the
|
||||
first word than before it. Mended: `(ROOM)` tries six cells and four
|
||||
return entries before a first word is read from within text, and
|
||||
`(GATE)` tries the three its writing needs before a first word goes.
|
||||
If they are not there the text ends "Stack overflow" with nothing on
|
||||
a wire.
|
||||
|
||||
**Not mended, and left for a second design of the wait:** a message has
|
||||
no way to be given up part way. On a mesh, if a fault does come after a
|
||||
first word, the reader waits for a rest that never comes and takes the
|
||||
next message's words for it.
|
||||
|
||||
**The test that was missing.** `v4/tools/depthsweep.py` runs every
|
||||
message path of the hosted product -- printing, `WORDS`, a line typed
|
||||
during `AWAIT`, `SEND`, a write to an empty port, an unknown word -- with
|
||||
the data stack at every depth from ten below its end to two past it, and
|
||||
from that many calls deep. Each line typed must be answered and the node
|
||||
must come back. `hosted-check` runs it: 164 runs. `test_host_quit.c`
|
||||
checks that nothing is ever put past the end of the output buffer.
|
||||
|
||||
**Verified.** `make -C v4 test` and `sanitize` at both widths,
|
||||
`hosted-check`, lint; three bare-metal boots, `logs/20261008-121610`
|
||||
(amd64), `-121857` (aarch64), `-122251` (riscv64), each typing 29 values
|
||||
on a line, `WORDS` with 26 on the stack, and `AWAIT` with 27 followed by
|
||||
a line. POST 538 of 538, `word_count=317`,
|
||||
`dict_hash=0x3629660aa2dc6823` on all six. (`logs/20261008-120121`,
|
||||
`-120624` and `-121117` are amd64 boots of the same code in which the
|
||||
typed session did not put the wait on a deep stack; they are kept.)
|
||||
|
||||
## 8. Storage
|
||||
|
||||
**Ruled 2026-10-06 and 2026-10-07** (Captain Bob). On 2026-10-07 he found
|
||||
|
||||
Reference in New Issue
Block a user