Repository navigation
all: fix the 0.3.0 review findings and bump to v0.3.1 - #10
Merged
Merged
Conversation
Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Co-authored-by: Astra <noreply@openai.com>
karalabe
force-pushed
the
loom-models
branch
from
September 26, 2026 01:43
119c55a to
03445af
Compare
Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Co-authored-by: Astra <noreply@openai.com>
karalabe
force-pushed
the
loom-models
branch
from
September 26, 2026 02:36
03445af to
dbcb6cf
Compare
Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes the findings of a second review of 0.3.0, and model-checks the wake protocol that #7 introduced.
A
notify_oneends at most one wait, one already waiting when it was sent. Waits on one condvar used to share a notification count. So once anotify_onehad gone to one wait, every other wait on that condvar left at its next wakeup of any kind. On a test clock, that included an advance reaching another wait on the condvar, and the wait that left then dropped out ofnext_deadline()until it waited again. In the review's probe, a driver stepping throughnext_deadline()over timed pool workers stopped early in 537 of 3,000 runs. Eachnotify_onenow queues a numbered notification that only a wait started before it can take, oldest first, and anotify_allends every wait started before it. An advance still wakes the other waits on a reached wait's condvar, but they find nothing and keep waiting, counted and listed. Notifications are still not buffered, and a notification the wait takes still wins over a reached deadline.next_deadline()reports a deadline that an advance already passed as the current time, since its wait stays listed until its thread runs.advance_to(next_deadline())used to panic with "clock cannot go backwards" when a thread the driver does not await, such as a heartbeat, was reached but had not run yet.An advance wakes the waits it reaches in deadline order, and timers due at the same instant fire in the order they were armed, both through a per-clock sequence number. Both used to follow heap addresses. A waiting
select_biased!over timers due at the same instant then took an arbitrary arm, and loom's replays diverged whenever one advance reached two waits, so no model could check that case. The signal registry only served that address lookup, so it is gone, and each listed deadline holds its own signal.The real
Clock::sleepsleeps in slices of at most a day, assleep_untildoes, since some Windows versions never return from athread::sleepof about 49.7 days or more.The first commit adds three loom models: a partial advance leaves a sleep listed, reaching one deadline wait keeps a later one on the same condvar listed, and a notification survives an advance racing it. The second adds six more. They cover a consumed
notify_oneleaving the other wait listed through an advance, a later wait never taking an earlier wait's notification, and a broadcast followed at once by anotify_one. They also cover one advance reaching two sleeps, at different and at equal deadlines, and two condvars, which fail on replay against 0.3.0. Unit tests cover the same notification cases deterministically, plus oldest-first taking, one notification against two reached waits,next_deadline()at the current time, delivery in deadline and arming order through a blockedselect_biased!, and deadline registrations. Each fails when the rule it checks is broken, 32 mutations in all.The unit tests also pass with every untimed wait returning spuriously every 20 µs, in 60 runs of the whole suite. Locally, every loom model passes at preemption bounds 5 and 6, and all but one at 7. In release mode, the suite ran 25,280 times on Linux and 2,000 times on macOS without a failure, all on this library code. The review's probes run clean: no early stop or overshoot in 24,000 driver runs, and no panic in 22,000 heartbeat and overshoot runs.
On macOS, real-clock hand-offs stay within the noise of 0.3.0, and a wait whose deadline has already passed takes about 48 ns instead of 37 ns. Locally, the loom suite takes about 90 s at CI's bound, against 12 s before the first commit.
The third commit bumps the version to 0.3.1, since the public API is unchanged. The fourth rewords three comments that ended a claim with "and no other" or a similar exclusion. Once this is merged, tagging
v0.3.1publishes the release through the trusted publishing workflow.Left as they are: the real-clock condvar keeps its extra lock,
recv_deadlinekeeps its retry after an advance, andafterandrecv_timeoutkeep their own overflow rule. The real sleep's slicing has no test, assleep_until's has none.