diff --git a/docs/v4.0.0/MESH.md b/docs/v4.0.0/MESH.md index 6af86722..4b8a4535 100644 --- a/docs/v4.0.0/MESH.md +++ b/docs/v4.0.0/MESH.md @@ -240,6 +240,10 @@ and these tables. Nothing else changes. ## 7a. Two neighbours writing to each other (ruled 2026-10-06) +*(The lower-number rule and the looking again of this section are +replaced by the wait, section 7c, ruled 2026-10-07. The messages waiting, +and what flooding costs, stand.)* + The fault is in section 10, step 4. **Ruled: a node writes only to a neighbour that is already reading; a node keeps the messages it takes in meanwhile, and one there is no room for is lost and counted.** @@ -457,6 +461,120 @@ Two types, beside text (1), output (2) and done (3): and passes it on when its wait ends, not before. - A node that was never told who is on its centre's port believes no GONE. +## 7c. The wait (ruled 2026-10-07) + +**What it closes.** Section 7b.7's limit: a node with something for a +neighbour that was not reading could only write anyway, and be blocked, or +look again and again, never sleeping and never showing as reading. Either +way a stuck node held up its neighbours until it was killed. What was +missing was a third move: sleep until the neighbour I want is ready, or +until anyone wants me. + +**v3's way.** A send never blocks: kernel-Hermes queues it for the target +and refuses at once when there is no room (section 7b). v4 left that at +step 4, when nodes were ruled to talk through ports. Put to Captain Bob: +the wait below, or v3's way in full. **Ruled: the wait.** It is not an +F18 thing either; it is nearer the alternation of CSP. Captain Bob: "we +don't necessarily have to stick to the F18 rules... we're just borrowing +ideas." + +### 7c.1 The rulings + +1. **A node offers the first word of a message and sleeps**, until that + word is taken or a word comes for it, whichever is first. +2. **The fabric does the handing over in one step**, so nothing can change + between a node's looking and its writing. +3. **The lower-number rule of section 7a is dropped.** When two nodes each + offer to the other, the fabric picks. +4. **The console release of 7b.6 ("a blocked write") comes out of the + engine.** A console line reaches a node in the wait as any message + does. + +### 7c.2 The engine + +Two more addresses follow a node's ports (section 4.1, 7a): + +| Address | What | +|---|---| +| `base + V4_PORTS + 4` | Offer to: store the number of a port | +| `base + V4_PORTS + 5` | Offer: store the word offered. Fetch: the wait | + +- A store to either is remembered and waits for nothing. +- **A fetch of the wait blocks the node** until one of these, which the + fabric looks for once a step, in this order: + 1. *A word for it.* A neighbour is blocked writing to it, on any port, + or a device on one of its ports has a word to give. It gets that + word, as a read of "any port" would, and "which port" says where + from. Its offer is withdrawn. + 2. *Its offer taken.* The node on the port offered to is blocked reading + that port or any port; or is a device that takes what is written; or + is itself in the wait. The word is handed over. The fetch gives 0, + and "which port" gives `V4_PORTS`, which is no port: the offer was + taken. + 3. *Two nodes each offering to the other:* the one at the lower place in + the fabric has its offer taken, and the other gets the word (case 2 + for the one, case 1 for the other). +- A node in the wait that is handed a word by case 2 of another node gets + it by its own case 1. +- A node in the wait executes nothing and spends no heat. It shows to its + neighbours as waiting to read. +- With nothing on the port offered to, a node that can take an error has + error 18 raised on it (section 4.1); a bare node waits. A neighbour that + is asleep takes nothing: the offer stands. +- `v4_fabric_interrupt_error`, a device's `pending`, and + `v4_node_words_since_look` are removed. +- The lone node of the two products (`v4/system/boot.c`) has the same + wait: the kernel and the console take an offer at once; any other port + has nothing on it. + +### 7c.3 The nucleus + +- *Beginning a message* (`(GATE)`): offer its first word; if a word comes + instead, take that message in and offer again; when the offer is taken, + write the rest, each word waiting for the neighbour, which has taken the + first and reads to the end. +- *Paying what is owed* (`(PAY)`): each NACK is offered the same way. A + node with nothing to do that owes one sleeps in the wait; it no longer + goes round, and it no longer writes one without looking. +- *Text from its console for a node that is waiting to begin a message* + ends what the node was doing in error 21, "Interrupted", and is then + done, as in `AWAIT` (7b.6). This is how Hera is typed to while she waits + on a stuck node. +- `NEIGHBOUR` stays: a node must know who is on its centre's port to + believe a GONE (7b.4). It is no longer needed to write. + +### 7c.4 What is still a limit + +- A node's own line that must begin a message to a stuck node waits until + Hera kills that node or, on Hera, a line is typed. It takes in + everything sent to it meanwhile, and holds up no one. +- A node in `AWAIT` keeps what comes for other nodes, and what it owes, + until its wait ends (7b.7). +- A message once begun is written to its end. A node that takes a first + word and is then removed leaves its writer with error 18. + +### 7c.5 Acceptance + +1. *Offer taken.* A node offers to a neighbour that is reading: the word + passes and the rest follows. +2. *Offer withdrawn.* A node offering to a neighbour that never reads is + written to by another: it takes that message and offers again. +3. *Two offers.* Two nodes offer to each other in the same step: one + message passes each way, and neither is lost. +4. *A stuck neighbour holds up no one.* With a node stuck in a loop: a + neighbour that owes it a NACK, whether its number is higher or lower, + goes on doing what it is sent, and so does a third node that writes to + that neighbour. A node with a message for the stuck one takes in what + it is sent meanwhile. +5. *Hera.* Waiting to begin a message to a stuck node, she is typed to: + the line that waited ends "Interrupted", and the new line, which kills + the stuck node, is done. +6. *An empty port.* An offer to a port with nothing on it is error 18. +7. *Nothing deadlocks.* The flood of section 7a's test, 800 messages + among three nodes, comes to rest. +8. *Nothing else changes.* POST 538 of 538, the existing tests, and one + hash on all six systems; `sanitize`, `hosted-check`, lint, three boots. + ## 8. Storage **Ruled 2026-10-06 and 2026-10-07** (Captain Bob). On 2026-10-07 he found @@ -1069,6 +1187,8 @@ Each is tested, committed and pushed before the next. 8. *Nothing else changes.* POST 538 of 538, the existing tests, and the same hashes on all six systems. + **6d. The wait (section 7c).** Ruled 2026-10-07; not built. + 7. **A second unit; scaling while running; sleep, wake and kill by command.** 8. **The hosted product is the five nodes**, on three ISAs: acceptance 1