feat(v4.0.0): the wait replaces looking and the console release; step 6d written up
The engine's console release (v4_fabric_interrupt_error), a device's pending, and the count of words since a look are removed: nothing uses them. MESH.md 4.1, 7b and 7c say what was built, where it differs from what was approved and why, and what is still a limit; step 6d is marked built, with the defects found on the way. make -C v4 test and sanitize at both widths, hosted-check, lint; three bare-metal boots. POST 538 of 538, word_count=317, dict_hash=0x6a39c0bb9d183418 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
ec817a8264
commit
2b587206ee
+113
-53
@@ -104,6 +104,9 @@ word address `base`:
|
||||
| `base` … `base + V4_PORTS − 1` | Port 0 … port `V4_PORTS − 1` |
|
||||
| `base + V4_PORTS` | Any port: a read here takes from whichever port has a neighbour writing |
|
||||
| `base + V4_PORTS + 1` | Which port the last read from "any" came from. Read only. |
|
||||
| `base + V4_PORTS + 2`, `+ 3` | Who is waiting to write to this node, and who to read from it: section 7a |
|
||||
| `base + V4_PORTS + 4 + k` | The offer on port *k*: section 7c |
|
||||
| `base + 2 * V4_PORTS + 4` | The wait: section 7c |
|
||||
|
||||
- **A write to a port blocks the node until the neighbour has read it.**
|
||||
Built 2026-10-05 for one port; the opcode after the write runs when the
|
||||
@@ -304,7 +307,8 @@ kernel-Hermes's work in v3 and is not decided for the mesh.
|
||||
gone; and a wait on a node that is alive and stuck is ended by Hera's
|
||||
killing that node, or from the console. A message that is refused is
|
||||
told to whoever waits on it, while the node that refuses it has room to
|
||||
remember that it owes the telling.** As first written the rule was "no
|
||||
remember that it owes the telling.** (Since step 6d, section 7c, a node
|
||||
that is stuck also holds up no other node.) As first written the rule was "no
|
||||
message is lost without its sender being told, and no node waits for
|
||||
ever"; the review showed that was more than what was built could keep,
|
||||
and section 7b.7 says exactly where it falls short. It closes two defects
|
||||
@@ -371,12 +375,12 @@ Two types, beside text (1), output (2) and done (3):
|
||||
- A NACK owed to this node itself -- its own message came back to it and
|
||||
was let go here -- is put with its messages waiting, as if it had come
|
||||
by a port.
|
||||
- Paying one: if the neighbour it goes by is reading, it is sent. If not,
|
||||
and that neighbour's number is the higher, it is written all the same,
|
||||
as any message to it is (section 7a). If its number is the lower, the
|
||||
NACK stays owed; the node goes on taking in what is written to it and
|
||||
tries again, and does not sleep while it owes one. One there is no way
|
||||
for, or whose way is a port with nothing on it, is dropped and counted.
|
||||
- Paying one: it is offered on the port it goes by, with everything else
|
||||
the node has to send, and the node sleeps in the wait (section 7c). One
|
||||
there is no way for, or whose way is a port with nothing on it, is
|
||||
dropped and counted. (As first mended it was written without looking to
|
||||
a higher-numbered neighbour and kept back from a lower; step 6d
|
||||
replaced that.)
|
||||
- A message is passed on by at most 16 nodes. Its fourth word, the TTL,
|
||||
carries how many more may pass it on; the node that would be the
|
||||
sixteenth refuses it as it would one it had no way for. (Ruled
|
||||
@@ -422,14 +426,11 @@ Two types, beside text (1), output (2) and done (3):
|
||||
as usual.
|
||||
- On the two products there is one node, and nobody but the console could
|
||||
ever answer it: a line typed while it waits does the same.
|
||||
- **A blocked write (ruled 2026-10-07).** Hera has the lowest number, so
|
||||
she writes to a neighbour without looking and is blocked until it reads
|
||||
(section 7a); if it never does, nothing could be typed to her again. So
|
||||
when a node is blocked writing the first word of a message to another
|
||||
node, and its console has a line for it, the fabric raises error 21 on
|
||||
it: it gives that message up and goes on to read the line. Only on the
|
||||
first word, so that half a message is never left on a wire
|
||||
(`v4_fabric_interrupt_error`, `v4/include/v4/fabric.h`).
|
||||
- **A blocked write (ruled 2026-10-07; replaced by section 7c the same
|
||||
day).** As first mended the fabric raised error 21 on a node blocked on
|
||||
the first word of a message while its console had a line for it. Since
|
||||
step 6d no node is blocked on a first word: it offers it and sleeps,
|
||||
and a console line reaches it as any message does (7c.3).
|
||||
- **A node waiting to write to a neighbour that has been removed** is told:
|
||||
the word that says which neighbours are reading also says which ports
|
||||
have anything on them at all, and with nothing there the wait ends in
|
||||
@@ -443,22 +444,11 @@ Two types, beside text (1), output (2) and done (3):
|
||||
console. v3's pool is finite too, 32 messages, and a send beyond it is
|
||||
refused.
|
||||
- A node whose neighbour is asleep waits until it is woken (section 4.1).
|
||||
- **A node that is stuck can hold up its neighbours until it is killed.**
|
||||
A node cannot tell a neighbour that is busy for a moment from one that
|
||||
is stuck for good, and there is no clock (ruling 2). So:
|
||||
- a node that owes a NACK to a stuck neighbour whose number is the
|
||||
higher is blocked writing it;
|
||||
- a node that owes one to a stuck neighbour whose number is the lower
|
||||
goes on taking in what lower-numbered neighbours write to it, but does
|
||||
not sleep, and a higher-numbered neighbour with something for it
|
||||
waits;
|
||||
- a node with a message for a stuck neighbour waits to write it.
|
||||
|
||||
Each ends when Hera kills the stuck node: the wire is then empty, the
|
||||
waiting node is told so (error 18) and goes on. Hera herself can always
|
||||
be typed to (7b.6). None of this can happen on a node that is gone.
|
||||
- A node that is waiting for an answer keeps what comes for other nodes
|
||||
and passes it on when its wait ends, not before.
|
||||
- ~~A node that is stuck can hold up its neighbours until it is killed.~~
|
||||
**Closed by step 6d (section 7c).** As step 6c left it, a node that
|
||||
owed a stuck neighbour a NACK, or had a message for it, was blocked or
|
||||
went round until Hera killed the stuck node; and a node waiting for an
|
||||
answer kept back what was passing through it.
|
||||
- A node that was never told who is on its centre's port believes no GONE.
|
||||
|
||||
## 7c. The wait (ruled 2026-10-07)
|
||||
@@ -525,9 +515,15 @@ a node may offer a word on each of its ports at once.)*
|
||||
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 a port it has an offer on, 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.
|
||||
- With nothing on a port it has an offer on -- because nothing ever was,
|
||||
or because what was there has been removed -- a node that can take an
|
||||
error is woken: the fetch gives 0 and "which port" gives
|
||||
`2 * V4_PORTS + k`. No error is raised: the node may be in the middle of
|
||||
something that has nothing to do with that port. A bare node waits. A
|
||||
neighbour that is asleep takes nothing: the offer stands. *(Changed
|
||||
while it was built: as approved, error 18 was raised. That ended the
|
||||
text of a node that merely had a message queued for a neighbour that
|
||||
was then killed.)*
|
||||
- `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
|
||||
@@ -536,30 +532,59 @@ a node may offer a word on each of its ports at once.)*
|
||||
|
||||
### 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)`): every NACK owed is offered at once,
|
||||
each on the port it goes by (one to a port). 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.
|
||||
*(Rewritten 2026-10-08 as built. The first form had the node passing a
|
||||
message on by beginning it at once, as its own text does. That held the
|
||||
node passing on whenever the node it was for was stuck: text typed for a
|
||||
stuck node left Hera deaf. So what is passed on waits, offered.)*
|
||||
|
||||
- *Beginning a message from text* (`(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. With nothing on the
|
||||
port it is error 18.
|
||||
- *Text from its console for a node whose text is waiting there* ends that
|
||||
text in error 21, "Interrupted", and is then done. This is how Hera is
|
||||
typed to while her line waits on a stuck node.
|
||||
- *A node with nothing to do* (`(IDLE)`) deals first with what is for
|
||||
itself, the oldest first. With nothing for itself it offers, all at
|
||||
once, the first message it has for each port and each NACK it owes, and
|
||||
sleeps in the wait. What is taken is written and done with; the rest
|
||||
stays with the messages waiting, in the order it came. A message for a
|
||||
stuck node waits there and holds up nothing.
|
||||
- *What a node sends other than from text* goes the same way: how text
|
||||
ended (type 3), and a GONE. Each is put with the messages waiting and
|
||||
goes when it can. So a node that did text for a sender that then stuck
|
||||
is not held by it, and `KILL` is not held by one stuck node from telling
|
||||
the next.
|
||||
- *Order.* How text ended is put before the other messages waiting, and a
|
||||
node does not begin another text from a sender while its answer to that
|
||||
sender is still with it: what one sender is told comes in the order its
|
||||
texts were done.
|
||||
- *A node waiting for an answer* (`AWAIT`) does all of this but begin
|
||||
text: it looks through the messages waiting for what would end its
|
||||
wait, offers what is to be passed on and what it owes, and sleeps in
|
||||
the wait. It no longer keeps back what passes through it.
|
||||
- `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 node's own text that must begin a message (`SEND`, or what it prints)
|
||||
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, but passes nothing
|
||||
on until its text ends.
|
||||
- A line typed at Hera while her text is waiting to begin a message ends
|
||||
that text, whether the node it waits on is stuck or only busy.
|
||||
- What a finished text printed is still begun as a message from text is,
|
||||
toward the console's node: if that node is stuck, nothing could be seen
|
||||
in any case.
|
||||
- An answer that reaches a waiting node whose messages waiting are full
|
||||
is refused, and the wait ends "Message refused".
|
||||
- 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.
|
||||
- The messages waiting are finite, 400 cells: a node that is passing on
|
||||
for a stuck node keeps what is for it until that node is killed, and
|
||||
with no room left refuses what comes, telling the sender.
|
||||
|
||||
### 7c.5 Acceptance
|
||||
|
||||
@@ -577,7 +602,8 @@ a node may offer a word on each of its ports at once.)*
|
||||
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.
|
||||
6. *An empty port.* Text that begins a message on a port with nothing on
|
||||
it ends in 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
|
||||
@@ -1195,7 +1221,41 @@ 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.
|
||||
**6d. The wait (section 7c).** Ruled 2026-10-07. **Built 2026-10-08.**
|
||||
- *The engine* (`v4/src/node.c`, `fabric.c`): the offer addresses and
|
||||
the wait; the fabric hands an offer over in one step; a node told
|
||||
there is nothing on a port it offered on. Removed: the console
|
||||
release of 7b.6, a device's `pending`, the count of words since a
|
||||
look.
|
||||
- *The nucleus* (`v4/capsule/core.v4`, `quit.v4`): `(OFFERS)`, `(GATE)`;
|
||||
`(IDLE)` as in 7c.3, with `(MINE?)`, `(FWD-SET)`, `(FWD-GO)`,
|
||||
`(PAY-SET)`, `(PAY-GO)`; `(FINISH)` and `GONE` put what they send with
|
||||
the messages waiting; `AWAIT` goes on passing on and paying. The
|
||||
lower-number rule, the looking again, `(PASS-ON)` and `(PAY)` are
|
||||
gone. The ports moved in the nucleus's map to make room.
|
||||
- *The lone node* (`v4/system/boot.c`): an offer is served as a write.
|
||||
- *Found while it was built, and mended, each with a check that failed
|
||||
first:* a message passed on toward a stuck node held the node passing
|
||||
it on (7c.3); a node waited on a stuck sender to give it its answer;
|
||||
with answers queued, a line typed during a wait was done before the
|
||||
earlier line's answer had gone; a node with two answers it could not
|
||||
give began no text; `KILL` waited to tell a stuck node, and a typed
|
||||
line then left the rest untold; removing a node raised "No one on
|
||||
that port" on the unrelated text of a neighbour with something
|
||||
queued for it (7c.2). Two commits on the way were wrong as pushed:
|
||||
`482cc75f` (the first of these) and `1c720ab2` (pushed with
|
||||
`hosted-check` failing); `35378372` and `ec817a82` mend them.
|
||||
- *Tests.* `test_fabric.c` 104 checks: acceptance 1, 2, 3, 6, and the
|
||||
ring, the same-step and the asleep cases. `test_host_mesh.c` 127:
|
||||
acceptance 4 for a creditor of either number, two refusals owed,
|
||||
order kept through a node passing on, a waiting node passing on, a
|
||||
line that waits and is typed to, and 7. `test_host_unit.c` 84:
|
||||
acceptance 5; a node with answers for two stuck senders; `KILL` with
|
||||
another node stuck.
|
||||
- *Verified.* `make -C v4 test` and `sanitize` at both widths,
|
||||
`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`.
|
||||
|
||||
7. **A second unit; scaling while running; sleep, wake and kill by
|
||||
command.**
|
||||
|
||||
@@ -0,0 +1,165 @@
|
||||
[2J[001;001H[=3h[2J[001;001H[2J[001;001H[8;042;160t[2J[001;001H[2J[001;001H[8;056;240t[2J[001;001HBdsDxe: loading Boot0002 "UEFI QEMU DVD-ROM QM00005 " from PciRoot(0x0)/Pci(0x1F,0x2)/Sata(0x2,0xFFFF,0x0)
|
||||
BdsDxe: starting Boot0002 "UEFI QEMU DVD-ROM QM00005 " from PciRoot(0x0)/Pci(0x1F,0x2)/Sata(0x2,0xFFFF,0x0)
|
||||
[2J[001;001H[=3h[2J[001;001HStarKernel UEFI Loader
|
||||
Loading kernel from ESP...
|
||||
[CKPT 001] Entered efi_main - ConOut live
|
||||
RAW SERIAL UP
|
||||
[CKPT 002] Serial (COM1) initialized
|
||||
Monolithic build - kernel linked directly
|
||||
Collecting boot information...
|
||||
CmdLine: parsed OK
|
||||
[CKPT 004] Command line parsed
|
||||
[CKPT 005] Kernel stack allocation decided
|
||||
[CKPT 006] Boot info collected (ACPI table located)
|
||||
GOP: linear framebuffer found
|
||||
[CKPT 007] GOP: linear framebuffer found
|
||||
[CKPT 008] About to enter ExitBootServices retry loop
|
||||
EBS...
|
||||
EBS OK
|
||||
Calling kernel_main (monolithic)...
|
||||
|
||||
|
||||
_____ _ _ __ _
|
||||
/ ____| | | |/ / | |
|
||||
| (___ | |_ __ _ _ __| ' / ___ _ __ _ __ ___| |
|
||||
\___ \| __/ _` | '__| < / _ \ '__| '_ \ / _ \ |
|
||||
____) | || (_| | | | . \ __/ | | | | | __/ |
|
||||
|_____/ \__\__,_|_| |_|\_\___|_| |_| |_|\___|_|
|
||||
|
||||
LithosAnanke v2.1.0
|
||||
Architecture: amd64
|
||||
Build: Oct 8 2026 01:15:32
|
||||
|
||||
UEFI BootServices: EXITED
|
||||
|
||||
=== StarKernel Boot Information ===
|
||||
Memory map entries: 132
|
||||
Total memory: 1023 MB
|
||||
Usable memory: 966 MB
|
||||
===================================
|
||||
|
||||
PMM initialized.
|
||||
PMM statistics:
|
||||
Total pages: 248741
|
||||
Free pages : 247218
|
||||
Used pages : 1523
|
||||
Total MB : 971
|
||||
Free MB : 965
|
||||
Used MB : 5
|
||||
|
||||
VMM initialized (mapped RAM, CR3 switched)
|
||||
VMM initialized (mapped RAM, CR3 switched)
|
||||
VMM self-test: mapped OK at 0xffff800000000000
|
||||
VMM self-test complete.
|
||||
|
||||
IDT installed.
|
||||
|
||||
APIC: init...
|
||||
APIC: IA32_APIC_BASE MSR=0x00000000fee00900
|
||||
APIC: stale-ISR drain: 0 EOI(s) issued
|
||||
APIC: initialized (xAPIC MMIO, TPR=0, SIVR=0x1FF, EOI-clear)
|
||||
APIC: init done
|
||||
|
||||
I/O APIC: init...
|
||||
I/O APIC: base=0xfec00000, gsi_base=0, overrides=5
|
||||
override: source=00 gsi=2 flags=0x0000
|
||||
override: source=05 gsi=5 flags=0x000d
|
||||
override: source=09 gsi=9 flags=0x000d
|
||||
override: source=0a gsi=10 flags=0x000d
|
||||
override: source=0b gsi=11 flags=0x000d
|
||||
i8042: keyboard ACKed enable-scanning
|
||||
i8042: IRQ1 enabled in controller config byte
|
||||
I/O APIC: keyboard IRQ1 routed (masked)
|
||||
|
||||
Timer: init...
|
||||
Timer: init start
|
||||
Timer: PM_TMR_BLK discovered from FADT at port 1544
|
||||
Timer: VM mode detected (hypervisor present).
|
||||
Timer: HPET calibration disabled (VM-exit MMIO would poison timing).
|
||||
Timer: WARNING: invariant TSC not present under hypervisor.
|
||||
Timer: continuing in RELATIVE mode (no determinism guarantees).
|
||||
Timer: RDTSCP not present; using RDTSC (less serialized).
|
||||
Timer: CPUID frequency unavailable; trying PM Timer...
|
||||
Timer: trust=1 (0=NONE,1=REL,2=ABS), TSC=2095226674 Hz
|
||||
Timer: init done
|
||||
|
||||
Kernel heap initialized.
|
||||
Heap statistics:
|
||||
Total bytes: 536870872
|
||||
Free bytes: 536870872
|
||||
Used bytes: 0
|
||||
Peak bytes: 0
|
||||
Heap base addr: 24641536
|
||||
Heap end addr: 561512448
|
||||
|
||||
Heartbeat: init...
|
||||
APIC Timer: calibrating...
|
||||
APIC Timer: apic_hz=1004544835, tick_hz=100, initial_count=10045448
|
||||
APIC Timer: configured (masked, ready to start)
|
||||
Heartbeat: init done
|
||||
Kernel initialization complete.
|
||||
Boot successful!
|
||||
|
||||
StarForth v4: one host node, the F18-derived engine
|
||||
V4: capsule v4:nucleus-64.f18 signature: missing (unsigned)
|
||||
PARITY:V4_NUCLEUS name=v4:nucleus-64.f18 capsule_id=0xe4f71542c2097e28 capsule_hash=0xe4f71542c2097e28 words=311
|
||||
V4: capsule v4:forth79.4th signature: missing (unsigned)
|
||||
PARITY:V4_CAPSULE name=v4:forth79.4th capsule_id=0x4055641ee17d176b capsule_hash=0x4055641ee17d176b dict_hash=0xe1367a919849c14b
|
||||
PARITY:V4_POST tests=538 pass=538 fail=0
|
||||
PARITY:V4_SYSTEM word_count=317 dict_hash=0x6a39c0bb9d183418
|
||||
PARITY:OK
|
||||
POST: PASSED
|
||||
[32m[HADES][INFO ] [0m[KRELTSC: 0] blk: raw device LBN 2048..3071 (1024 blocks)
|
||||
PCI: init...
|
||||
PCI: ECAM mapped (amd64)
|
||||
virtio-blk: found device
|
||||
[32m[HADES][INFO ] [0m[KRELTSC: 80444133] blk: disk 'StarForth Volume' v2 LBN 3072..789009 (785938 user b
|
||||
Artemis: virtio-blk attached
|
||||
ok> : SQ DUP * ;
|
||||
ok
|
||||
ok> 7 SQ . 3 4 U* . .
|
||||
49 0 12 ok
|
||||
ok> T{
|
||||
UNKNOWN WORD: 'T{'
|
||||
ERROR
|
||||
ok> RS1
|
||||
UNKNOWN WORD: 'RS1'
|
||||
ERROR
|
||||
ok> COLD
|
||||
FORTH-79 Cold Start
|
||||
System initialized.
|
||||
ok
|
||||
ok> 3 4 U* . .
|
||||
0 12 ok
|
||||
ok> FORGET U*
|
||||
Protected word
|
||||
ERROR
|
||||
ok> 9 KERNEL-WORD ASK9 ASK9
|
||||
Argument out of range
|
||||
ERROR
|
||||
ok> 1 BLOCK C@ . 2047 BLOCK C@ .
|
||||
0 0 ok
|
||||
ok> 2100 BLOCK 1024 BLANK 65 2100 BLOCK C! UPDATE SAVE-BUFFERS EMPTY-BUFFERS 2100 BLOCK C@ .
|
||||
65 ok
|
||||
ok> 3072 BLOCK C@ .
|
||||
0 ok
|
||||
ok> 3072 BLOCK DROP UPDATE SAVE-BUFFERS
|
||||
Storage refused
|
||||
ERROR
|
||||
ok> 9999999 BLOCK
|
||||
Block out of range
|
||||
ERROR
|
||||
ok> 5 7 PORT!
|
||||
No one on that port
|
||||
ERROR
|
||||
ok> 1 2 + .
|
||||
3 ok
|
||||
ok> 5 AWAIT
|
||||
7 8 * .
|
||||
Interrupted
|
||||
ERROR
|
||||
ok> 56 ok
|
||||
ok> HERE .
|
||||
8300 ok
|
||||
ok> BYE
|
||||
BYE: cold restart
|
||||
@@ -0,0 +1,138 @@
|
||||
UEFI firmware (version 2025.11-3ubuntu7.3 built at 15:40:26 on Sep 23 2026)
|
||||
[2J[001;001H[=3h[2J[001;001H[2J[001;001H[8;031;100t[2J[001;001HBdsDxe: failed to load Boot0002 "UEFI Misc Device" from PciRoot(0x0)/Pci(0x2,0x0): Not Found
|
||||
BdsDxe: failed to load Boot0003 "UEFI QEMU QEMU USB HARDDRIVE 1-0000:00:04.0-1" from PciRoot(0x0)/Pci(0x4,0x0)/USB(0x0,0x0): Not Found
|
||||
BdsDxe: loading Boot0004 "UEFI Misc Device 2" from PciRoot(0x0)/Pci(0x6,0x0)
|
||||
BdsDxe: starting Boot0004 "UEFI Misc Device 2" from PciRoot(0x0)/Pci(0x6,0x0)
|
||||
[2J[001;001H[=3h[2J[001;001HStarKernel UEFI Loader
|
||||
Loading kernel from ESP...
|
||||
[CKPT 001] Entered efi_main - ConOut live
|
||||
Collecting boot information...
|
||||
[CKPT 004] Command line parsed
|
||||
[CKPT 005] Kernel stack allocation decided
|
||||
[CKPT 006] Boot info collected (ACPI table located)
|
||||
[CKPT 007] GOP: linear framebuffer found
|
||||
[CKPT 008] About to enter ExitBootServices retry loop
|
||||
|
||||
|
||||
_____ _ _ __ _
|
||||
/ ____| | | |/ / | |
|
||||
| (___ | |_ __ _ _ __| ' / ___ _ __ _ __ ___| |
|
||||
\___ \| __/ _` | '__| < / _ \ '__| '_ \ / _ \ |
|
||||
____) | || (_| | | | . \ __/ | | | | | __/ |
|
||||
|_____/ \__\__,_|_| |_|\_\___|_| |_| |_|\___|_|
|
||||
|
||||
LithosAnanke v2.1.0
|
||||
Architecture: aarch64
|
||||
Build: Oct 8 2026 01:18:07
|
||||
|
||||
UEFI BootServices: EXITED
|
||||
|
||||
=== StarKernel Boot Information ===
|
||||
Memory map entries: 108
|
||||
Total memory: 4093 MB
|
||||
Usable memory: 4054 MB
|
||||
===================================
|
||||
|
||||
PMM initialized.
|
||||
PMM statistics:
|
||||
Total pages: 1039353
|
||||
Free pages : 1037942
|
||||
Used pages : 1411
|
||||
Total MB : 4059
|
||||
Free MB : 4054
|
||||
Used MB : 5
|
||||
|
||||
VMM initialized (mapped RAM, CR3 switched)
|
||||
VMM initialized (mapped RAM, CR3 switched)
|
||||
VMM self-test: mapped OK at 0xffff800000000000
|
||||
VMM self-test complete.
|
||||
|
||||
AArch64: running at EL1
|
||||
IDT installed.
|
||||
|
||||
APIC: init...
|
||||
PSCI: no DTB -- using HVC (QEMU virt-machine default)
|
||||
GICv2: no DTB GIC node -- using QEMU virt-machine defaults
|
||||
GICv2: distributor+CPU interface enabled, PPI 30
|
||||
APIC: init done
|
||||
|
||||
Timer: init...
|
||||
Timer: AArch64 generic timer initialised.
|
||||
Timer: init done
|
||||
|
||||
Kernel heap initialized.
|
||||
Heap statistics:
|
||||
Total bytes: 2147483608
|
||||
Free bytes: 2147483608
|
||||
Used bytes: 0
|
||||
Peak bytes: 0
|
||||
Heap base addr: 1207959552
|
||||
Heap end addr: 3355443200
|
||||
|
||||
Heartbeat: init...
|
||||
Heartbeat: init done
|
||||
Kernel initialization complete.
|
||||
Boot successful!
|
||||
|
||||
StarForth v4: one host node, the F18-derived engine
|
||||
V4: capsule v4:nucleus-64.f18 signature: missing (unsigned)
|
||||
PARITY:V4_NUCLEUS name=v4:nucleus-64.f18 capsule_id=0xe4f71542c2097e28 capsule_hash=0xe4f71542c2097e28 words=311
|
||||
V4: capsule v4:forth79.4th signature: missing (unsigned)
|
||||
PARITY:V4_CAPSULE name=v4:forth79.4th capsule_id=0x4055641ee17d176b capsule_hash=0x4055641ee17d176b dict_hash=0xe1367a919849c14b
|
||||
PARITY:V4_POST tests=538 pass=538 fail=0
|
||||
PARITY:V4_SYSTEM word_count=317 dict_hash=0x6a39c0bb9d183418
|
||||
PARITY:OK
|
||||
POST: PASSED
|
||||
[32m[HADES][INFO ] [0m[KRELTSC: 0] blk: raw device LBN 2048..3071 (1024 blocks)
|
||||
PCI: init...
|
||||
virtio-blk: found device
|
||||
[32m[HADES][INFO ] [0m[KRELTSC: 1229791] blk: disk 'StarForth Volume' v2 LBN 3072..789009 (785938 user b
|
||||
Artemis: virtio-blk attached
|
||||
ok> : SQ DUP * ;
|
||||
ok
|
||||
ok> 7 SQ . 3 4 U* . .
|
||||
49 0 12 ok
|
||||
ok> T{
|
||||
UNKNOWN WORD: 'T{'
|
||||
ERROR
|
||||
ok> RS1
|
||||
UNKNOWN WORD: 'RS1'
|
||||
ERROR
|
||||
ok> COLD
|
||||
FORTH-79 Cold Start
|
||||
System initialized.
|
||||
ok
|
||||
ok> 3 4 U* . .
|
||||
0 12 ok
|
||||
ok> FORGET U*
|
||||
Protected word
|
||||
ERROR
|
||||
ok> 9 KERNEL-WORD ASK9 ASK9
|
||||
Argument out of range
|
||||
ERROR
|
||||
ok> 1 BLOCK C@ . 2047 BLOCK C@ .
|
||||
0 0 ok
|
||||
ok> 2100 BLOCK 1024 BLANK 65 2100 BLOCK C! UPDATE SAVE-BUFFERS EMPTY-BUFFERS 2100 BLOCK C@ .
|
||||
65 ok
|
||||
ok> 3072 BLOCK C@ .
|
||||
0 ok
|
||||
ok> 3072 BLOCK DROP UPDATE SAVE-BUFFERS
|
||||
Storage refused
|
||||
ERROR
|
||||
ok> 9999999 BLOCK
|
||||
Block out of range
|
||||
ERROR
|
||||
ok> 5 7 PORT!
|
||||
No one on that port
|
||||
ERROR
|
||||
ok> 1 2 + .
|
||||
3 ok
|
||||
ok> 5 AWAIT
|
||||
7 8 * .
|
||||
Interrupted
|
||||
ERROR
|
||||
ok> 56 ok
|
||||
ok> HERE .
|
||||
8300 ok
|
||||
ok> BYE
|
||||
BYE: cold restart
|
||||
@@ -0,0 +1,208 @@
|
||||
|
||||
OpenSBI v1.8
|
||||
____ _____ ____ _____
|
||||
/ __ \ / ____| _ \_ _|
|
||||
| | | |_ __ ___ _ __ | (___ | |_) || |
|
||||
| | | | '_ \ / _ \ '_ \ \___ \| _ < | |
|
||||
| |__| | |_) | __/ | | |____) | |_) || |_
|
||||
\____/| .__/ \___|_| |_|_____/|____/_____|
|
||||
| |
|
||||
|_|
|
||||
|
||||
Platform Name : riscv-virtio,qemu
|
||||
Platform Features : medeleg
|
||||
Platform HART Count : 1
|
||||
Platform HART Protection : pmp
|
||||
Platform IPI Device : aclint-mswi
|
||||
Platform Timer Device : aclint-mtimer @ 10000000Hz
|
||||
Platform Console Device : uart8250
|
||||
Platform HSM Device : ---
|
||||
Platform PMU Device : ---
|
||||
Platform Reboot Device : syscon-reboot
|
||||
Platform Shutdown Device : syscon-poweroff
|
||||
Platform Suspend Device : ---
|
||||
Platform CPPC Device : ---
|
||||
Firmware Base : 0x80000000
|
||||
Firmware Size : 321 KB
|
||||
Firmware RW Offset : 0x40000
|
||||
Firmware RW Size : 65 KB
|
||||
Firmware Heap Offset : 0x47000
|
||||
Firmware Heap Size : 37 KB (total), 0 KB (reserved), 12 KB (used), 23 KB (free)
|
||||
Firmware Scratch Size : 4096 B (total), 1464 B (used), 2632 B (free)
|
||||
Runtime SBI Version : 3.0
|
||||
Standard SBI Extensions : ipi,pmu,srst,sse,hsm,rfnc,fwft,time,base,legacy,dbcn,dbtr
|
||||
Experimental SBI Extensions : none
|
||||
|
||||
Domain0 Name : root
|
||||
Domain0 Boot HART : 0
|
||||
Domain0 HARTs : 0*
|
||||
Domain0 Region00 : 0x0000000080040000-0x000000008005ffff M: (F,R,W) S/U: ()
|
||||
Domain0 Region01 : 0x0000000080000000-0x000000008003ffff M: (F,R,X) S/U: ()
|
||||
Domain0 Region02 : 0x0000000000100000-0x0000000000100fff M: (I,R,W) S/U: (R,W)
|
||||
Domain0 Region03 : 0x0000000010000000-0x0000000010000fff M: (I,R,W) S/U: (R,W)
|
||||
Domain0 Region04 : 0x0000000002000000-0x000000000200ffff M: (I,R,W) S/U: ()
|
||||
Domain0 Region05 : 0x000000000c400000-0x000000000c5fffff M: (I,R,W) S/U: (R,W)
|
||||
Domain0 Region06 : 0x000000000c000000-0x000000000c3fffff M: (I,R,W) S/U: (R,W)
|
||||
Domain0 Region07 : 0x0000000000000000-0xffffffffffffffff M: () S/U: (R,W,X)
|
||||
Domain0 Next Address : 0x0000000020000000
|
||||
Domain0 Next Arg1 : 0x00000000bfe00000
|
||||
Domain0 Next Mode : S-mode
|
||||
Domain0 SysReset : yes
|
||||
Domain0 SysSuspend : yes
|
||||
|
||||
Boot HART ID : 0
|
||||
Boot HART Domain : root
|
||||
Boot HART Priv Version : v1.12
|
||||
Boot HART Base ISA : rv64imafdch
|
||||
Boot HART ISA Extensions : sstc,zicntr,zihpm,zicboz,zicbom,sdtrig,svadu
|
||||
Boot HART PMP Count : 16
|
||||
Boot HART PMP Granularity : 2 bits
|
||||
Boot HART PMP Address Bits : 54
|
||||
Boot HART MHPM Info : 16 (0x0007fff8)
|
||||
Boot HART Debug Triggers : 2 triggers
|
||||
Boot HART MIDELEG : 0x0000000000001666
|
||||
Boot HART MEDELEG : 0x0000000000f4b509
|
||||
[2J[004D[=3h[2J[009D[2J[004D[8;031;100t[2J[016DRISC-V EDK2 firmware version 2025.11-3ubuntu7.3
|
||||
Press ESCAPE within 5 seconds for boot options ERROR: C40000002:V03051002 I0 6D33944A-EC75-4855-A54D-809C75241F6C 83FFF850
|
||||
BdsDxe: failed to load Boot0001 "UEFI Misc Device" fr
|
||||
om PciRoot(0x0)/Pci(0x1,0x0): Not Found
|
||||
[2J[001;001H[=3h[2J[009DStarKernel UEFI Loader
|
||||
Loading kernel from ESP...
|
||||
[CKPT 001] Entered efi_main - ConOut live
|
||||
Monolithic build - kernel linked directly
|
||||
Collecting boot information...
|
||||
CmdLine: parsed OK
|
||||
[CKPT 004] Command line parsed
|
||||
[CKPT 005] Kernel stack allocation decided
|
||||
[CKPT 006] Boot info collected (ACPI table located)
|
||||
GOP: linear framebuffer found
|
||||
[CKPT 007] GOP: linear framebuffer found
|
||||
[CKPT 008] About to enter ExitBootServices retry loop
|
||||
Calling kernel_main (monolithic)...
|
||||
riscv64 item 4.3.5a: satp state at kernel entry (before switch)
|
||||
satp.MODE = 0x000000000000000a
|
||||
satp.PPN = 0x00000000000bf868
|
||||
__kernel_start = 0x00000000bdc9baaa
|
||||
riscv64: satp cleared -- Bare mode, explicit (item 4.3.5a)
|
||||
|
||||
|
||||
_____ _ _ __ _
|
||||
/ ____| | | |/ / | |
|
||||
| (___ | |_ __ _ _ __| ' / ___ _ __ _ __ ___| |
|
||||
\___ \| __/ _` | '__| < / _ \ '__| '_ \ / _ \ |
|
||||
____) | || (_| | | | . \ __/ | | | | | __/ |
|
||||
|_____/ \__\__,_|_| |_|\_\___|_| |_| |_|\___|_|
|
||||
|
||||
LithosAnanke v2.1.0
|
||||
Architecture: riscv64
|
||||
Build: Oct 8 2026 01:21:21
|
||||
|
||||
UEFI BootServices: EXITED
|
||||
|
||||
=== StarKernel Boot Information ===
|
||||
Memory map entries: 100
|
||||
Total memory: 1020 MB
|
||||
Usable memory: 975 MB
|
||||
===================================
|
||||
|
||||
PMM initialized.
|
||||
PMM statistics:
|
||||
Total pages: 250269
|
||||
Free pages : 249617
|
||||
Used pages : 652
|
||||
Total MB : 977
|
||||
Free MB : 975
|
||||
Used MB : 2
|
||||
|
||||
VMM initialized (mapped RAM, CR3 switched)
|
||||
VMM initialized (mapped RAM, CR3 switched)
|
||||
VMM self-test: mapped OK at 0xffff800000000000
|
||||
VMM self-test complete.
|
||||
|
||||
IDT installed.
|
||||
|
||||
APIC: init...
|
||||
PLIC: no DTB PLIC node -- using QEMU virt-machine default (base=0x0c000000)
|
||||
PLIC: init (S-mode context 1, threshold=0)
|
||||
APIC: init done
|
||||
|
||||
Timer: init...
|
||||
Timer: RISC-V time CSR @ 10000000 Hz (FALLBACK, no devicetree)
|
||||
Timer: init done
|
||||
|
||||
Kernel heap initialized.
|
||||
Heap statistics:
|
||||
Total bytes: 536870872
|
||||
Free bytes: 536870872
|
||||
Used bytes: 0
|
||||
Peak bytes: 0
|
||||
Heap base addr: 2214588416
|
||||
Heap end addr: 2751459328
|
||||
|
||||
Heartbeat: init...
|
||||
Heartbeat: init done
|
||||
Kernel initialization complete.
|
||||
Boot successful!
|
||||
|
||||
StarForth v4: one host node, the F18-derived engine
|
||||
V4: capsule v4:nucleus-64.f18 signature: missing (unsigned)
|
||||
PARITY:V4_NUCLEUS name=v4:nucleus-64.f18 capsule_id=0xe4f71542c2097e28 capsule_hash=0xe4f71542c2097e28 words=311
|
||||
V4: capsule v4:forth79.4th signature: missing (unsigned)
|
||||
PARITY:V4_CAPSULE name=v4:forth79.4th capsule_id=0x4055641ee17d176b capsule_hash=0x4055641ee17d176b dict_hash=0xe1367a919849c14b
|
||||
PARITY:V4_POST tests=538 pass=538 fail=0
|
||||
PARITY:V4_SYSTEM word_count=317 dict_hash=0x6a39c0bb9d183418
|
||||
PARITY:OK
|
||||
POST: PASSED
|
||||
[32m[HADES][INFO ] [0m[KRELTSC: 0] blk: raw device LBN 2048..3071 (1024 blocks)
|
||||
PCI: init...
|
||||
virtio-blk: found device
|
||||
[32m[HADES][INFO ] [0m[KRELTSC: 18926187] blk: disk 'StarForth Volume' v2 LBN 3072..789009 (785938 user b
|
||||
Artemis: virtio-blk attached
|
||||
ok> : SQ DUP * ;
|
||||
ok
|
||||
ok> 7 SQ . 3 4 U* . .
|
||||
49 0 12 ok
|
||||
ok> T{
|
||||
UNKNOWN WORD: 'T{'
|
||||
ERROR
|
||||
ok> RS1
|
||||
UNKNOWN WORD: 'RS1'
|
||||
ERROR
|
||||
ok> COLD
|
||||
FORTH-79 Cold Start
|
||||
System initialized.
|
||||
ok
|
||||
ok> 3 4 U* . .
|
||||
0 12 ok
|
||||
ok> FORGET U*
|
||||
Protected word
|
||||
ERROR
|
||||
ok> 9 KERNEL-WORD ASK9 ASK9
|
||||
Argument out of range
|
||||
ERROR
|
||||
ok> 1 BLOCK C@ . 2047 BLOCK C@ .
|
||||
0 0 ok
|
||||
ok> 2100 BLOCK 1024 BLANK 65 2100 BLOCK C! UPDATE SAVE-BUFFERS EMPTY-BUFFERS 2100 BLOCK C@ .
|
||||
65 ok
|
||||
ok> 3072 BLOCK C@ .
|
||||
0 ok
|
||||
ok> 3072 BLOCK DROP UPDATE SAVE-BUFFERS
|
||||
Storage refused
|
||||
ERROR
|
||||
ok> 9999999 BLOCK
|
||||
Block out of range
|
||||
ERROR
|
||||
ok> 5 7 PORT!
|
||||
No one on that port
|
||||
ERROR
|
||||
ok> 1 2 + .
|
||||
3 ok
|
||||
ok> 5 AWAIT
|
||||
7 8 * .
|
||||
Interrupted
|
||||
ERROR
|
||||
ok> 56 ok
|
||||
ok> HERE .
|
||||
8300 ok
|
||||
ok> BYE
|
||||
BYE: cold restart
|
||||
+8
-2
@@ -141,8 +141,14 @@ sixteenth to pass it on, sends a NACK to whoever waits on it; `(REFUSED)`
|
||||
counts them. `AWAIT` ends in an error if the answer is not going to come:
|
||||
"Message refused", "Node gone", or "Interrupted" when a line is typed at
|
||||
the console. `n KILL` on Hera removes node n and tells every other node it
|
||||
is gone; a node believes that only from its centre. A stuck node can hold
|
||||
up its neighbours until it is killed: `MESH.md` 7b.7 says how.
|
||||
is gone; a node believes that only from its centre.
|
||||
|
||||
**The wait** (`MESH.md` 7c, step 6d). A node does not write the first word
|
||||
of a message: it offers it, and sleeps until it is taken or a word comes
|
||||
for it. What a node has to pass on, the answers it has to give and the
|
||||
refusals it owes all wait with it, offered, and go when they can. So a
|
||||
node that is stuck holds up no other: only text that must itself send to
|
||||
the stuck node waits, and on Hera a typed line ends that.
|
||||
|
||||
**Blocks** (`MESH.md` step 6). The block words are the kernel's, as they
|
||||
are for a v3 VM: `BLOCK`, `BUFFER`, `UPDATE`, `SAVE-BUFFERS` and
|
||||
|
||||
@@ -26,7 +26,6 @@ typedef struct {
|
||||
int (*take)(void *self, v4_cell value); /* the node wrote `value`: 1 if it is taken, 0 if not yet */
|
||||
int (*give)(void *self, v4_cell *value); /* the node is reading: 1 with a word in *value, 0 if not yet */
|
||||
void *self;
|
||||
int (*pending)(void *self); /* 1 if it has a word to give that has not been asked for; may be 0: it never says */
|
||||
} v4_device;
|
||||
|
||||
/* One end of a wire. */
|
||||
@@ -56,7 +55,6 @@ typedef struct {
|
||||
v4_place *place;
|
||||
unsigned capacity;
|
||||
v4_cell gone_error; /* see v4_fabric_gone_error; 0: none */
|
||||
v4_cell interrupt_error; /* see v4_fabric_interrupt_error; 0: none */
|
||||
} v4_fabric;
|
||||
|
||||
/* An empty fabric with room for `capacity` nodes, in `places`. */
|
||||
@@ -73,19 +71,6 @@ void v4_fabric_init(v4_fabric *f, v4_place *places, unsigned capacity);
|
||||
* is how a fabric begins, nothing is raised. */
|
||||
void v4_fabric_gone_error(v4_fabric *f, v4_cell code);
|
||||
|
||||
/* A NODE BLOCKED WRITING TO A NODE THAT DOES NOT READ. Of two neighbours
|
||||
* one may write to the other without looking (docs/v4.0.0/MESH.md 7a), and
|
||||
* is then blocked until the other reads; if the other never does, it is
|
||||
* blocked for ever, and if it is the node the console is on, nothing can be
|
||||
* typed to it again. So: when a node that can take an error is blocked
|
||||
* writing to another node, on the first word of a message (node.h,
|
||||
* v4_node_words_since_look: nothing of the message has gone), and a device
|
||||
* on one of its own ports says it has something pending for it, the error
|
||||
* `code` is raised on the node: it gives up that message and goes on, to
|
||||
* read what the device has. Only a device with a `pending` function can
|
||||
* do this. With `code` 0, which is how a fabric begins, it never happens. */
|
||||
void v4_fabric_interrupt_error(v4_fabric *f, v4_cell code);
|
||||
|
||||
/* More room: `places`, of `capacity` no less than before, takes over; every
|
||||
* node keeps its number and its wiring. */
|
||||
void v4_fabric_grow(v4_fabric *f, v4_place *places, unsigned capacity);
|
||||
|
||||
@@ -65,11 +65,6 @@ typedef struct {
|
||||
* port". */
|
||||
#define V4_ERROR_NO_ONE 18
|
||||
|
||||
/* The nucleus's error for a node let go of a message it was blocked on the
|
||||
* first word of, because its console has a line for it (fabric.h,
|
||||
* v4_fabric_interrupt_error): "Interrupted". */
|
||||
#define V4_ERROR_INTERRUPTED 21
|
||||
|
||||
/* The description of the nucleus built from v4/capsule (the generated file
|
||||
* defines it). */
|
||||
extern const v4_image v4_capsule_image;
|
||||
|
||||
@@ -113,7 +113,6 @@ typedef struct {
|
||||
unsigned last_from; /* the port the last read from "any" took its word from */
|
||||
unsigned writers; /* bit k: the neighbour on port k is blocked writing to this node */
|
||||
unsigned readers; /* bit k: the neighbour on port k is blocked reading from this node */
|
||||
unsigned since_look; /* words taken from this node since it last fetched either of those */
|
||||
unsigned offers; /* bit k: a word is offered on port k (the wait: docs/v4.0.0/MESH.md 7c) */
|
||||
v4_cell offer[V4_PORTS]; /* the words offered */
|
||||
int waiting; /* non-zero: the read it is blocked in is the wait */
|
||||
@@ -225,13 +224,6 @@ void v4_node_port_attach(v4_node *n, v4_cell base);
|
||||
/* The neighbour has taken what the node wrote. */
|
||||
void v4_node_port_served(v4_node *n);
|
||||
|
||||
/* How many words the node has had taken since it last looked at its
|
||||
* neighbours (a fetch of either of the two status addresses). A node that
|
||||
* looks before it begins a message (MESH.md 7a) and is blocked writing with
|
||||
* this at 0 is blocked on the first word of the message: nothing of it has
|
||||
* gone. */
|
||||
unsigned v4_node_words_since_look(const v4_node *n);
|
||||
|
||||
/* THERE IS NO ONE ON THE PORT the node is blocked at -- writing to it, or
|
||||
* reading from that one port -- and there will not be. A node that can
|
||||
* take an error (it has an error register and a fault table: node.h,
|
||||
|
||||
@@ -18,7 +18,6 @@ void v4_fabric_init(v4_fabric *f, v4_place *places, unsigned capacity)
|
||||
f->place = places;
|
||||
f->capacity = capacity;
|
||||
f->gone_error = 0;
|
||||
f->interrupt_error = 0;
|
||||
for (i = 0; i < capacity; i++) clear_place(&places[i]);
|
||||
}
|
||||
|
||||
@@ -27,10 +26,6 @@ void v4_fabric_gone_error(v4_fabric *f, v4_cell code)
|
||||
f->gone_error = code;
|
||||
}
|
||||
|
||||
void v4_fabric_interrupt_error(v4_fabric *f, v4_cell code)
|
||||
{
|
||||
f->interrupt_error = code;
|
||||
}
|
||||
|
||||
void v4_fabric_grow(v4_fabric *f, v4_place *places, unsigned capacity)
|
||||
{
|
||||
@@ -239,24 +234,6 @@ unsigned v4_fabric_step(v4_fabric *f)
|
||||
}
|
||||
}
|
||||
|
||||
/* a node blocked on the first word of a message to a node that is not
|
||||
* reading, while a device of its own has something for it */
|
||||
if (f->interrupt_error != 0)
|
||||
for (i = 0; i < f->capacity; i++) {
|
||||
v4_node *n;
|
||||
unsigned k;
|
||||
if (!awake(f, i)) continue;
|
||||
n = &f->place[i].node->n;
|
||||
if (!n->asking || f->place[i].wire[n->ask_port].kind != V4_WIRE_NODE || v4_node_words_since_look(n) != 0) continue;
|
||||
for (k = 0; k < V4_PORTS; k++) {
|
||||
const v4_wire *w = &f->place[i].wire[k];
|
||||
if (w->kind == V4_WIRE_DEVICE && w->device->pending && w->device->pending(w->device->self)) {
|
||||
done += (unsigned)v4_node_port_gone(n, f->interrupt_error);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* a node blocked at one port that nothing is wired to */
|
||||
if (f->gone_error != 0)
|
||||
for (i = 0; i < f->capacity; i++) {
|
||||
|
||||
+2
-8
@@ -126,8 +126,8 @@ v4_cell v4_node_fetch(v4_node *n, v4_cell addr)
|
||||
{
|
||||
int port = v4_node_port_index(n, addr);
|
||||
if (port == (int)V4_PORTS + 1) return (v4_cell)n->last_from;
|
||||
if (port == (int)V4_PORTS + 2) { n->since_look = 0; return (v4_cell)n->writers; }
|
||||
if (port == (int)V4_PORTS + 3) { n->since_look = 0; return (v4_cell)n->readers; }
|
||||
if (port == (int)V4_PORTS + 2) return (v4_cell)n->writers;
|
||||
if (port == (int)V4_PORTS + 3) return (v4_cell)n->readers;
|
||||
if (port == (int)V4_PORT_WAIT) {
|
||||
/* the wait: the word that came, or 0 for an offer taken */
|
||||
if (!n->given) return 0;
|
||||
@@ -193,7 +193,6 @@ void v4_node_port_attach(v4_node *n, v4_cell base)
|
||||
n->last_from = 0;
|
||||
n->writers = 0;
|
||||
n->readers = 0;
|
||||
n->since_look = 0;
|
||||
n->offers = 0;
|
||||
n->waiting = 0;
|
||||
n->offer_asked = 0;
|
||||
@@ -273,17 +272,12 @@ void v4_node_born(v4_node *n, v4_cell base)
|
||||
void v4_node_port_served(v4_node *n)
|
||||
{
|
||||
n->asking = 0;
|
||||
n->since_look++;
|
||||
if (n->offer_asked) { /* what was served was an offer: the wait is over */
|
||||
n->offer_asked = 0;
|
||||
v4_node_port_give(n, V4_PORTS + n->ask_port, 0);
|
||||
}
|
||||
}
|
||||
|
||||
unsigned v4_node_words_since_look(const v4_node *n)
|
||||
{
|
||||
return n->since_look;
|
||||
}
|
||||
|
||||
int v4_node_port_gone(v4_node *n, v4_cell code)
|
||||
{
|
||||
|
||||
@@ -70,10 +70,6 @@ static void count_for_ever(void)
|
||||
v4_asm_branch(&as, V4_OP_JUMP, again);
|
||||
}
|
||||
|
||||
/* a device that says whether it has something pending */
|
||||
static int *dev_has;
|
||||
static int device_has(void *self) { (void)self; return *dev_has; }
|
||||
|
||||
/* Let time pass until nothing more can happen, or `max` steps. */
|
||||
static unsigned settle(unsigned max)
|
||||
{
|
||||
@@ -392,62 +388,6 @@ int main(void)
|
||||
CHECK(ND(a)->n.asking && ND(a)->n.request == 5 && ND(c)->n.reading && ND(c)->n.mem[OUT] == 0, "looking takes nothing and gives nothing: both wait as they did");
|
||||
CHECK(!ND(b)->n.stopped && ND(b)->n.reading, "and the one that looked did not wait to look");
|
||||
|
||||
/* ---- a node blocked on the first word of a message, while a device of its own has something for it ---- */
|
||||
{
|
||||
static int has; /* what the device says it has pending */
|
||||
static stream none;
|
||||
static v4_device dev;
|
||||
v4_fabric_init(&f, places, 4);
|
||||
for (i = 0; i < 3; i++) v4_node_reset(&pool[i].n);
|
||||
a = loaded(0); /* looks about, then writes two words to its port 0 */
|
||||
LIT(PB + (v4_cell)V4_PORTS + 3); O(BANG_B); O(FETCH_B); O(DROP);
|
||||
LIT(PB + 0); O(BANG_B); LIT(1); O(STORE_B); LIT(2); O(STORE_B); wait_for_ever();
|
||||
b = loaded(1); /* never reads */
|
||||
LIT(OUT); O(BANG_A);
|
||||
{
|
||||
v4_cell again = v4_asm_label(&as);
|
||||
O(FETCH_A); LIT(1); O(ADD); O(STORE_A);
|
||||
v4_asm_branch(&as, V4_OP_JUMP, again);
|
||||
}
|
||||
CHECK(v4_asm_ok(&as) && v4_fabric_wire(&f, a, 0, b, 3), "a writer that looks first, wired to a node that never reads");
|
||||
dev.take = stream_take; dev.give = 0; dev.self = &none; dev.pending = device_has; has = 1; dev_has = &has;
|
||||
CHECK(v4_fabric_wire_device(&f, a, 5, &dev), "and to a device, which has something for it");
|
||||
for (i = 0; i < 40; i++) (void)v4_fabric_step(&f);
|
||||
CHECK(ND(a)->n.asking && ND(a)->n.request == 1 && v4_node_words_since_look(&ND(a)->n) == 0, "the writer is blocked on its first word, and waits: the fabric has no error for it");
|
||||
v4_fabric_interrupt_error(&f, 21);
|
||||
for (i = 0; i < 40; i++) (void)v4_fabric_step(&f);
|
||||
CHECK(ND(a)->n.asking && ND(a)->n.faults == 0, "nor is a bare node let go when it has: it cannot take an error");
|
||||
v4_node_error_attach(&ND(a)->n, OUT + 20);
|
||||
v4_node_fault_attach(&ND(a)->n, 900);
|
||||
has = 0;
|
||||
for (i = 0; i < 40; i++) (void)v4_fabric_step(&f);
|
||||
CHECK(ND(a)->n.asking && ND(a)->n.faults == 0, "a node that can take one waits all the same while the device has nothing for it");
|
||||
has = 1;
|
||||
(void)v4_fabric_step(&f);
|
||||
CHECK(!ND(a)->n.asking && ND(a)->n.fault_kind == V4_FAULT_RAISED && ND(a)->n.fault_addr == 21 && ND(a)->n.mem[OUT + 20] == 21,
|
||||
"when it has, the writer is let go and the error raised on it");
|
||||
|
||||
/* once the first word has gone, it is not let go: the message must be finished */
|
||||
v4_fabric_init(&f, places, 4);
|
||||
for (i = 0; i < 3; i++) v4_node_reset(&pool[i].n);
|
||||
a = loaded(0);
|
||||
LIT(PB + (v4_cell)V4_PORTS + 3); O(BANG_B); O(FETCH_B); O(DROP);
|
||||
LIT(PB + 0); O(BANG_B); LIT(1); O(STORE_B); LIT(2); O(STORE_B); wait_for_ever();
|
||||
b = loaded(1); /* reads one word, and no more */
|
||||
LIT(PB + 3); O(BANG_B); O(FETCH_B); LIT(OUT); O(BANG_A);
|
||||
{
|
||||
v4_cell again = v4_asm_label(&as);
|
||||
O(FETCH_A); LIT(1); O(ADD); O(STORE_A);
|
||||
v4_asm_branch(&as, V4_OP_JUMP, again);
|
||||
}
|
||||
CHECK(v4_asm_ok(&as) && v4_fabric_wire(&f, a, 0, b, 3) && v4_fabric_wire_device(&f, a, 5, &dev), "the same, to a node that reads one word and no more");
|
||||
v4_node_error_attach(&ND(a)->n, OUT + 20);
|
||||
v4_node_fault_attach(&ND(a)->n, 900);
|
||||
v4_fabric_interrupt_error(&f, 21);
|
||||
for (i = 0; i < 60; i++) (void)v4_fabric_step(&f);
|
||||
CHECK(ND(a)->n.asking && ND(a)->n.request == 2 && ND(a)->n.faults == 0, "blocked on its second word with the device still pending, the writer waits");
|
||||
}
|
||||
|
||||
/* ---- the wait (MESH.md 7c): a node offers a word and sleeps ---- */
|
||||
{
|
||||
static stream none;
|
||||
|
||||
@@ -71,8 +71,7 @@ static int console_take(void *self, v4_cell value)
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
static int console_pending(void *self) { (void)self; return going_at < going.count; }
|
||||
static const v4_device console = { console_take, console_give, 0, console_pending };
|
||||
static const v4_device console = { console_take, console_give, 0 };
|
||||
|
||||
static int is_empty(const char *s) { return s[0] == 0; }
|
||||
|
||||
|
||||
@@ -140,7 +140,7 @@ static int host_born(void *self)
|
||||
v4_node_fault_attach(&pool[k].n, w_fault);
|
||||
v4_blocks_init(&node_blocks[k], BUF0_W);
|
||||
if (k != 0) { /* Hera's kernel is wired where she is made */
|
||||
node_kernel[k].take = node_kernel_take; node_kernel[k].give = 0; node_kernel[k].self = &pool[k]; node_kernel[k].pending = 0;
|
||||
node_kernel[k].take = node_kernel_take; node_kernel[k].give = 0; node_kernel[k].self = &pool[k];
|
||||
if (!v4_fabric_wire_device(&f, (unsigned)place, 0, &node_kernel[k])) return -1;
|
||||
}
|
||||
return place;
|
||||
@@ -194,7 +194,7 @@ static int kernel_take(void *self, v4_cell value) /* a request */
|
||||
if (value < FIRST_REQUEST || !v4_manage_serve(&manage, hera_place, (unsigned)(value - FIRST_REQUEST))) refused++;
|
||||
return 1;
|
||||
}
|
||||
static const v4_device kernel = { kernel_take, kernel_give, 0, 0 };
|
||||
static const v4_device kernel = { kernel_take, kernel_give, 0 };
|
||||
|
||||
/* ---- the console: a device on Hera's port 1 ---- */
|
||||
#define CONSOLE_ID 1
|
||||
@@ -237,8 +237,7 @@ static int console_take(void *self, v4_cell value)
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
static int console_pending(void *self) { (void)self; return going_at < going.count; }
|
||||
static const v4_device console = { console_take, console_give, 0, console_pending };
|
||||
static const v4_device console = { console_take, console_give, 0 };
|
||||
|
||||
/* Is there a node that will execute at the next step? A step in which a
|
||||
* node only faulted counts nothing done (exec.h), and it goes on from its
|
||||
@@ -384,7 +383,6 @@ 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);
|
||||
v4_fabric_interrupt_error(&f, V4_ERROR_INTERRUPTED);
|
||||
place = host_born(0);
|
||||
CHECK(place == 0, "a node is born");
|
||||
hera_place = (unsigned)place;
|
||||
|
||||
Reference in New Issue
Block a user