fix(v4.0.0): step 6c mended after its review -- what a stuck or gone node can and cannot hold up
The review of step 6c found it did not keep its rule. Ruled: fix them all; 16 hops. - Paying a NACK no longer waits on a lower-numbered neighbour; a node that owes one does not sleep, and goes on taking in what it is sent. - AWAIT looks first through the messages already waiting. - A node waiting to write to a removed neighbour gets error 18: the word that says who is reading also says which ports have anything on them. - A console line lets Hera go when she is blocked on the first word of a message (v4_fabric_interrupt_error, a device's `pending`). - A refused answer is told to the node that waits, not the one that answered; one owed to the node itself goes to its own queue. - A message is passed on by at most 16 nodes, then refused. - A GONE is believed only when it says it is from the node's centre. - Tests: the check that tested nothing is replaced; no room for a waiting sender; the limit that remains is tested as a limit. - MESH.md 7b's rule reworded to what holds, 7b.7 says where it falls short; README likewise. make -C v4 test, sanitize, hosted-check; three bare-metal boots. POST 538 of 538, word_count=317, dict_hash=0xc0769523a47b7dc3 on all six. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
d343001dea
commit
59727f762a
+64
-16
@@ -197,14 +197,34 @@ header CMOVE
|
||||
\ the messages waiting are kept for those two types, so that ordinary
|
||||
\ messages cannot take all the room.
|
||||
|
||||
\ ( to about -- ) a refusal is owed to the node `to`, about the node `about`
|
||||
\ ( to about -- ) a refusal is owed to the node `to`, about the node `about`.
|
||||
\ Owed to this node itself -- its own message came back to it and was let
|
||||
\ go here -- it is put with the messages waiting, as if it had come by a
|
||||
\ port, in the room kept for refusals.
|
||||
: (OWE)
|
||||
over (ME) a! @ xor if SELF drop
|
||||
(OWED#) a! @ -8 + -if NOROOM
|
||||
drop (OWED#) a! @ 2* (OWED) + a!
|
||||
push !+ pop !
|
||||
(OWED#) a! @ 1 + ! ;
|
||||
SELF: drop 1 (MQ#) a! @ + -MQ-ROOM + -if NOROOM
|
||||
drop push (MQ!) (ME) a! @ (MQ!) 4 (MQ!) 0 (MQ!) 0 (MQ!) 0 (MQ!) 4 (MQ!) 0 (MQ!) pop (MQ!) ;
|
||||
NOROOM: drop drop drop (LOST) a! @ 1 + ! ;
|
||||
|
||||
\ ( from to type -- ) a message of that type, from the one node for the
|
||||
\ other, has been let go here. Whoever is waiting on it is told: its
|
||||
\ sender; or, for a node's answer (type 3), the node the answer was for,
|
||||
\ which is the one that waits. Nothing is owed for a NACK or a GONE.
|
||||
: (TELL-OF)
|
||||
dup -4 + if NOT -1 + if NOT drop
|
||||
-3 + if ANSWER drop jump (OWE) \ to its sender, about whom it was for
|
||||
ANSWER: drop SWAP jump (OWE) \ to whom it was for, about the node that answered
|
||||
NOT: drop drop drop drop ;
|
||||
|
||||
\ ( port -- flag ) is there anything on that port, by its address?
|
||||
: (THERE)
|
||||
(PORT) - -PORTS - (READERS) b! @b SWAP jump (BIT)
|
||||
|
||||
\ ( port to -- ) the seven words of a message being taken in, and the
|
||||
\ port, go into (MQ-HDR). B is at the port, by its address, and `to` is
|
||||
\ the message's first word, already read from it.
|
||||
@@ -223,7 +243,7 @@ header CMOVE
|
||||
LONG: drop 3 + 2/ 2/ -1 + FOR @b drop UNEXT -1 (MQ-HDR)+6 a! ! 0
|
||||
COUNTED: \ ( n ) how many words of text follow
|
||||
dup (MQ#) a! @ + \ what it would come to
|
||||
(MQ-HDR)+2 a! @ -4 + -if KEPT-FOR \ a NACK or a GONE may use the room kept for them
|
||||
(MQ-HDR)+2 a! @ -4 + if KEPT-FOR -1 + if KEPT-FOR \ a NACK or a GONE may use the room kept for them
|
||||
drop -MQ-ORDINARY + jump ROOM
|
||||
KEPT-FOR: drop -MQ-ROOM +
|
||||
ROOM: -if FULL
|
||||
@@ -235,9 +255,7 @@ header CMOVE
|
||||
FULL: drop if READ -1 + FOR @b drop UNEXT jump LOSE
|
||||
READ: drop
|
||||
LOSE: (LOST) a! @ 1 + !
|
||||
(MQ-HDR)+2 a! @ -4 + -if NOT-OWED \ nothing is owed for a NACK or a GONE
|
||||
drop (MQ-HDR)+1 a! @ (MQ-HDR) a! @ jump (OWE) \ to whoever sent it, about whom it was for
|
||||
NOT-OWED: drop ;
|
||||
(MQ-HDR)+1 a! @ (MQ-HDR) a! @ (MQ-HDR)+2 a! @ jump (TELL-OF)
|
||||
|
||||
\ ( port to -- ) take in a message and keep it
|
||||
: (TAKE) (TAKE-HDR) jump (TAKE-KEEP)
|
||||
@@ -257,7 +275,10 @@ header CMOVE
|
||||
ASK: drop
|
||||
(READERS) b! @b (GATE-PORT) a! @ (PORT) - (BIT) if NOTYET
|
||||
drop (GATE-PORT) a! @ b! ; \ it is waiting to read
|
||||
NOTYET: drop jump L
|
||||
NOTYET: drop
|
||||
(READERS) b! @b (GATE-PORT) a! @ (PORT) - -PORTS - (BIT) if NOONE \ is there anything on the port at all?
|
||||
drop jump L
|
||||
NOONE: drop NODE-ERROR b! 18 !b ; \ no: what waits here would wait for ever
|
||||
|
||||
\ ( type -- ) words 1 to 5 of a message this node sends: from, type, and
|
||||
\ the three that are carried and not used yet. Its caller has put B at the
|
||||
@@ -266,18 +287,45 @@ header CMOVE
|
||||
: (HDR)
|
||||
(ME) a! @ !b \ from
|
||||
!b \ type
|
||||
0 !b 0 !b 0 !b ; \ heat and TTL, ACL tag, sequence
|
||||
16 !b 0 !b 0 !b ; \ how many nodes may pass it on (the TTL: MESH.md 7b); ACL tag; sequence
|
||||
|
||||
\ ( -- ) send one refusal this node owes, if it owes any: the one noted
|
||||
\ last. With no way to whom it is owed, it is let go and counted.
|
||||
\ PAYING WHAT IS OWED does not hold this node up. A refusal is sent if the
|
||||
\ neighbour it goes by is reading at this moment. If it is not, and its
|
||||
\ number is the higher, the refusal is written all the same, as any message
|
||||
\ would be (MESH.md 7a): that neighbour takes it in when it next looks. If
|
||||
\ its number is the lower, or it has not been told of, the refusal stays
|
||||
\ owed, and this node goes on with what it has to do and tries again; it
|
||||
\ does not sleep while it owes one (quit.v4, (IDLE)). One there is no way
|
||||
\ for, or whose way is a port with nothing on it, is let go and counted.
|
||||
|
||||
\ ( k -- ) the k-th refusal owed is done with: the last takes its place
|
||||
: (PAID)
|
||||
(OWED#) a! @ -1 + dup !
|
||||
2* (OWED) + a! @+ @
|
||||
push push 2* (OWED) + a! pop !+ pop ! ;
|
||||
|
||||
\ ( k -- ) send the k-th refusal owed, if it can go now
|
||||
: (PAY1)
|
||||
dup 2* (OWED) + a! @+ @ \ k to about
|
||||
over (PORT-FOR) if NOWAY \ k to about port
|
||||
dup (THERE) if GONE
|
||||
drop (READERS) b! @b over (PORT) - (BIT) if BUSY
|
||||
drop
|
||||
WRITE: b! \ k to about B: the port
|
||||
SWAP !b 4 (HDR) 4 !b !b \ k to; from, type 4; four characters; about
|
||||
jump (PAID)
|
||||
BUSY: drop \ it is not reading:
|
||||
dup (PORT) - (NEAR) + a! @ if LEAVE \ k to about port near
|
||||
(ME) a! @ - -if BLIND jump LEAVE \ its number less this node's
|
||||
BLIND: drop jump WRITE \ the higher: it will take it in
|
||||
LEAVE: drop drop drop drop drop ;
|
||||
GONE: drop
|
||||
NOWAY: drop drop drop (LOST) a! @ 1 + ! jump (PAID)
|
||||
|
||||
\ ( -- ) send every refusal this node owes that can go now
|
||||
: (PAY)
|
||||
(OWED#) a! @ if NONE
|
||||
-1 + dup !
|
||||
2* (OWED) + a! @+ @ \ to about
|
||||
over (PORT-FOR) if NOWAY
|
||||
(GATE) over !b \ to
|
||||
4 (HDR) 4 !b !b drop ; \ from, type 4; four characters; about
|
||||
NOWAY: drop drop drop (LOST) a! @ 1 + ! ;
|
||||
(OWED#) a! @ if NONE -1 +
|
||||
FOR pop dup push (PAY1) NEXT ;
|
||||
NONE: drop ;
|
||||
|
||||
\ ( -- ) send what has been printed, to where (PRINT-TO) says, by the port
|
||||
|
||||
Reference in New Issue
Block a user