Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 44 additions & 0 deletions docs/provenance.md
Original file line number Diff line number Diff line change
Expand Up @@ -427,3 +427,47 @@ files. Against that branch's export at `10c7b400`, only kore-rt's `futex.rs`
and `thread_controller.rs`, the record, and five services' `boot.toml`
digests differ. The digests come from #1494's own reseal (`f2644e5b`), which
followed its export.

## A relayed wake reaches its waiter alone

The export records Kore `fba0662d3485d065ef85ffd400acd4643e73460f`, on
`ft/admiring-lovelace-69eiok`, which is stacked on `ft/brave-heisenberg-zgoaux`
and merges its head (`83861dc9`). Against that branch's export at `4a56f827`,
the closure keeps its 27 packages and 401 files, and two things differ:

- `kore-rt`'s thread controller relays a wake to the threads it was for and no
others (Kore `b67f198`). Managed threads hold no send into each other's
doorbells, so a wake between two of them goes through the controller's hub.
The hub used to count relays, and the controller swept: it kicked every
thread with a doorbell waiter, whatever word that thread waited on, so every
relayed wake woke every parked thread in the program. Now a waker owes the
hub the bands of the waiters it found and could not kick before it moves the
hub's word: `wake` owes its first, `wake_all` all of them and `wake_thread`
its target. The controller takes the owed bands after it reads that word and
kicks each band that still waits. The registry's Dekker argument makes this
lossless: a waiter that registers after the waker's scan reads the new word
and never parks.
- `services/swap/boot.toml`'s digests, from that branch's reseal (`83861dc9`),
which followed its export. This branch's reseal over the relay follows this
export in turn.

No exported manifest changed, so `native/Cargo.lock` did not.

Nothing in `kore-ffi` or `kore-c` changes. A C program's futex wakes take the
controller's relay as before and reach fewer threads; `docs/runtime.md` now
says so. The metal evidence is Kore's `keytest-tcc-x86`. The libkore tour has
two threads take 400 turns through a mutex and a condition variable on the
futex while `main` and as many more threads as the controller admits, up to
eight, wait parked on words nobody stores. Before the founder's arena, the
controller admitted two managed threads at once, so `main` was the only
parked thread. On the image built from `4f913c4` no wake reached it; with
kore-rt's futex and controller from `a4ab7234`, which count and sweep, it was
woken 208 times and the tour failed that step. Kore `e0717eb` repeated that
over the founding wait: no wake, against 206 with the founding wait's own
futex and controller (`36b99426`).

Kore's reseal over this export measures it with all nine parked (`09a98a0`,
built from `8b617ee`, which pins it): every step ran to `exit 42` and no wake
reached any of them. The same tree with the futex and controller of that
branch's head (`83861dc9`), which count and sweep, delivered 1466 wakes to
them over the 400 turns, and the tour failed that step.
6 changes: 5 additions & 1 deletion docs/runtime.md
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,11 @@ capabilities; portable handles contain identifiers, never arena slot authority.
Calls use bounded shared records and futex parks: the controller parks until a
request, a thread's end or a relayed wake moves its word, and a waiting caller
parks until the controller wakes it. Only a thread the controller cannot wake
parks in bounded 1 ms slices. Calls must run on native threads, not executor
parks in bounded 1 ms slices. Managed threads hold no send into each other's
doorbells, so a futex wake between two of them is relayed through the
controller, which kicks only the thread the waker found waiting: a mutex or
condition handed between two threads leaves the threads parked on other words
asleep. Calls must run on native threads, not executor
callbacks that owe other futures progress. Capacity depends on native bands and
the controller's capability arena; ordinary slot exhaustion is refused before
spending a band.
Expand Down
Loading