Conversation
…ail claim
Peeled from `mikegrier/deferred-namespace-ops`, where it was written alongside
work that is not ready. It is landed on its own because it is an INSTRUMENT: it
is useful before the plan that consumes it exists, and landing it first is what
lets that decision be made against a measurement rather than an argument.
The probe answers two questions a queue-shape decision is waiting on: whether
the bounded array queue's tail claim contends badly enough to justify the linked
and sharded MPSC shapes, and what `reserving_mpsc`'s extra read of the
consumer's position actually costs.
Two regimes, and the pair is the point. **Isolated** gives producers capacity
large enough that nothing is refused and runs no consumer, so whatever curve
appears against N is the claim and nothing else. **Drained** runs a consumer
popping continuously, which is the only regime that can price the read of
`head` -- that read is cheap until a consumer is WRITING the line, so measuring
it in isolation would report it as free. Each row carries the refusal count from
the queue's own `Observable` counters, so a consumer-bound plateau is visible as
a fact rather than mistaken for contention.
**It is deliberately absent from the CI probe job**, unlike every other probe,
and the reason is a measurement rather than a preference: that job runs
`cargo run` without `--release`, and in a debug build `mpsc` and
`reserving_mpsc` come out at 249.7 and 254.0 ns/push at sixteen producers --
indistinguishable. In release, same machine, same minute: 193.5 and 52.2. A
debug run does not merely lose precision, it reports the two shapes as
equivalent, which is a confident wrong answer. It also wants more cores than a
hosted runner has, and costs about a minute against a job whose other probes
are seconds.
Verified by running it rather than by building it: exit 0 in 64.8s on
x86_64 16p/8c, 181 lines, banner and both regimes present. At sixteen producers,
isolated: `baseline_fetch_add` 14.2 ns/push, `reserving_mpsc` 35.0,
`permit_mpsc` 22.2, `slotwise_mpsc` 198.5.
The `experimental-permit-claim` feature is enabled on the dependency because
this probe is what decides its fate -- it has to be measured against the
shipping shapes on the same host, in the same run, by the same harness. `dwcas`
is what lets it instantiate the 128-bit claim layout.
Two design-note corrections were needed on the way in, because the notes had
been written against a state that has since moved:
- The claim-word section said the three apportionments were "built as
duplicates in claim_layout.rs so the shipping crate was not disturbed".
That scaffolding is gone -- the layouts SHIP now, as `ClaimLayout` with
`Balanced`, `Enduring`, `Perpetual` and `Wide`, which is what this probe
imports. A reader who went looking for `claim_layout.rs` would not have
found it. The duplicate-then-decide cycle closed and the note never said so.
- Both sections linked to checklists that do not exist in this repository
(`CHECKLIST-io-domains.md`, `CHECKLIST-claim-word-layout.md`); they arrive
with the rest of the queue work. The notes now name the QUESTIONS rather
than linking to items that would dangle, and say plainly that the plans
carrying them land later.
Every link in the added notes was checked to resolve before writing it.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
🟡 Changes recommended
Unresolved benchmark timing, consumer-readiness, interpretation, and documentation issues remain.
Get a fresh assessment by requesting another Copilot review.
Pull request overview
Adds a standalone Windows queue-contention probe for comparing MPSC queue shapes, reservation costs, and claim layouts.
Changes:
- Adds isolated and drained benchmark regimes with refusal counts.
- Registers the probe binary and enables required queue features.
- Documents methodology, rationale, and recorded measurements.
File summaries
| File | Reviewed change |
|---|---|
crates/windows-platform-probes/src/queue_contention.rs |
Benchmark implementation and timing regimes |
crates/windows-platform-probes/src/lib.rs |
Probe module export and documentation index |
crates/windows-platform-probes/src/bin/queue_contention.rs |
Benchmark report rendering and comparisons |
crates/windows-platform-probes/DESIGN-NOTES.md |
Measurement rationale and results |
crates/windows-platform-probes/Cargo.toml |
Binary registration and dependency features |
Cargo.lock |
Dependency graph update |
Review details
Suppressed comments (6)
crates/windows-platform-probes/DESIGN-NOTES.md:525
- The heading says the wide word costs 2-3x, but the shipping-type measurements below report 3.83x and 3.99x at 16 and 32 producers, and the later section explicitly says those values supersede the earlier stand-in results. Update the heading so it does not understate the result that this note now treats as authoritative.
## The claim word's width costs 2-3x in isolation and much less in use
crates/windows-platform-probes/DESIGN-NOTES.md:530
- This introduction still says there are three apportionments and omits the probe's
8/56(Perpetual) layout. The current probe measures four layouts, and the superseding table below includes 8/56, so the note's setup is inconsistent with the instrument it documents.
Three apportionments of `reserving_mpsc`'s claim word: 32/32 and 16/48 over
`AtomicU64`, and 64/64 over `AtomicU128`.
crates/windows-platform-probes/src/bin/queue_contention.rs:183
cmpxchg16bis x86-specific, but this binary can be built for the repository's other Windows targets andportable-atomicuses target-specific primitives for the wide operation. On ARM64 this line mislabels the instruction being measured. Use architecture-neutral wording or render the instruction conditionally.
" apportioned differently; 64/64 is a u128 exchange (cmpxchg16b)."
crates/windows-platform-probes/src/queue_contention.rs:31
- Removing the consumer and backpressure does not make this "the compare-and-swap and nothing else": each timed push still performs the queue's slot-metadata/publication work, and
reserving_mpscstill readsheadeven when no consumer is running. The resulting curve is total producer-only push-path scaling, so interpreting it as pure tail-CAS contention can misattribute the cost behind the queue-shape decision. Please narrow this description or add a matched control that holds the other push-path work constant.
//! - **Isolated** -- capacity large enough that nothing is ever refused, and no
//! consumer running. This is the *cleanest* measurement of tail-claim
//! contention: nothing else touches the queue, so whatever curve appears
//! against N is the compare-and-swap and nothing else.
crates/windows-platform-probes/src/queue_contention.rs:410
- All participants are released at the same barrier, but that does not make the consumer ready to pop. The scheduler can run producers first, fill the 1024-slot queue, and record refusal/retry cycles before the consumer writes
head; that startup delay is included instarted, so the drained rows are not guaranteed to represent a continuously draining consumer, especially at low producer counts. Add a consumer-readiness handshake before starting the producers and clock, and apply it to each drained helper.
let consumer = thread::spawn(move || {
consumer_gate.wait();
// Spin rather than park: the doorbell's cost is `doorbell_cost`'s
// question, and parking here would measure that instead of the claim.
while !consumer_done.load(Ordering::Relaxed) {
crates/windows-platform-probes/src/queue_contention.rs:281
- The barrier only releases the workers; it does not synchronize their first operation with the timestamp taken afterward. Once
gate.wait()releases everyone, a worker can run (or finish) before the main thread is scheduled to executeInstant::now(), so the elapsed interval is too short and the reported throughput can be inflated, especially for the one-producer rows. This release-then-timestamp pattern is repeated throughout the timed functions; use a ready barrier plus a separate release barrier (or another timestamp handoff) so the timestamp is established before workers enter the loop.
gate.wait();
Instant::now()
- Files reviewed: 5/6 changed files
- Comments generated: 3
- Review effort level: Lite
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
…features took away Four findings from a code review of this PR, one of them a real regression the PR introduced. **Enabling `dwcas` and `experimental-permit-claim` on a workspace member unifies them across the whole workspace.** `windows-platform-probes` did not depend on `windows-waitable-queues` at all before this branch, so every `--workspace` step built that crate at its default features. With the probe's dependency added, `cargo tree --workspace -e features -i windows-waitable-queues` now reports both features on, sourced solely from here -- and since CI builds that crate only through `--workspace` steps, with no `-p windows-waitable-queues` job anywhere, NOTHING was left compiling it without `dwcas`. That is the configuration that can break unnoticed, because `dwcas` is additive: `Wide` and its `ClaimLayout` impl exist only under it. The queue crate's own manifest calls `dwcas` "non-default so nothing depends on it by accident" and "the only thing in this crate that costs a third-party dependency" -- claims that are only true while something still builds without it. Fixed by adding a `windows-waitable-queues (default features)` job, modelled on the existing `placement-probe-no-serde` job, which exists for exactly this shape of problem. Verified locally before committing: build, clippy `-D warnings`, and 304 + 12 + 1 tests all clean at default features. Not fixed by making the probe's dependency optional: the probe must stay buildable by a plain `cargo build`, and a feature that has to be remembered before it compiles is a worse trade than a job that cannot be forgotten. **The design note's stated reason for keeping the probe out of CI was false**, and it was the load-bearing half. It said the job "runs `cargo run` without `--release`" -- but `probe-doorbell-cost` and `probe-request-cost` already run there WITH `--release`, under a comment establishing the very rule this probe would fall under. It also said "unlike every other probe", and `probe-cancel-io` is likewise absent. And it said the run "costs about two minutes" against the 64.8s this PR's own commit message reports. The decision is unchanged and still right; the argument for it was wrong. Rewritten around what is true -- core count and wall time -- with the release requirement kept as a constraint on HOW it runs rather than as a reason to exclude it. Re-measured: 60.2s. **Two prose defects, both mine and both the same class as ones this PR already fixed elsewhere.** The module doc still named `CHECKLIST-io-domains.md`, a file in no branch -- I swept the design notes for dangling links and did not sweep the source beside them. And three sites named `mpsc`, a module the queue crate does not have; it is `slotwise_mpsc`, which is what the probe measures and labels. That is residue of exactly the rename this probe's own comments record as having caused one silent failure already. Re-ran the probe after changing its output text rather than assuming: exit 0, 60.2s, 181 lines, and the reworded passage renders as intended. Swept every path-shaped `.md`/`.rs` reference in the PR's files for resolvability: zero unresolvable. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
🟡 Changes recommended
Unresolved critical and moderate findings remain around target support, timing synchronization, and measurement safeguards.
Get a fresh assessment by requesting another Copilot review.
Review details
Suppressed comments (5)
Previously missed (1) — in code that hasn't changed since the last review.
crates/windows-platform-probes/DESIGN-NOTES.md:537
- The heading and opening count are stale relative to the replacement results later in this same note: the shipping-type section reports 3.83x/3.99x at 16/32 producers and the probe now measures four layouts, including 8/56. Leaving
2-3xandThree apportionmentshere makes the canonical heading present the superseded stand-in result as current; update this opening to the final result or label the old block as historical.
crates/windows-platform-probes/src/bin/queue_contention.rs:16
- The PR's measurement notes state that debug timings make the relevant queue shapes look equivalent, but this entry point accepts a normal debug
cargo runand emits an authoritative-looking report. Add a release-build guard before measuring so a manual invocation cannot produce numbers that are used for the queue decision despite being known-invalid.
fn main() {
crates/windows-platform-probes/src/lib.rs:151
- The crate-level “What each probe establishes” table enumerates the probe functions, but the new
queue_contention::measurebinary-only probe is not added to it. The public crate documentation therefore omits this new probe and its claim, leaving the inventory stale. Add a row for it alongside the other binary-only probes.
pub mod queue_contention;
crates/windows-platform-probes/src/queue_contention.rs:245
- This warm-up calls
timer, but every timer call allocates and drops its own queue. The untimed pass therefore does not pre-touch the backing storage used by any timed repetition; first-use page faults or initialization can still occur afterInstant::now(), contrary to the comment and making the reported time depend on allocator/page reuse. Reuse the allocation being timed or explicitly pre-touch that allocation before starting the clock.
// One untimed pass first: the first touch of a fresh allocation faults
// pages in, and that cost belongs to the allocator rather than the queue.
let _ = timer(producers);
let mut results: Vec<Repetition> = (0..REPETITIONS).map(|_| timer(producers)).collect();
crates/windows-platform-probes/src/queue_contention.rs:406
- This barrier only proves that the consumer reached
wait(), not that it has entered the drain loop. After release, the scheduler can run producers long enough to fill the 1024-slot queue before the consumer executespop; that startup delay and its refusals are then included in the supposedly continuously-drained timing. Add a consumer-ready handshake before releasing and timing the producers, and apply the same synchronization to the other drained variants.
let gate = start_barrier(producers + 1);
- Files reviewed: 6/7 changed files
- Comments generated: 2
- Review effort level: Lite
There was a problem hiding this comment.
🔵 Needs a closer look
It has unresolved portability, timing-correctness, documentation, and rationale issues.
Review details
Suppressed comments (7)
.github/workflows/ci.yml:510
- The PR description still says the probe is excluded because the CI probe job runs
cargo runwithout--release, but this workflow already runs the timing probes with--releaseat lines 317-324. The new design note also identifies that premise as false; please update the description to the actual reasons for exclusion (host core count and runtime) so the stated rationale matches the workflow.
# **This job exists because adding `probe-queue-contention` took the default
# configuration away from every other job.** That probe needs `dwcas` and
# `experimental-permit-claim`, and enabling them on a workspace member
# unifies them across the whole workspace -- so the `--workspace` steps that
# deliberately omit `--all-features` stopped being a default-features build
crates/windows-platform-probes/Cargo.toml:158
- This normal dependency enables
dwcasfor every Windows build ofwindows-platform-probes, soreserving_mpsc::Wideandportable_atomic::AtomicU128are compiled even when the probe is built for a target without native double-width CAS. The queue crate's owndwcasdocumentation records thatAtomicU128is unavailable on i686 withdefault-features = false, so a normalcargo build -p windows-platform-probesloses the Windows-wide buildability this crate otherwise has. Keep the wide experiment x64-only (for example, target-gate the probe/dependency or split the binary) while leaving the ordinary probe crate buildable on other Windows targets.
windows-waitable-queues = { path = "../windows-waitable-queues", features = [
"experimental-permit-claim",
# So the probe can instantiate the 128-bit layout. The 64-bit ones need no
# feature; this is the only one that costs the queue crate a dependency.
"dwcas",
crates/windows-platform-probes/DESIGN-NOTES.md:650
CW-1.6is still an unresolvable work-item reference: it has no definition elsewhere in this checkout, while the preceding section explicitly says the queue checklists are not present yet. This leaves the provenance of the deletion unavailable to readers; either link the eventual checklist when it lands or state the current fact without the missing item ID.
`CW-1.6` deleted the duplicated protocol in this crate once
`windows-waitable-queues` took the layout as a parameter, so the probe now
instantiates the real type at each layout. The numbers below supersede the ones
above, which were taken from the stand-in.
crates/windows-platform-probes/DESIGN-NOTES.md:533
- The heading still presents the old stand-in result as the current decision, even though the later section says the shipping-type measurements supersede it and reports a 3.83-3.99x wide-word cost at 16-32 producers. Mark this section explicitly as historical (or update/remove the stale title), otherwise readers can stop here and carry forward the obsolete 2-3x conclusion.
## The claim word's width costs 2-3x in isolation and much less in use
crates/windows-platform-probes/src/bin/queue_contention.rs:186
- The report hard-codes
cmpxchg16b, butWideis backed byportable-atomicand this binary is not restricted to x86_64. Onaarch64-pc-windows-msvcthe same 128-bit operation uses the ARM atomic sequence (ldxp/stxp), so running the probe there would attach the wrong instruction to the measurement. Make the description target-dependent or describe it generically instead of presenting an x86-specific name as universal.
" apportioned differently; 64/64 is a u128 exchange (cmpxchg16b)."
crates/windows-platform-probes/src/lib.rs:151
- The crate-level
# What each probe establishestable is the inventory for this crate and currently ends atrequest_cost::measure; adding the publicqueue_contentionmodule without a row leaves the new instrument undiscoverable in the API documentation and omits its binary-only/release-only constraints. Add aqueue_contention::measureentry describing the two measured regimes.
pub mod queue_contention;
crates/windows-platform-probes/src/queue_contention.rs:308
Barrier::wait()only releases the parties; it does not make the followingInstant::now()atomic with that release. Every caller returns the workers from this barrier and only then takes the timestamp, so a worker can execute an arbitrary prefix of its loop before timing starts, biasing the producer-count curves (especially when the main thread is descheduled). Use a second start barrier/flag so the timestamp is established before workers can enter the timed loop.
/// The count includes this thread: the workers arrive and block, this thread
/// arrives last, and the clock starts as the barrier releases them together.
fn start_barrier(participants: usize) -> Arc<Barrier> {
Arc::new(Barrier::new(participants + 1))
- Files reviewed: 6/7 changed files
- Comments generated: 0 new
- Review effort level: Lite
… a spin on a dead queue
Three findings from a second review of this PR. The first changes the numbers.
**The timing window was wrong at both ends, and the error was not small.** Every
timer released a barrier, called `Instant::now()` on THIS thread, and read
`elapsed()` after `thread::scope` returned:
- `Barrier::wait` releases every party together and this thread is just
another party, so a worker could return from `wait` and run an arbitrary
prefix of its pushes before this thread was scheduled again to read the
clock. That understates the interval, which OVERSTATES throughput -- and it
bites hardest at high producer counts, where this thread is competing with
N busy workers for a core. Which is exactly where the curve is the finding.
- `thread::scope` joins before it returns, so thread exit and join sat inside
the measured interval. That overstates it, and dominates at one producer
where a whole run is only hundreds of microseconds.
Each worker now timestamps itself either side of its own pushes, and the span is
the earliest start to the latest finish. A previous review had explicitly
cleared this, concluding the clock "genuinely starts at release"; it does not.
**Measured, with a control, because a benchmark correction that is not measured
is just a rewrite.** On x86_64 16p/8c, `reserving_mpsc` at sixteen producers:
35.0 ns/push before, 49.8-52.8 after. Two runs of the same build put the
run-to-run spread at 2-6%, so this is signal: the probe was reporting roughly
45% more throughput than the producers actually achieved, at the producer counts
the decision turns on. The one-producer rows moved the other way and slightly
(2.4 -> 2.3, 6.5 -> 6.0), which is the join overhead leaving the window.
The four figures recorded in DESIGN-NOTES predate this and are now marked as
such rather than quietly left standing. The qualitative finding they support --
a debug build swamps the effect -- is unaffected.
**A dead queue was retried forever.** The drained producers looped on every
`PushError`, but only `Full` is retryable; the queue crate's own documentation
says "retrying the first is sensible and retrying the second is a spin". If the
consumer panicked and dropped the receiver, every producer would spin
indefinitely, and because the consumer is joined only after the producer scope
completes, the panic could never surface -- the probe would hang rather than
fail. All four loops now assert `is_retryable()` first. Joining the producers
inside the scope, which the timing fix required anyway, means a producer panic
now surfaces too.
**The isolated regime does not isolate the compare-and-swap**, and both the
module doc and the design note said it did: "whatever curve appears against N is
the compare-and-swap and nothing else". What is timed is each shape's whole push
path -- tail claim, slot-sequence load, item write, publication store, doorbell
fence -- and `permit_mpsc` takes two shared read-modify-writes where the others
take one. A difference here is a difference in push cost. Narrowed to that.
Gate: fmt, clippy --all-targets, 236 lib + 12 integration, and the probe run end
to end (exit 0, 63.6s and 64.8s across two runs).
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
🟡 Changes recommended
Moderate issues remain around target support, drained-regime synchronization, report validation, and platform-correct output.
Get a fresh assessment by requesting another Copilot review.
Review details
Suppressed comments (9)
crates/windows-platform-probes/Cargo.toml:158
- Enabling
dwcasunconditionally makes this package fail to build fori686-pc-windows-msvc:queue_contention.rsimports and instantiatesWide, but the queue crate'sAtomicU128implementation is unavailable on i686. The queue crate explicitly preserves i686 support, and this probe is not target-gated, so a workspace check for that supported target now breaks. Gate the wide rows and dependency feature on targets with 128-bit atomics, or explicitly exclude this probe from unsupported targets.
windows-waitable-queues = { path = "../windows-waitable-queues", features = [
"experimental-permit-claim",
# So the probe can instantiate the 128-bit layout. The 64-bit ones need no
# feature; this is the only one that costs the queue crate a dependency.
"dwcas",
crates/windows-platform-probes/DESIGN-NOTES.md:545
- This heading is stale relative to the re-measured shipping-type results later in the same section: lines 669-670 report 3.83x and 3.99x at 16 and 32 producers, and explicitly supersede the earlier 2.37x/2.99x figures. Leaving "2-3x" in the heading makes the current design note contradict its own authoritative table.
## The claim word's width costs 2-3x in isolation and much less in use
crates/windows-platform-probes/DESIGN-NOTES.md:545
- The later "Re-measured on the shipping type" section explicitly says that its numbers supersede this section, but this heading has no adjacent superseded-status marker. Add the required marker immediately below the heading so readers do not mistake the earlier 2-3x table and conclusions for the current measurement.
## The claim word's width costs 2-3x in isolation and much less in use
crates/windows-platform-probes/src/bin/queue_contention.rs:186
- The report hard-codes
cmpxchg16b, but this binary is not x86_64-only; the sameWidelayout is available on ARM64, where the exchange usesldxp/stxp. Running the probe there therefore emits an incorrect instruction description. Use a target-neutral description or select the instruction name with target-specific code.
" apportioned differently; 64/64 is a u128 exchange (cmpxchg16b)."
crates/windows-platform-probes/src/bin/queue_contention.rs:114
- These lookups intentionally turn a missing row into
Noneand then into--, so a wiring regression can produce a plausible report with an absent column. The new probe has no deterministic test for the expected shape/producer matrix or ratio rows, even though its module documentation calls out this exact rename failure mode. Add a syntheticObservation/renderer test in a sibling test module that asserts every expected row is present.
let plain = observation.find(&observation.drained, shapes::SLOTWISE_MPSC, producers);
let reserving = observation.find(&observation.drained, shapes::RESERVING_MPSC, producers);
let permit = observation.find(&observation.drained, shapes::PERMIT_MPSC, producers);
let ratio = format_ratio(reserving, plain);
crates/windows-platform-probes/src/lib.rs:151
- The crate-level
What each probe establishesinventory has no entry for the newly registeredqueue_contentionmodule. Because this probe is binary-only and deliberately omitted from CI, leaving it out makes the public crate documentation an incomplete inventory and hides the claim this instrument supports. Add aqueue_contentionrow with its binary-only tier and measurement claim.
pub mod queue_contention;
crates/windows-platform-probes/src/queue_contention.rs:558
- This second drained setup has the same readiness gap: the barrier releases the consumer and producers together, but does not ensure the consumer has executed a pop before producer timers begin. Consequently this row can measure startup scheduling as well as the intended head contention. Use an explicit consumer-ready handshake before starting the producers.
let gate = start_barrier(producers + 1);
let consumer_gate = Arc::clone(&gate);
let consumer = thread::spawn(move || {
consumer_gate.wait();
while !consumer_done.load(Ordering::Relaxed) {
crates/windows-platform-probes/src/queue_contention.rs:623
- The barrier does not establish that the permit consumer is actually draining when the producers start; it only establishes that all parties reached the barrier. A producer can run and fill/refuse against the queue before the consumer's first
pop, so the measured cost includes an uncontrolled startup phase. Add a consumer-ready handshake before the timed producer work.
let gate = start_barrier(producers + 1);
let consumer_gate = Arc::clone(&gate);
let consumer = thread::spawn(move || {
consumer_gate.wait();
while !consumer_done.load(Ordering::Relaxed) {
crates/windows-platform-probes/src/queue_contention.rs:731
- This layout-specific drained row also releases the consumer and producers simultaneously, without proving that the consumer has started its drain loop. The resulting initial backlog/refusals depend on scheduling and can bias the layout comparison. Gate producer timing on an explicit consumer-ready signal instead of using this barrier as a readiness guarantee.
let gate = start_barrier(producers + 1);
let consumer_gate = Arc::clone(&gate);
let consumer = thread::spawn(move || {
consumer_gate.wait();
while !consumer_done.load(Ordering::Relaxed) {
- Files reviewed: 6/7 changed files
- Comments generated: 2
- Review effort level: Lite
The queue-contention section said the u64 re-apportionments "track the default within noise", so twenty years of counter headroom was "free". The table directly beneath it showed 1.21x and 1.13x against a noise floor the same file put at 2-6% -- the prose contradicted its own evidence in adjacent lines. Re-measured seven times on x86_64 16p/8c after the timing correction in d49a71f, which the original figures predate. Two findings: - The 2-6% floor was obtained by comparing two runs, which cannot measure a spread. Seven runs put the same-configuration spread at 7-61%. - The probe already emits its own control: `reserving_mpsc` and `reserving(32/32)` are the same code at the same layout, measured twice per run, so their ratio is an empirical "no difference" -- 0.68-1.27x. That is a derived control rather than an asserted floor. Against that control the 128-bit word separates decisively (3.45x/3.81x at 16/32 producers) and the u64 re-apportionments do not. The claim is withdrawn in BOTH directions rather than inverted: 1.23-1.30x against a control reaching 1.12x, on one host, is a flag to measure locally, not a cost. Swept the class rather than the reported line: the same claim appeared three times (the stand-in section, the headroom section's "at no measured cost", and the re-measured section). All three corrected. Records D-observations-not-verdicts: figures are published with their capture parameters, and fine-grained layout choices belong to the client. Windows exposes no NUMA distance table, so the processor-to-node assignment in the banner is the analog used in its place; the measurement host's `numa[16]` is a single domain, so these figures say nothing about cross-domain behaviour. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…dance The withdrawn claim had propagated out of the probe's design note into this crate's consumer-facing documentation, where it told callers that `Perpetual` buys twenty years of headroom "at no measured cost". Three restatements plus the decision they derive from: - README.md, the "What to do about it" bullet - src/lib.rs, the same text as public rustdoc on docs.rs - README.md, the "Start here" chooser - DESIGN-NOTES.md D-41, "measured indistinguishable outside noise" The recurrence arithmetic is unaffected -- time-to-wrap follows from the field width and a rate, not from a throughput measurement -- so the recommendation stands. What is removed is the unsupported claim about what it costs to run. Re-measured, the deeper layouts are indistinguishable from `Balanced` up to eight producers and near 1.26x at sixteen and thirty-two, against a same-code control reaching 1.12x, on a single host. This is CONTRACT INTEGRITY rule 3: the reported site was a sample, not the population, and a correction to a shipped rule obliges a re-check of what was written against the old one. Verified: 13 doctests pass, including the compiled README. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
🟡 Changes recommended
Unresolved moderate findings affect measurement reporting, probe discoverability, and helper-test coverage.
Get a fresh assessment by requesting another Copilot review.
Review details
Suppressed comments (6)
crates/windows-platform-probes/DESIGN-NOTES.md:782
- The table immediately above is unlabeled, but it contains the 64/64 ratios 1.37x, 3.45x, and 3.81x at 1, 16, and 32 producers, while this sentence says the drained 128-bit word stays inside the control band. As written, the note either contradicts its table or omits the drained table needed to support the claim; label the table's regime and correct the conclusion to match the actual measurements.
In the drained regime nothing separates at all -- every u64 layout *and* the
128-bit word sit inside the control band at every producer count (the widest
median is 1.13x at one producer, against a control that reaches 1.27x).
crates/windows-platform-probes/DESIGN-NOTES.md:746
- These capture details are not emitted by the new binary: it runs five repetitions and reports only the median, does not retain or print the observed range, and prints no release/debug marker. Because this probe is intentionally manual rather than CI-gated, stdout is the measurement record; add those fields to the observation/report or revise this promise before relying on the ratios.
Seven runs, median of the per-run ratios with the observed range beside it,
release build. **The banner's `numa[16]` is load-bearing here: it means a single
NUMA node holding all sixteen processors**, so every figure below was taken
crates/windows-platform-probes/src/bin/queue_contention.rs:50
- This label duplicates
DRAINED_CAPACITYfrom the measurement module. If the benchmark capacity changes, execution will use the new value while the captured report still sayscapacity 1024, making the observation self-contradictory; share/export the constant (or expose it through the observation) and interpolate it here.
"\n-- drained: a consumer popping continuously, capacity 1024 --"
crates/windows-platform-probes/src/bin/queue_contention.rs:57
- This heading overstates what the measurement isolates.
scalingis computed fromRun.pushes_per_second, and each timed run includes slot-sequence loads, the item write, publication, and the doorbell fence, as the module documentation notes; it is not a tail-CAS-only measurement. Rename the heading to describe producer push-path scaling/contended push cost so readers do not attribute the whole curve to the tail claim.
let _ = writeln!(out, " 1. tail-claim contention (isolated regime)\n");
crates/windows-platform-probes/src/lib.rs:151
- Please add
queue_contention::measureto theWhat each probe establishestable above. That table is the crate's canonical inventory of probe tiers and claims (src/lib.rs:110-136), but the new module is currently only exported below, so this binary-only probe is undiscoverable in the documented inventory.
pub mod queue_contention;
crates/windows-platform-probes/src/queue_contention.rs:167
- The new pure observation helpers have no tests: a missing shape/producer lookup silently becomes
--, and an incorrectscalingcalculation would directly change the conclusions printed by this probe. Add sibling unit tests forfindandscaling(including missing and one-producer cases) without invoking the long host measurement; the repository already keeps focused sibling tests for comparable probe logic.
pub fn scaling(&self, regime: &[Run], shape: &str, producers: usize) -> Option<f64> {
let one = self.find(regime, shape, 1)?;
let many = self.find(regime, shape, producers)?;
Some(many.pushes_per_second / one.pushes_per_second)
- Files reviewed: 10/11 changed files
- Comments generated: 2
- Review effort level: Lite
…not a wider ruler The queue-contention repair derived a noise control from the probe's own output -- `reserving_mpsc` and `reserving(32/32)` are the same code at the same layout, measured twice per run -- and immediately used it to withdraw an unsupported claim. But it then used it only as a yardstick, which quietly promoted a symptom into a tool. Two measurements of identical code in the same run differing by 27%, with same-configuration spread reaching 61%, is first a finding about the METHOD. Recording it as merely a coarser ruler and carrying on is how a methodological problem becomes permanent. Records D-variance-is-a-finding. The candidate causes are not separable from the dispersion itself, so the note refuses to guess among them: wrong instrument for the variable, a residual probe defect (one was already found and fixed in d49a71f, invisible in the numbers and worth ~45%), too few runs or too short a span, or a nanosecond-scale measurement on a shared loaded desktop. The calibration is recorded rather than assumed, because it cuts both ways: a spread this wide would be disqualifying in a benchmark or marketing document, which exist to carry a comparative claim. These figures exist to support planning for deployment environments resembling the measured one -- an ordinary machine under ordinary load -- so the treatment is neither suppression nor promotion. Publish the data, publish the dispersion, and publish that the dispersion is unexplained. Queues M4.2 as a diagnosis item rather than leaving the work in a design note, per "design notes are not a work queue". It names a negative result as a valid outcome that must still be recorded, and forbids resolving it by suppressing the ranges. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
🟡 Changes recommended
Unresolved moderate and nit findings remain in probe reporting, inventory, and documentation.
Get a fresh assessment by requesting another Copilot review.
Review details
Suppressed comments (8)
Previously missed (3) — in code that hasn't changed since the last review.
crates/windows-platform-probes/src/bin/queue_contention.rs:32
- This report includes a host banner, but
fingerprint::banner_line()formats only host identity and does not say whether the binary is debug or release. The probe's documentation shows that debug and release can make the queue shapes look equivalent, so a captured report cannot establish whether its figures were produced under the required profile. Add an explicit build-profile line before the measurements.
crates/windows-waitable-queues/README.md:185 - The earlier README paragraph at lines 142-147 still says deeper positions cost nothing measurable, while this later changed paragraph correctly says the cost is unknown. A reader of this document gets both conclusions; update the earlier statement and the matching API/manifest docs too.
crates/windows-waitable-queues/src/lib.rs:155 - This new bullet says the throughput cost is not established, but the preceding public module docs at lines 110-116 still say that a deeper position costs nothing measurable; the same stale claim remains in
reserving_mpsc.rs:186-188andCargo.toml:60-62. That leaves the published API guidance contradictory, so update all of those restatements in the same change.
crates/windows-platform-probes/DESIGN-NOTES.md:620
- The PR description still says the existing probe job runs
cargo runwithout--release, but the workflow already runs the nanosecond probes in release at.github/workflows/ci.yml:317-324. This paragraph correctly attributes exclusion to core count and runtime; align the PR description with that reason so release is not reported as the job-wide blocker.
**That is a constraint on HOW it runs, not an argument for keeping it out**, and an earlier draft of this
paragraph confused the two -- it said the CI job "runs `cargo run` without `--release`", which is not true
of the job it describes: `probe-doorbell-cost` and `probe-request-cost` already run there with `--release`,
under a comment establishing exactly the rule this probe would fall under. It also said "unlike every other
probe", and `probe-cancel-io` is likewise absent. Corrected by a review. The release precedent exists; what
keeps this one out is that it costs an order of magnitude more than the two probes that use it, on hardware
that cannot answer the question anyway.
crates/windows-platform-probes/DESIGN-NOTES.md:688
- This subsection still presents
cmpxchg16bas 2-3x in isolation and 5-12% in the drained regime, but the shipping-type remeasurement below reports 3.45-3.81x isolated at 16/32 producers and says all layouts fall within the control band when drained. The later section says it supersedes these numbers; mark this heading/conclusion as historical or move it to the rationale so the current design note does not expose two incompatible conclusions.
**Widening the word is not free, and how much it costs depends entirely on the
regime.** Isolated, where the claim is the only thing happening, `cmpxchg16b`
costs 2-3x and the penalty *grows* with contention. Drained, with a consumer
running, it is 5-12%. This is the one conclusion in this section that the
seven-run re-measurement strengthened rather than withdrew.
crates/windows-platform-probes/src/bin/queue_contention.rs:50
DRAINED_CAPACITYis defined as 1024 in the library, but this report repeats 1024 as a string literal. If the benchmark capacity changes, the output will describe the wrong regime, which is especially harmful because refusal counts are interpreted relative to this capacity. Render the heading from the shared constant instead.
"\n-- drained: a consumer popping continuously, capacity 1024 --"
crates/windows-platform-probes/src/lib.rs:151
- The module-level "What each probe establishes" table at
src/lib.rs:110-136is the crate's exhaustive probe inventory, but this addition only declaresqueue_contentionand adds no row forprobe-queue-contention. Add its binary-only tier and supported claim there so the new instrument is discoverable and the inventory remains complete.
pub mod queue_contention;
crates/windows-platform-probes/src/queue_contention.rs:11
- These module docs say the probe exists to force two decisions, but the implementation and renderer also measure and report a third decision about claim-word layout (the output's "Question 3"). Update the module-level contract to mention that comparison, or explain why it is subordinate to one of the two decisions, so users can reconcile the documented scope with the report.
//! # The two decisions this exists to force
//!
//! **1. Are the linked and sharded MPSC shapes needed at all?** They are parked
- Files reviewed: 11/12 changed files
- Comments generated: 1
- Review effort level: Lite
…ere the floor is Extends D-variance-is-a-finding with the practical half, and re-scopes M4.2 from "diagnose the variance" to "give the probes the controls that make diagnosing it possible" -- the judgement stays with the person, the probe stops being the obstacle. What the note now says: - Gather more of the same before gathering anything different. Lengthening the span and raising the repetition count is the only step that changes nothing about what is measured, so it is the only one whose result is interpretable before the others have been tried. Pinning, quiescing, or altering the probe all move the measurement as well as the noise. - A warmup separates transient cost from ongoing noise. Recorded with the objection it invites: if noise were inherent, warming could not remove it. It does not -- warming removes front-loaded transients (page faults, cold caches, frequency ramp) while tenant contention runs for the whole measurement. So warming uncovers the inherent floor rather than hiding it, and the expected signature is a spread that narrows and then plateaus. - There is always a floor, and recognising it is the skill. Past it more runs buy nothing. - The floor is NOT necessarily a fraction of the measured value. It can be set by the sampling regime -- clock granularity, independent sample count, how the span is built. This probe takes two timestamps per worker per repetition, so what limits resolution at small values is the pass count, not a percentage of the nanoseconds printed. The two readings prescribe opposite actions, which is why "small numbers are just noisy" is a guess and not a diagnosis. M4.2's software scope, verified against the source: PUSHES_PER_PRODUCER (50_000) and REPETITIONS (5) are private consts and measure() takes no arguments, so the prescribed first move currently requires a source edit and a rebuild. Defaults must not change, and whatever settings a run used have to be reported beside the host banner -- they are capture parameters now, per D-observations-not-verdicts. Note the warmup is partly present already: one untimed pass exists, but only to fault in the allocation's pages. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…meters This PR added D-observations-not-verdicts, which requires every published figure to carry the parameters of its capture, and then published figures missing two of them. The block recorded the host banner, the build profile, and "seven runs" -- but not what a run consists of. Each run is a whole probe invocation, within which every configuration is measured REPETITIONS (5) times and the median reported, each measurement being PUSHES_PER_PRODUCER (50,000) pushes per producer thread, preceded by one untimed pass that faults in the fresh allocation's pages. So each published figure rests on 35 timed passes per configuration, and "seven runs" alone does not let anyone reproduce it. Also names where the two constants live and points at M4.2, which makes them adjustable -- the note now prescribes lengthening the span and raising the repetition count as the first response to a wide control, and the probe cannot currently do either without a source edit. Recording the gap is what this PR owes; closing it is follow-up. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Six sites said the reservation-count field is what limits `Enduring` and
`Perpetual`, full stop. It is not. The achievable count is the lesser of the
queue's capacity and the field ceiling, so a `Perpetual` queue of capacity 64
admits 64 reservations rather than 255 -- and the README's own worked example
uses exactly that capacity, so it stood as a counterexample to the sentence three
paragraphs above it.
The crate had this right where it was tested and wrong where it was described.
An earlier sabotage on this branch already demonstrated it: the same test that
fills Perpetual to 255 at capacity 1024 stops at 128 when the capacity is 128.
The evidence was in the branch and the prose contradicted it.
Corrected in the README, the crate rustdoc, `ClaimLayout`'s table note, the
`Balanced` comparison, and both the `Enduring` and `Perpetual` type docs, which
said "Holds 65,535" and "Holds 255" as though every instance could.
Three corrections in the root design note, all to claims about its own analysis
rather than about the code:
- "validate the first three rows" named an ordinal position; the table's second
row is a time row, so the sentence contradicted the one before it. Named the
three rows instead of counting them.
- "converting 19 hand-written 255s into checked derivations" overstated the
proposed check: the 19 spans all five figures and includes prose occurrences
a table parser never sees. Now says it reaches the tabular occurrences and
only those.
- the note pointed at `M30` in the root checklist, which does not exist on this
branch -- it is queued on another. Removing the branch-status qualifier last
round for durability turned a stale reference into a broken one. The note now
says a survey is queued separately without naming an ID it cannot resolve.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Sweep of outstanding review feedback, and the response to itI scanned every Copilot review on this PR rather than only the ones surfaced to me, and found three review rounds I had never seen — Everything below is now addressed in The unresolved thread:
|
This PR adds the rule that a number belongs in one place and prose should carry the claim. The section stating it opened with a prose-to-code ratio, three workspace line counts and a five-row census table, all hand-maintained and none reproducible. It was a counterexample to itself, which a review said plainly. It had also already failed twice. The table drifted within days when a rustdoc qualifier added an occurrence -- recorded in a parenthetical rather than fixed -- and re-running the census while making this change shows the ceiling at 22 occurrences where the table says 19, because corrections landed in this same session. A census of restatements had become a restatement needing maintenance. Now qualitative, with the command that computes the counts. A reader gets current numbers instead of a snapshot of someone else's, which is what 'let findings be findings computed directly' means when applied to this section rather than only recommended by it. The command was run before committing. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
🔵 Needs a closer look
Unresolved renderer validation and duplicated benchmark provenance concerns remain.
Review details
Suppressed comments (8)
Previously missed (1) — in code that hasn't changed since the last review.
DESIGN-NOTES.md:1877
- These workspace line counts and restatement counts are the quantitative evidence for this decision, but no committed capture, command, or provenance is provided. A later recount cannot be verified or detected, recreating the hand-transcription problem this note identifies; please add a checked-in capture/provenance or state the conclusion qualitatively without these digits.
DESIGN-NOTES.md:1932
- D-31 says the queue ships without machine-checked memory orderings and that model checking is planned; this repository has no TLA+ or loom run producing a result. The preceding section correctly says the absence of findings is because no instrument exists, so saying these tools “have produced no findings” turns an unmeasured property into a result. Please describe them as planned/not run and keep the absence of evidence explicit.
- **Policy** -- client prescriptions surviving [D-no-client-prescriptions](crates/windows-platform-probes/DESIGN-NOTES.md#d-no-client-prescriptions).
Only a reviewer catches these.
- **Algorithm properties** -- **zero findings, in any round.**
DESIGN-NOTES.md:1978
- A digit-free prose claim can still drift from its measurement: if the artifact or host data changes, “measured faster” can become stale while containing no numbers, and a reader cannot see that without checking the artifact. This should say that prose reduces transcription drift, not that it cannot drift.
README and the crate rustdoc disagreeing because one was retaken; an attribution naming a capture
the figures no longer came from; one recurrence horizon left unqualified across seven sites in three
wordings; a withdrawn magnitude surviving in two public rustdocs. The most instructive was a
proportion that restated two counts **given four words earlier in the same sentence** and got one of
crates/windows-platform-probes/src/queue_contention.rs:350
- The guard here only checks the denominator. Because
Runfields and this renderer are public, a caller can pass aRunwhose numerator or span containsNaN/inf; this then formats asNaNx/infx(and possiblyNaNbounds) instead of the non-finite-safe--output used byformat_scaling. Please make the ratio path reject non-finite values consistently, including the span values used byratio_bounds, and add a regression test for a non-finite numerator.
pub fn format_ratio_bounded(numerator: Option<Run>, denominator: Option<Run>) -> String {
match (numerator, denominator) {
(Some(numerator), Some(denominator)) if denominator.nanos_per_op > 0.0 => {
let point = numerator.nanos_per_op / denominator.nanos_per_op;
match ratio_bounds(numerator, denominator) {
crates/windows-platform-probes/src/queue_contention.rs:432
- The same denominator-only check leaves this public helper able to emit
NaNxorinfxwhen a caller constructs aRunwith a non-finite numerator. That is especially inconsistent with the new renderer contract, which explicitly maps non-finite scaling values to--; please apply the same finite-input policy here and cover it in the renderer tests.
pub fn format_ratio(numerator: Option<Run>, denominator: Option<Run>) -> String {
match (numerator, denominator) {
(Some(numerator), Some(denominator)) if denominator.nanos_per_op > 0.0 => {
format!("{:.2}x", numerator.nanos_per_op / denominator.nanos_per_op)
}
crates/windows-waitable-queues/README.md:413
- This table is a second hand-maintained copy of the same fecd352 capture that is also embedded in the crate rustdoc (
src/lib.rs). Because neither copy is generated from a single data artifact, a later retake can update one table and leave the other publishing stale values—the exact transcription drift this PR documents. Please make one capture/table canonical and derive or otherwise mechanically validate the other.
**What was measured**, in ns per operation, isolated regime (producers only,
capacity large enough that nothing is refused). Each cell is the median of three
whole-probe runs, followed by the full range across all fifteen repetitions those
runs contain. An operation is one successful push for the three queue shapes;
for `baseline_fetch_add` it is one `fetch_add`, which is why the column is
labelled per operation rather than per push:
| producers | `slotwise_mpsc` | `reserving_mpsc` | `permit_mpsc` | `baseline_fetch_add` |
|---|---|---|---|---|
| 1 | 6.3 (6.3-7.5) | 5.4 (5.4-6.4) | 7.9 (7.9-8.3) | 2.3 (2.3-2.7) |
| 2 | 50.6 (19.3-59.5) | 31.9 (22.5-35.2) | 44.2 (37.4-45.9) | 12.1 (5.8-14.3) |
| 4 | 91.6 (89.7-99.9) | 37.2 (31.6-41.5) | 31.8 (30.4-32.9) | 13.8 (12.6-17.6) |
| 8 | 138.6 (126.9-157.6) | 37.8 (34.3-41.7) | 25.9 (25.0-27.4) | 14.7 (13.9-15.9) |
| 16 | 218.0 (188.9-272.7) | 47.9 (44.9-56.0) | 21.8 (20.9-25.6) | 14.8 (14.4-15.9) |
| 32 | 224.7 (131.4-268.3) | 51.3 (40.7-55.4) | 21.9 (20.7-39.0) | 15.0 (14.7-15.7) |
crates/windows-waitable-queues/src/lib.rs:343
- This rustdoc table duplicates the same fecd352 capture maintained separately in
README.md, so the two public surfaces can silently diverge on the next measurement retake. Please make one capture/table canonical and derive or mechanically validate the other instead of keeping two numeric copies by hand.
//! | producers | `slotwise_mpsc` | `reserving_mpsc` | `permit_mpsc` | `baseline_fetch_add` |
//! |---|---|---|---|---|
//! | 1 | 6.3 (6.3-7.5) | 5.4 (5.4-6.4) | 7.9 (7.9-8.3) | 2.3 (2.3-2.7) |
//! | 2 | 50.6 (19.3-59.5) | 31.9 (22.5-35.2) | 44.2 (37.4-45.9) | 12.1 (5.8-14.3) |
//! | 4 | 91.6 (89.7-99.9) | 37.2 (31.6-41.5) | 31.8 (30.4-32.9) | 13.8 (12.6-17.6) |
//! | 8 | 138.6 (126.9-157.6) | 37.8 (34.3-41.7) | 25.9 (25.0-27.4) | 14.7 (13.9-15.9) |
//! | 16 | 218.0 (188.9-272.7) | 47.9 (44.9-56.0) | 21.8 (20.9-25.6) | 14.8 (14.4-15.9) |
//! | 32 | 224.7 (131.4-268.3) | 51.3 (40.7-55.4) | 21.9 (20.7-39.0) | 15.0 (14.7-15.7) |
crates/windows-waitable-queues/src/reserving_mpsc.rs:263
- This public
ClaimLayoutrustdoc still publishes the exact1.23-1.30xand1.12xmeasurements without the host, run count, dispersion, or a capture link. That conflicts with the probe's ownD-observations-not-verdictsrequirement that every published figure carry its sampling context, and makes these numbers another unattributed copy even though the surrounding text correctly withdraws the performance conclusion. Please remove the figures from this API documentation or attach the same provenance as the attributed probe results.
/// slower. **What that costs in throughput is not established**: a probe
/// comparing them found them indistinguishable at low producer counts, and at high counts ran 1.23-1.30x the default against a same-code control that itself reaches 1.12x -- outside the control, but too close to it to establish an ordering or a cost on this host. The settled trade is the
/// reservation ceiling; throughput is target-dependent and this crate does not
/// characterise it beyond the one host in the note above.
- Files reviewed: 21/22 changed files
- Comments generated: 0 new
- Review effort level: Lite
There was a problem hiding this comment.
🔵 Needs a closer look
Unresolved documentation claims still describe a finite 2^64 horizon as unreachable and retain an unqualified performance recommendation.
Review details
Suppressed comments (4)
crates/windows-waitable-queues/README.md:133
- The table makes
2^64pushes look unreachable even though this column is explicitly computed from a finite sustained rate. At the stated 116 million pushes/second, this is about 5,000 years; please publish the finite practical horizon rather than an absolute impossibility claim.
| `Wide` (needs `dwcas`) | 4,294,967,295 | 2^64 | unreachable |
crates/windows-waitable-queues/src/lib.rs:102
- This compiled copy of the layout table repeats the unsupported
unreachablevalue for a finite2^64position. The surrounding text says the horizon is arithmetic at 116 million pushes/second, which is roughly 5,000 years; please keep this public rustdoc consistent with the README and describe it as a practical, rate-dependent horizon.
//! | `Wide` (needs `dwcas`) | 4,294,967,295 | 2^64 | unreachable |
crates/windows-waitable-queues/src/reserving_mpsc.rs:37
2^64is a finite position bound, so saying no deployment reaches it is stronger than the arithmetic documented immediately below and is not portable across sustained rates or deployment lifetimes. Please describe this as a practical horizon that depends on the caller's rate.
//! the recurrence to 2^64 pushes, which no deployment reaches.
crates/windows-waitable-queues/src/reserving_mpsc.rs:70
- The public rustdoc still ends with
slotwise_mpscbeing for a caller who wants the “cheapest possible push” (lines 97-99). That remains an unqualified performance recommendation, even though this updated paragraph says the complete-path measurement foundreserving_mpscfaster on the tested hosts and the crate documentation deliberately avoids choosing a winner. Please remove or qualify that stale prescription as an unmeasured design trade-off so the withdrawn claim is not still published through this module’s API docs.
//! **What that read costs is not established, and this comparison cannot
//! establish it.** This shape measured *faster* than `slotwise_mpsc` under
//! contention on the hosts tried -- an end-to-end result over the complete push
//! path, in which the consumer-position read is one term among the protocol,
//! metadata and retry costs and is not separated from them. So the honest
//! statement is that the extra read did not stop this shape being the faster of
//! the two here; it is **not** that the read is cheap, nor that it is "not what
- Files reviewed: 21/22 changed files
- Comments generated: 0 new
- Review effort level: Lite
Seven sites called `Wide`'s recurrence unreachable, or said no deployment reaches it -- two as the table cell "unreachable", five as prose. The column those cells sit in is explicitly arithmetic over a finite rate, and the rows beside them read 37 seconds, 28 days and 20 years. Computed at the same rate the table documents, 2^64 pushes is about 5,000 years. So the crate published an absolute claim in a column of finite arithmetic, three cells away from the arithmetic that contradicts it. All seven now give the figure, and say it is a longer horizon rather than the absence of one, moving with the caller's rate like every other entry in that column. Verified by computing all four rows: 2^32 gives 37 seconds and 2^56 gives 19.7 years, which match what was already published, so the rate model is the same one. This is the table-cell form of a claim already withdrawn twice in this branch as prose -- "Wide removes it" went through the same correction rounds ago. A cell is a restatement like any other and the sweeps that fixed the sentences did not reach it, because a one-word cell does not read like a claim. The module docs also still said `slotwise_mpsc` is "for a caller who wants the cheapest possible push". That asserts a cost ordering this crate does not establish and that its own end-to-end measurement did not find -- the same measurement whose causal reading was withdrawn earlier in this branch. The two shapes are now distinguished by what each offers rather than by which is quicker, with the withdrawn phrasing recorded rather than silently dropped. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Response to this round (4 suppressed findings)Addressed in
|
| position | pushes to recurrence | at the documented rate |
|---|---|---|
| 32 bits | 2^32 | 37 seconds |
| 48 bits | 2^48 | 28 days |
| 56 bits | 2^56 | 19.7 years |
| 64 bits | 2^64 | ~5,039 years |
I computed all four rather than just the disputed one, because the first three matching what was already published is what confirms the rate model is the same one — the fourth figure is only trustworthy if the arithmetic reproduces the others.
So the crate published an absolute claim inside a column of finite arithmetic. All seven sites now give the figure and say it is a longer horizon rather than the absence of one, scaling with the caller's rate like every other entry.
Two of the seven were table cells reading unreachable. That matters beyond the count: this is the cell form of a claim already withdrawn twice in this branch as prose — "Wide removes it" went through exactly this correction rounds ago. The sweeps that fixed the sentences did not reach the cells, because a one-word cell does not read like a claim. Worth naming: my instruments scan for sentences.
slotwise_mpsc "for a caller who wants the cheapest possible push"
Changed. Correct — that asserts a cost ordering this crate does not establish, and that its own end-to-end measurement did not find. It is also a survivor of the same withdrawal: the causal reading of that comparison was retracted earlier in this branch, and this sentence was the conclusion left standing after its premise went.
The two shapes are now distinguished by what each offers — one for a caller who can treat refusal as backpressure, one for a caller with a message it must not lose — rather than by which is quicker. The withdrawn phrasing is recorded rather than silently dropped.
What the round taught
A table cell is a restatement, and it does not look like one. Every instrument I have built in this PR searches prose: flattened multi-line regexes, claim-based rather than phrasing-based, swept across .rs, .md and .toml. All of them walk straight past | unreachable |, because a cell has no verb, no hedge, and nothing that reads as an assertion — while being, in this case, the strongest assertion on the page.
There was a problem hiding this comment.
🔵 Needs a closer look
The queue-contention formatting guard and documentation consistency nits remain unresolved.
Review details
Suppressed comments (7)
Previously missed (1) — in code that hasn't changed since the last review.
crates/windows-platform-probes/src/queue_contention.rs:349
- This guard only rejects a zero denominator. If the numerator row is zero (the same failure sentinel used by the formatter tests), this renders
0.00x;ratio_boundscorrectly rejects that span, but the fallback still publishes a numeric ratio that looks measured. Require a positive numerator as well (and cover that case) before formatting the point estimate.
This issue also appears on line 430 of the same file.
DESIGN-NOTES.md:1910
- This paragraph says there are “two time figures,” but the layout tables carry more than two arithmetic horizons (37 seconds, 28 days, 20 years, and the
Wide5,000-year row). The proposed constants-versus-table check should not describe its uncovered set with a count that is already inconsistent with the table; refer to “the time figures” (or enumerate the intended subset precisely).
**All of these are restated by hand with nothing checking them.** Three of those facts -- the
ceiling, the span and the field ceiling -- follow from `ClaimLayout`'s associated constants. The two
time figures follow from a field width *and* an assumed sustained push rate, so a
constants-versus-table check would validate those three outright and the time figures only once the
rate is pinned somewhere single. That distinction bounds what the cheapest remedy below can do -- an
crates/windows-platform-probes/CHECKLIST.md:146
- This completion link introduces another bare date. The repository's timestamp convention requires dates written in tracked documents to be UTC or carry an explicit offset; please include
UTCin the link text (the archive already has the precise completion timestamp).
- [x] **M4.5** -- Emit the dispersion, not just the median. -> [completed 2026-09-15](COMPLETED-CHECKLIST.md#m45)
crates/windows-platform-probes/COMPLETED-CHECKLIST.md:1118
- The new archive group header records only a local calendar date even though the repository requires newly written dates to be UTC or carry an explicit offset. Use the existing completion timestamp, including its offset, in the group heading.
## Moved 2026-09-15 -- M4.5: the probe carries its own dispersion
crates/windows-platform-probes/src/queue_contention.rs:431
- The same sentinel handling is incomplete here: a zero numerator passes this predicate and produces
0.00x, even though the function's contract says an unmeasurable row should render--. The existing test only exercises a zero denominator, so add the numerator check and regression case too.
(Some(numerator), Some(denominator)) if denominator.nanos_per_op > 0.0 => {
format!("{:.2}x", numerator.nanos_per_op / denominator.nanos_per_op)
crates/windows-waitable-queues/README.md:435
- This capture date is written without a timezone, but repository documentation requires dates in tracked files to be UTC or carry an explicit offset so the recorded instant is unambiguous. Please label it as
2026-09-15 UTC(and keep the mirrored rustdoc entry consistent).
| Taken | 2026-09-15 |
crates/windows-waitable-queues/src/lib.rs:356
- The mirrored capture attribution repeats a bare local date. Repository documentation requires dates in tracked files to be UTC or carry an explicit offset; please use the same explicit
UTC/offset form as the README so the two published attributions cannot be interpreted differently.
//! | Taken | 2026-09-15 |
- Files reviewed: 21/22 changed files
- Comments generated: 0 new
- Review effort level: Lite
… a result Both ratio formatters guarded only the denominator, on the reasoning that division is what breaks. Zero is this probe's sentinel for "this shape did not run", and it means that on either side of the division: a zero denominator printed `inf`, which the guard caught, and a zero numerator printed `0.00x`, which nothing caught. The second is the worse of the two and is why this is a fix rather than tidying. `inf` announces itself as broken. `0.00x` reads as a shape that was immeasurably fast -- a plausible number, in a column of measurements, produced by a row that never ran. Both formatters now require a positive numerator and denominator. Three tests cover it, including one that asserts the two functions agree about what is unmeasurable in every position: they are separate functions with separate guards, which is precisely how one of them came to guard half the cases. Verified by sabotage -- restoring the denominator-only guard renders `0.00x` and fails two tests. Also corrects two dates this branch wrote without an offset, against the "timestamps carry their offset" rule: M4.5's archive group heading and its stub link. The archive's own completion stamp already carried `UTC-07:00`, so the group heading contradicted the entry beneath it. Swept the dates this branch added rather than the two reported; the rest of the repository's bare dates are filenames, directory names and pre-existing history, which that rule does not govern. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Both published copies of the capture attribution wrote a bare 2026-09-15. The timestamps-carry-their-offset rule exists so two readers in different zones agree on the instant; a capture attribution is exactly the place that matters, since its whole purpose is to make a figure reusable by someone else. The root design note said the layout tables carry 'two time figures'. They now carry four -- 37 seconds, 28 days, 20 years and the 5,000-year Wide row -- and the fourth is one I added last round while correcting the unreachable claim. My own fix invalidated the sentence counting the thing it changed, two paragraphs away. Reworded to name the constant-derived facts and the time figures without counting either. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Response to this round (7 suppressed findings)Addressed in A zero numerator rendered
|
| rendered | caught? | |
|---|---|---|
| zero denominator | inf |
yes |
| zero numerator | 0.00x |
no |
And the uncaught one is the more dangerous, which is why this is a fix rather than tidying. inf announces itself as broken. 0.00x reads as a shape that was immeasurably fast — a plausible number, in a column of measurements, produced by a row that never ran.
Three tests cover it, including one asserting the two functions agree about what is unmeasurable in every position. That test exists because of how the defect arose: they are separate functions with separate guards, so fixing one said nothing about the other. Verified by sabotage — restoring the denominator-only guard renders 0.00x and fails two tests.
You also noted the existing test only exercised a zero denominator. That is exactly right, and it is the same shape as the refusals: 0 fixture problem from an earlier round: a test that only ever supplies the failure sentinel in one position cannot discover that the other position is unguarded.
The four bare dates
Changed. The convention is explicit — "when you write a date into a repository file, make it UTC or give it its offset" — and I broke it in four places this branch introduced.
The archive entry is the one worth noting: its completion stamp already read 2026-09-15 20:04:09 UTC-07:00, while the group heading immediately above it read a bare 2026-09-15. The correct form was sitting one line below the incorrect one.
I swept the dates this branch added rather than the two reported, and deliberately left the rest: the repository's other bare dates are filenames, directory names, and pre-existing history, which that rule does not govern. Churning them would be noise in a PR about something else.
DESIGN-NOTES: "two time figures"
Changed, and this one is entirely self-inflicted. The tables now carry four arithmetic horizons — 37 seconds, 28 days, 20 years, and the 5,000-year Wide row — and the fourth is one I added last round, while correcting the "unreachable" claim.
So my fix invalidated a sentence two paragraphs away that counted the thing the fix changed. Reworded to name the constant-derived facts and the time figures without counting either, since a count is the part that goes stale.
What the round taught
Three of these are the same failure at different scales: a count or a guard that was correct for the case in front of me and silent about its siblings. The denominator guard did not know about the numerator. The test fixture put the sentinel in one position only. The sentence counting time figures did not know a fourth had arrived.
None of them are restatements, so none would be caught by the claim-sweeping I have been building all through this PR. What they share is that each was written while looking at one instance of a set — which is the same root as the reported site is a sample, not the population, turned inward on my own edits rather than outward on the codebase.
There was a problem hiding this comment.
🔵 Needs a closer look
Unresolved documentation issues remain, including duplicated measurement sources and stale or restated benchmark figures.
Review details
Suppressed comments (10)
DESIGN-NOTES.md:1981
- This paragraph computes
57 / 61as93%immediately after presenting the two counts, but the new documentation rule explicitly says not to restate proportions over data already shown because the hand-computed copy can drift. Please describe this review finding without repeating the ratio (or link to a single artifact that owns the measurement).
wordings; a withdrawn magnitude surviving in two public rustdocs. The most instructive was a
proportion that restated two counts **given four words earlier in the same sentence** and got one of
them wrong -- "in both cases roughly 60%", against 57 of 61, which is 93%. The data was adjacent and
the summary of it was false, because prose is not checkable and nobody checks it.
DESIGN-NOTES.md:1997
15.3and246.9are medians from the superseded pre-correction capture that this PR says was removed from the documentation. Leaving them as bare examples here reintroduces stale benchmark figures without attribution, and conflicts with the immediately stated rule that measured numbers belong only in a provenance-carrying artifact; use non-numeric placeholders instead.
- **A number belongs in an artifact.** `15.3`, `246.9`, `fecd352`, a count of occurrences: one copy,
with its provenance travelling *with* it rather than in a hand-maintained attribution table
beside it.
crates/windows-platform-probes/COMPLETED-CHECKLIST.md:1146
- This archived checklist entry repeats the same hand-computed "factor of three" immediately after showing 19.3 and 59.5. The new repository rule says proportions over already-shown data are restatements, so retain the observed range but remove the derived ratio here as well.
The dispersion justified itself on first capture. `slotwise_mpsc` at two producers spans 19.3 to
59.5 ns/op -- a factor of three within one configuration on one host -- which the median alone had
concealed entirely, in a table that had already been published twice.
crates/windows-waitable-queues/DESIGN-NOTES.md:78
- This decision row says the figures are in the probe note "rather than restated here", but it still embeds
1.23-1.30xand1.12xin the row itself. That leaves the measurement with two prose homes and contradicts the single-source rule added in this PR. Remove the numeric ratios here and point readers to the probe note instead.
| <a id="d-41"></a>D-41 | **The claim word's apportionment is a caller's choice, and the recurrence behind SH-14.1 is a number the caller sets rather than one this crate imposes.** Supersedes [D-36](#d-36), whose premise was that the only fix was the [D-35](#d-35) claim-protocol replacement, gated on an open question -- so disclosing beat delaying. That premise was false, and measurement is what showed it: the 32/32 split followed from requiring the reservation half to hold the *entire capacity*, because every slot could be reserved at once. Capping outstanding reservations instead leaves the capacity bounded only by the ring, and the position is free to take 48 or 56 bits. `Balanced` (32/32), `Enduring` (16/48) and `Perpetual` (8/56) issue the **same** atomic compare-exchange on the same `u64`, differing only in shift and mask constants -- so the recurrence moves from about 37 seconds to about 20 years without a dependency. **An earlier version of this row added "and measured indistinguishable outside noise", and that clause is withdrawn**: it rested on a single probe run read against a noise floor of 2-6% that seven runs put at 7-61%. Re-measured, the deeper layouts are indistinguishable from `Balanced` at low producer counts, and at high counts ran 1.23-1.30x the default against a same-code control that itself reaches 1.12x -- outside the control, but too close to it to establish an ordering or a cost on this host: a flag to measure locally, not a finding. The figures are in the probe's note rather than restated here. The layout is the caller's choice and the throughput question belongs on the caller's hardware; see the queue-contention section of [DESIGN-NOTES.md](../windows-platform-probes/DESIGN-NOTES.md#d-queue-layout-observations). Which half the bits go to is the trade this decision exposes rather than settles: a 32-bit reservation field, whose count the shipping type caps at `u32::MAX` and whose achievable value capacity caps lower still, against a position whose width sets the recurrence horizon. The bound that matters on the reservation side is how many reservations a caller holds at once -- the lesser of the ring capacity and the field, reachable by one producer alone, since `reserve` takes `&self`. Which of the two a deployment needs is the deployment's question. **An earlier version of this row said the real bound was "however many producers are mid-send", and that is withdrawn as false**: one producer fills `Perpetual`'s 255 in a loop and is then refused, which `one_producer_alone_can_exhaust_the_reservation_field` pins. The correction matters because the false premise made the narrower fields look unreachable, which is the argument for spending bits on the position. `Wide` (64/64 over a `u128`) is offered behind the non-default `dwcas` feature, because it is the one thing here that costs a third-party crate -- the standard library has no 128-bit atomic -- and the whole push path was measured as slower under it as producer count rises in the isolated regime -- near parity at one or two, several times by thirty-two -- while falling inside the same-code control when drained. The probe times the complete push, so that is the layout's effect on that path rather than a measurement of the exchange alone; it buys a guarantee rather than a lifetime argument. **The default stays `Balanced`** so introducing the choice changed no existing caller's behaviour, and its documentation states the defect outright -- that past 2^32 pushes from two or more producers the queue can silently lose an item -- rather than leaving the status quo to look safe by inertia. It states the defect rather than recommending against the layout, per [D-no-client-prescriptions](../windows-platform-probes/DESIGN-NOTES.md#d-no-client-prescriptions): a caller told what the layout does can decide; a caller told what to prefer has been handed our judgement about their deployment. |
crates/windows-waitable-queues/DESIGN-NOTES.md:78
- D-41 now says the pre-correction figures belong only in the probe note, but the decision index still presents D-35 as a current measured result ("2.7x" at 16–32 producers and "1.45x" at one) without marking those values as predating the timing correction. A reader using the index can therefore still take the withdrawn magnitudes as current; mark the D-35 index entry as historical/pre-correction as part of this withdrawal sweep.
| <a id="d-41"></a>D-41 | **The claim word's apportionment is a caller's choice, and the recurrence behind SH-14.1 is a number the caller sets rather than one this crate imposes.** Supersedes [D-36](#d-36), whose premise was that the only fix was the [D-35](#d-35) claim-protocol replacement, gated on an open question -- so disclosing beat delaying. That premise was false, and measurement is what showed it: the 32/32 split followed from requiring the reservation half to hold the *entire capacity*, because every slot could be reserved at once. Capping outstanding reservations instead leaves the capacity bounded only by the ring, and the position is free to take 48 or 56 bits. `Balanced` (32/32), `Enduring` (16/48) and `Perpetual` (8/56) issue the **same** atomic compare-exchange on the same `u64`, differing only in shift and mask constants -- so the recurrence moves from about 37 seconds to about 20 years without a dependency. **An earlier version of this row added "and measured indistinguishable outside noise", and that clause is withdrawn**: it rested on a single probe run read against a noise floor of 2-6% that seven runs put at 7-61%. Re-measured, the deeper layouts are indistinguishable from `Balanced` at low producer counts, and at high counts ran 1.23-1.30x the default against a same-code control that itself reaches 1.12x -- outside the control, but too close to it to establish an ordering or a cost on this host: a flag to measure locally, not a finding. The figures are in the probe's note rather than restated here. The layout is the caller's choice and the throughput question belongs on the caller's hardware; see the queue-contention section of [DESIGN-NOTES.md](../windows-platform-probes/DESIGN-NOTES.md#d-queue-layout-observations). Which half the bits go to is the trade this decision exposes rather than settles: a 32-bit reservation field, whose count the shipping type caps at `u32::MAX` and whose achievable value capacity caps lower still, against a position whose width sets the recurrence horizon. The bound that matters on the reservation side is how many reservations a caller holds at once -- the lesser of the ring capacity and the field, reachable by one producer alone, since `reserve` takes `&self`. Which of the two a deployment needs is the deployment's question. **An earlier version of this row said the real bound was "however many producers are mid-send", and that is withdrawn as false**: one producer fills `Perpetual`'s 255 in a loop and is then refused, which `one_producer_alone_can_exhaust_the_reservation_field` pins. The correction matters because the false premise made the narrower fields look unreachable, which is the argument for spending bits on the position. `Wide` (64/64 over a `u128`) is offered behind the non-default `dwcas` feature, because it is the one thing here that costs a third-party crate -- the standard library has no 128-bit atomic -- and the whole push path was measured as slower under it as producer count rises in the isolated regime -- near parity at one or two, several times by thirty-two -- while falling inside the same-code control when drained. The probe times the complete push, so that is the layout's effect on that path rather than a measurement of the exchange alone; it buys a guarantee rather than a lifetime argument. **The default stays `Balanced`** so introducing the choice changed no existing caller's behaviour, and its documentation states the defect outright -- that past 2^32 pushes from two or more producers the queue can silently lose an item -- rather than leaving the status quo to look safe by inertia. It states the defect rather than recommending against the layout, per [D-no-client-prescriptions](../windows-platform-probes/DESIGN-NOTES.md#d-no-client-prescriptions): a caller told what the layout does can decide; a caller told what to prefer has been handed our judgement about their deployment. |
crates/windows-waitable-queues/README.md:411
- This PR adds the same hand-maintained measurement table to the README and the crate rustdoc, while the new documentation rule says a figure should have exactly one home and public prose should point to a committed artifact instead of duplicating it. A future retake can update one surface and leave the other stale. Please make the capture authoritative in one place and have both public surfaces reference that source.
| producers | `slotwise_mpsc` | `reserving_mpsc` | `permit_mpsc` | `baseline_fetch_add` |
|---|---|---|---|---|
| 1 | 6.3 (6.3-7.5) | 5.4 (5.4-6.4) | 7.9 (7.9-8.3) | 2.3 (2.3-2.7) |
| 2 | 50.6 (19.3-59.5) | 31.9 (22.5-35.2) | 44.2 (37.4-45.9) | 12.1 (5.8-14.3) |
| 4 | 91.6 (89.7-99.9) | 37.2 (31.6-41.5) | 31.8 (30.4-32.9) | 13.8 (12.6-17.6) |
crates/windows-waitable-queues/README.md:418
- The new repository rule says not to restate a proportion over values already shown in the same document. This sentence turns the displayed range into the hand-computed claim "a factor of three"; please leave the range itself as the evidence and remove the derived proportion.
**The ranges are the point, not a footnote.** `slotwise_mpsc` at two producers
spans 19.3 to 59.5 -- a factor of three within one configuration on one host --
and at thirty-two, 131.4 to 268.3. A median quoted without that is an anecdote,
crates/windows-waitable-queues/README.md:449
- This sentence derives and restates a
1.33xspread from the displayed181.5-242.3range. That is the exact hand-computed proportion the new documentation rule says not to duplicate; retain the observed range and omit the derived multiplier.
-- a fourth, separate invocation of the same build gave that row a median of
226.5 over a 181.5-242.3 range, a spread of 1.33x across its five repetitions.
crates/windows-waitable-queues/src/lib.rs:332
- This duplicates the README's "factor of three" summary from the same displayed endpoints. The new documentation rule explicitly rejects hand-computed proportions over data already present; keep the range as the evidence instead of repeating the ratio in the rustdoc copy.
//! half: `slotwise_mpsc` at two producers spans a factor of three within one
//! configuration on one host.
crates/windows-waitable-queues/src/lib.rs:373
- This rustdoc copy also derives
1.33xfrom the immediately displayed181.5-242.3range. Please keep the sampled range as the evidence and remove the hand-computed proportion, consistent with the new repository rule.
//! spread -- a fourth, separate invocation of the same build gave that row a
//! median of 226.5 over a 181.5-242.3 range, a spread of 1.33x across its five
//! repetitions. The parenthesised ranges in the table above are the wider
- Files reviewed: 21/22 changed files
- Comments generated: 0 new
- Review effort level: Lite
Ten findings, all of them this PR's new documentation rule turned on the PR that
added it. That is the right outcome and most of them are correct.
The measurement table had two hand-maintained homes -- the README and the crate
rustdoc -- which is precisely what the rule forbids, and this branch had already
demonstrated the failure: a retake updated the README and left the rustdoc
carrying the superseded capture for two commits. The rustdoc copy is gone. It now
carries the claims that do not drift (one host's observation, not a ranking; the
ranges matter more than the medians; what an operation is in each row; the host
is a single NUMA node so nothing there speaks to cross-domain behaviour) and
links to the README, which owns the figures and their attribution. The README's
measurement section gained a real heading so the link has a stable anchor.
Six derived proportions removed, each restating data shown beside it:
"a factor of three" over 19.3 to 59.5, in three files
"a spread of 1.33x" over 181.5-242.3, in two
"which is 93%" over 57 of 61 -- inside the paragraph explaining why
not to do this
The last one is the one to sit with. The rule's own worked example computed a
ratio over the counts it was citing as a cautionary tale about computing ratios
over counts. Removing it costs nothing: the counts were already there, and the
reader can see 57 of 61 without being told what fraction that is.
Two stale figures were serving as illustrative examples of "a number" in the rule
itself -- both medians from the superseded pre-correction capture this PR removed
from the documentation. Using withdrawn measurements as decoration reintroduces
them without attribution. Replaced with descriptions of the kinds of number.
D-41 said the figures live in the probe's note "rather than restated here" and
then restated them. Removed. Sweeping that claim found it in five more places --
the README twice, the crate rustdoc twice, and ClaimLayout's rustdoc -- all now
stating the qualitative conclusion and leaving the magnitudes to the probe note
that owns them.
D-35 presented pre-correction magnitudes as current, in its index row and in its
section. Both now carry the status adjacent to the claim. The review asked only
about the index row; marking the section too is the same pairing D-17 and D-27
needed, and missing the section half is a mistake this branch has now made three
times.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Response to this round (10 suppressed findings)Addressed in The table had two hand-maintained homesChanged — the rustdoc copy is gone. This is the finding that matters, and the evidence for it is in this branch's own history: a retake updated the README and left the rustdoc carrying the superseded capture for two commits, which a review had to catch. The rule was written from that experience and then the same PR shipped the duplication intact. The rustdoc now carries only what does not drift — one host's observation rather than a ranking; the ranges matter more than the medians; what an operation means in each row; the host is a single NUMA node so nothing there speaks to cross-domain behaviour; This does not decide the committed-artifact question, which is deliberately still open. It does reduce two hand-maintained copies to one, which is the part of the rule that can be satisfied today. Six derived proportions, including one inside the rule's own exampleAll removed.
The last is worth sitting with rather than laughing off. The rule's cautionary example computed a ratio over the counts it was citing as a cautionary tale about computing ratios over counts. Removing it costs nothing — the counts were already there, and a reader can see 57 of 61 without being told what fraction that is. Stale figures used as decorationChanged. Two medians from the superseded pre-correction capture were serving as illustrative examples of "a number" inside the rule itself. Using withdrawn measurements as decoration reintroduces them without attribution — they read as current to anyone who does not already know the capture was retired. Replaced with descriptions of the kinds of number. D-41 restated what it said it did notChanged, and sweeping it found the same claim in five more places — the README twice, the crate rustdoc twice, and D-41 literally said "the figures are in the probe's note rather than restated here" with the figures restated in the same sentence. D-35 presented pre-correction magnitudes as currentChanged in both the index row and the section. You asked about the index row; the section needed it too, and marking only the index would have left a reader who scrolls past the row taking the body as current. That pairing — index row and section — is the third time on this branch. D-17 and D-27 each needed the same correction after I marked one half and not the other. It is a reliable enough mistake that it belongs in the convention rather than in my attention. What the round taughtA rule written from experience does not retroactively fix the document that states it. Every one of these ten was in prose that either introduced the rule or sat beside it, written before the rule existed and left unswept when it did. Adding a rule is a contract change, and the blast-radius sweep it obliges includes the text that added it — which is the one place nobody thinks to look, because it is where the thinking just happened. |
`Run::spread()` returned `0.0` when a row measured nothing, on the reasoning that zero is not a plausible spread so it could serve as a sentinel. The report renders it through `format_scaling`, which rejects only non-finite values, so that row printed `1.00x`'s more flattering neighbour: **`0.00x`**, the most reassuring value the column can hold, meaning every repetition agreed exactly -- produced by a shape that never ran. This is the third time on this branch that a zero sentinel reached a reader as a plausible number, after `format_ratio` and `format_ratio_bounded` two commits ago. Fixing those two and leaving this one is the same sibling-blindness the round before flagged: I corrected the functions the review named and not the accessor feeding a third call site. `spread()` now returns `Option<f64>`, which removes the sentinel rather than guarding it. Every neighbouring accessor -- `scaling`, `scaling_bounds`, `ratio_bounds` -- already returns `Option` for exactly this situation; `spread` was the one exception, and the exception is what a renderer got wrong. A type that cannot express "no measurement" forces every caller to remember a convention, and one of them will not. Two tests: the accessor answers `None`, and the renderer marks it `--`. The second exists because the accessor is not where the damage happened. Verified by sabotage -- restoring the sentinel behind the `Option` renders `Some(0.0)` and fails. Report re-rendered from a release build; measured rows are unchanged. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The previous commit edited these two lines through PowerShell and pushed without re-running cargo fmt, so CI's rustfmt job failed on line length. The repository's pre-commit gate requires fmt then clippy whenever a staged file is .rs; I ran the encoding and commit-scope checks and skipped that one, because the change looked like a test edit rather than a code edit. The gate does not make that distinction and is right not to. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
🟡 Changes recommended
Unresolved critical and moderate findings, along with documentation corrections, remain before approval.
Get a fresh assessment by requesting another Copilot review.
Review details
Suppressed comments (7)
DESIGN-NOTES.md:1867
- This adds a substantial new canonical design principle to Tier 1, but the repository's Tier 1/Tier 2 split keeps current decisions in
DESIGN-NOTES.mdand historical alternatives and measurement rationale in the rootDESIGN-RATIONALE.md(see its opening contract). This section is mostly review history, measurements, and alternatives, yet no matching Tier 2 section is added, so the new design record does not follow the repository's documentation structure. Keep a compact current principle here and move the historical material intoDESIGN-RATIONALE.mdin the same change.
## <a id="prose-volume-and-error-surface"></a>Prose volume is not the error surface; restatement count is
[Restatement drift](#restatement-drift) explains the mechanism and gives the remedy. This note
records something that section does not: a measurement of **where** the drift actually lives, taken
after PR #90's eighteenth review round, and what follows from it about formal specification.
DESIGN-NOTES.md:1984
- This is a repository path in a Markdown document, so it should be a relative clickable link rather than inline code. The capture directory exists; linking it lets readers open the artifact directly and follows the repository's Markdown cross-reference convention.
`mutation-sweeps/2026-09-02/` is a dated, committed capture directory: data as an artifact, cited
crates/windows-platform-probes/COMPLETED-CHECKLIST.md:1139
- This archived M4.5 entry now contradicts the implementation:
Run::spread()returnsNonefor an unmeasured row, and the renderer prints--; it no longer returns zero. Because this archive is meant to preserve the completed work accurately, update the text so it does not document the sentinel behavior that this change explicitly removed.
`Run` gained `fastest_nanos_per_op` and `slowest_nanos_per_op`, taken from the ends of the sort that
already existed, plus a `spread()` accessor that returns zero rather than infinity when a shape
failed to run -- the same guard `format_ratio` carries for the same reason. `render_table` publishes
an `ns/op range` column and a `spread` column.
crates/windows-platform-probes/src/queue_contention.rs:345
- The positivity checks here do not reject non-finite
Runvalues:f64::INFINITY > 0.0, soratio_boundscan returnSome((NaN, NaN))for an infinite span.format_ratio_boundedthen publishes strings such asinfx [NaNx-NaNx]instead of the--marker used for unmeasurable values. SinceRunand these helpers are public, reject non-finite medians/spans consistently in this path (and its sibling ratio formatter) and add regression cases.
pub fn ratio_bounds(numerator: Run, denominator: Run) -> Option<(f64, f64)> {
if numerator.fastest_nanos_per_op <= 0.0
|| numerator.slowest_nanos_per_op <= 0.0
|| denominator.fastest_nanos_per_op <= 0.0
|| denominator.slowest_nanos_per_op <= 0.0
{
return None;
}
// Widest is the numerator at its worst over the denominator at its best;
// narrowest is the reverse.
let low = numerator.fastest_nanos_per_op / denominator.slowest_nanos_per_op;
let high = numerator.slowest_nanos_per_op / denominator.fastest_nanos_per_op;
Some((low, high))
crates/windows-waitable-queues/DESIGN-NOTES.md:870
- The qualification here is contradicted by the still-active D-26 text below: it continues to state “up to 4x faster,” that
reserving_mpscis cheaper at every producer count, and quotes the pre-correction drained values. Those are precisely the magnitudes and causal/ordering claims this PR withdraws; the section needs the same qualified end-to-end wording as D-41/README instead of leaving the old decision text normative.
**That "within noise" rests on a floor this workspace has since measured to be far
wider.** The figure was read against a 2-6% run-to-run spread; seven runs of the
same probe later put the same-configuration spread at 7-61% depending on producer
count, and the probe's own same-code control spans 0.68-1.27x. The figures below
are not retracted -- the direction of `D-26` survived a re-measurement on the
shipping type -- but "agreed within noise" is a weaker statement than it reads as,
and any difference here smaller than that control should not be treated as
established. See
crates/windows-waitable-queues/DESIGN-NOTES.md:923
- This newly qualified paragraph correctly says the probe cannot isolate or bound the sequence read, but the next paragraph still concludes “the reserving shape's extra read is cheaper than the read it replaces.” That conclusion is an unsupported causal attribution and directly contradicts the limitation just stated; remove or rewrite it as an explicitly historical hypothesis, as D-41 now does.
**The causal mechanism below is a hypothesis this workspace has not established, and the figures in it
predate a correction to the probe's timing window.** Read the whole section as the historical argument
that made `D-26`'s result explicable rather than as a measured finding. What survives is the end-to-end
observation -- `reserving_mpsc` measured faster than `slotwise_mpsc` under contention on the hosts tried
-- and the fact that the difference is a property of the two *protocols* rather than of two
implementations of one. What does not survive is the attribution: the probe times the complete push and
so cannot isolate or bound the sequence read, which is the quantity this explanation rests on. The
padding experiment below is a real measurement and still rejects the false-sharing hypothesis; its
numbers, being pre-correction, should be read as optimistic.
crates/windows-waitable-queues/src/reserving_mpsc.rs:28
- This caveat is not propagated to the
Perpetualrustdoc below: it still says the 2^56 recurrence is “beyond any real deployment.” The horizon is explicitly rate-dependent here, so a faster caller can reach it much sooner; please replace that universal deployment claim with the qualified planning-rate/floor wording used in this section and the README.
//! *sustained* pushing at this crate's disclosed rates, roughly two minutes at
//! two producers. Those rates predate a correction to the probe's timing window,
//! so they are a floor rather than a forecast -- the correction lowers the rate
//! and lengthens the horizon, which is the conservative direction for a hazard;
//! see [`ClaimLayout`]. The wrap alone is not enough -- a producer must also stall
- Files reviewed: 21/22 changed files
- Comments generated: 1
- Review effort level: Lite
| assert!( | ||
| error.is_retryable(), | ||
| "the consumer is gone, so this push can never \ | ||
| succeed: {error}" | ||
| ); |
There was a problem hiding this comment.
🔵 Needs a closer look
Unresolved documentation nits remain across the reviewed files.
Review details
Suppressed comments (9)
DESIGN-NOTES.md:1882
- This paragraph hard-codes the exact file count (
five separate files) even though the new principle says such counts drift and deliberately avoids recording them. Any later documentation or test mention will make this design note stale in the same way it describes; please remove the tally or make it a derived artifact rather than prose.
any of them. The ceiling is the worst: it appears in five separate files.
DESIGN-NOTES.md:1981
- This paragraph hard-codes the 60%/57-of-61 example in prose even though the new section's stated principle is that measured numbers belong in one attributed artifact. Keeping the figures here creates the same transcription/restatement surface this decision is meant to remove; please move the example to a committed capture or describe it qualitatively and link to that artifact.
proportion that restated two counts **given four words earlier in the same sentence** and got one of
them wrong -- it said "in both cases roughly 60%" where one of the two cases was 57 of 61. The data
was adjacent and the summary of it was false, because prose is not checkable and nobody checks it.
crates/windows-platform-probes/COMPLETED-CHECKLIST.md:1139
- This archived completion note describes the new
Run::spread()contract incorrectly: the implementation returnsOption<f64>and the renderer prints--for an unmeasured row; it does not return zero (or infinity). Please update the historical record so it does not teach the old sentinel behavior.
`Run` gained `fastest_nanos_per_op` and `slowest_nanos_per_op`, taken from the ends of the sort that
already existed, plus a `spread()` accessor that returns zero rather than infinity when a shape
failed to run -- the same guard `format_ratio` carries for the same reason. `render_table` publishes
an `ns/op range` column and a `spread` column.
crates/windows-waitable-queues/DESIGN-NOTES.md:1302
- The updated status paragraph still overstates the retained D-35 direction: its own table below shows
permit_mpscslower thanreserving_mpscat two producers (1.26x), so “faster where contention exists and slower at one producer” is false if contention means more than one producer. Please describe the crossover as four-or-more producers versus one-or-two, matching the table.
[D-29](#d-29) no current public figure derives from that capture. The direction the section
establishes -- that the permit claim is faster where contention exists and slower at one producer --
survives the correction; the multipliers do not.
crates/windows-waitable-queues/DESIGN-NOTES.md:72
- The D-35 index row repeats the same inaccurate scope: the retained ratio table shows
permit_mpscis still 1.26x slower at two producers, so the faster result begins at four producers rather than at every producer count above one. Please keep this summary consistent with the corrected paragraph below.
| <a id="d-35"></a>D-35 | **The magnitudes below predate the timing correction and are retained as the record of what the measurement showed, not as current figures.** **Measured: the permit claim is faster than `reserving_mpsc` at high producer counts and slower at one** -- originally recorded as 2.7x and 1.45x respectively, from a capture taken before the probe's timing window was corrected; per [D-29](#d-29) no current public figure derives from that capture. The direction survives the correction; the magnitudes do not. The safer claim is also the faster one everywhere contention exists, which was not the expected result -- it touches *two* shared lines where the shipping shape touches one plus a read, and [D-26](#d-26) had established that the shared line is what collapses. The mechanism is that both of its operations are unconditional read-modify-writes that never retry, where the shipping shape's compare-exchange retries once per lost race; the retries dominate long before the second line does. It is the only shape measured that gets *faster* per push as producers are added (42.8 ns at two to 19.5 at thirty-two) and the only one that stays within 1.5x of a bare contended `fetch_add`. **This decides the shape of the fix but not the fix**: the drained regime's refusal counts differ by orders of magnitude in a way this harness cannot attribute, which SH-15.5.1 exists to settle before SH-15.6 adopts anything. |
crates/windows-waitable-queues/README.md:379
- This new guidance still inherits the obsolete “in one run” framing from the surrounding bullet: the recurrence exposure is accumulated over the lifetime of one queue, as the earlier section now correctly states. Please make this heading describe a queue lifetime so readers do not treat a long-lived queue as safe merely because no single run crosses the threshold.
Under its default layout `reserving_mpsc` can lose an item past that volume.
crates/windows-waitable-queues/src/reserving_mpsc.rs:27
- This says the disclosed rates are a floor, but a rate that was overstated by the timing defect is an upper bound; the resulting wrap horizon is the floor. Please make the subject of “floor” the horizon so callers do not invert the conservative direction.
//! two producers. Those rates predate a correction to the probe's timing window,
//! so they are a floor rather than a forecast -- the correction lowers the rate
//! and lengthens the horizon, which is the conservative direction for a hazard;
crates/windows-waitable-queues/src/slotwise_mpsc.rs:555
- This sentence is missing its subject: “Why is not established” is ungrammatical and makes the comment harder to read. Please say “The reason is not established.”
// slower than `reserving_mpsc` under contention despite it. Why is not
crates/windows-waitable-queues/src/slotwise_mpsc.rs:88
- The same wording mistake appears here: the disclosed rate is not a floor after a correction that lowers it; the time-to-wrap computed from that rate is. Please name the horizon as the floor.
/// which at this crate's disclosed rates is a matter of minutes -- a floor,
/// since those rates predate a timing correction that lowers them: the stalled
- Files reviewed: 21/22 changed files
- Comments generated: 0 new
- Review effort level: Lite
A row that did not run reports zero, and zero is not an obviously broken value in any of this report's columns: `0.0` ns/op reads as immeasurably fast, `0.00x` as a ratio of one, `0.0-0.0` as perfect stability. Three renderers guarded the sentinel and four did not, so the same row was refused a ratio and granted a cost. That asymmetry is the residue of fixing `Run::spread` at the instance rather than the class: the guard was a convention each renderer restated, so a renderer could omit it by saying nothing. `Run::is_measured` makes it a definition every renderer asks, and `render_table` now marks every measured cell of an unmeasured row rather than only its spread. The producer count and shape survive, being configuration rather than measurement. Also widens the layout table's ratio columns, which allocated 10 characters to a formatter whose ordinary output is 19. A Rust width is a minimum, so the value was not truncated -- it pushed the next two columns out of line with their headers, silently, in every report the probe has emitted. The width is now derived from a named constant that a test holds against the formatter, and the value columns say `ns/op` rather than `ns`, which is the unit they carry. Verified by sabotage: reverting `is_measured` to `true` fails 8 tests, reverting either scaling guard fails 2, and restoring the old column width fails with `"10.00x [6.67-15.00]" is 19 characters ... which allows 10`. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Every claim-position layout recurs. `Wide` moves the horizon to 2^64 pushes rather than removing it, which the `Wide` rustdoc already said outright -- "Longer, not unbounded" -- while three other sites still stated the withdrawn claim in words that shared no keyword with it: - D-41's index row: "it buys a guarantee rather than a lifetime argument", which is exactly what a longer horizon is not. - `Perpetual`: 20 years "puts the recurrence beyond any real deployment rather than merely far away" -- an absolute claim about the *shortest* of the deferred horizons, and one a caller pushing an order of magnitude faster falsifies in two years. - `permit_mpsc`: a wider field "moves the recurrence out of reach", immediately before claiming the shape "addresses the structure rather than the interval" -- which "out of reach" contradicts, since it is an interval claim. The earlier sweep that corrected "unreachable" and "no deployment reaches" missed all three because it swept the phrasings that had been written rather than the proposition they encode. Swept the proposition this time: "Wide/Perpetual is qualitatively different" across both crates. 4 sites found, 4 corrected; the `Wide` rustdoc and the probe's horizon table already agreed. The fourth site is the probe report's "8/56 merely deferring it", which lives in the probes crate and so landed in the preceding commit to keep the release scope clean. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Self-review round (GPT Sol),
|
| Sabotage | Result |
|---|---|
is_measured -> true |
8 tests fail |
either format_scaling* zero guard removed |
2 tests fail |
RATIO_COLUMN_WIDTH back to 10 |
fails with "10.00x [6.67-15.00]" is 19 characters ... which allows 10 |
Gate: cargo fmt, clippy --all-targets (both crates, --all-features on the queue crate), 294 probe tests + 345 queue tests + doctests, cargo doc -D warnings, encoding check 646 files clean.
Split into fix(probes) and docs(queues) so the queue crate takes no unearned version bump.
There was a problem hiding this comment.
🔵 Needs a closer look
An unresolved moderate spread() validation issue and two documentation nits remain.
Review details
Suppressed comments (4)
Previously missed (1) — in code that hasn't changed since the last review.
crates/windows-platform-probes/src/queue_contention.rs:246
- The
> 0.0guard does not reject non-finite public span values:NaNcompares false, while an infinite fastest/slowest value can produceSome(NaN)orSome(inf). SinceRunand these fields are public,spread()can return a numeric-looking result for an unmeasurable row despite its documentedNonecontract, and the direct API is inconsistent with the finite checks in the renderers. Require both span endpoints to be finite and positive before dividing, and add a NaN/infinity regression case.
This issue also appears on line 355 of the same file.
DESIGN-NOTES.md:1985
- This new design-note section names the committed capture directory as inline code, so readers cannot Ctrl+Click to inspect the evidence. Repository Markdown requires paths whose purpose is to direct readers to another file or artifact to be relative clickable links; please link this directory (or its README) here.
`mutation-sweeps/2026-09-02/` is a dated, committed capture directory: data as an artifact, cited
rather than retyped. `windows-platform-probes`, which produces the most-cited numbers in the
DESIGN-NOTES.md:2044
- This says a formal-methods survey is queued in the root CHECKLIST.md, but that checklist has no item for a formal-methods/TLA+/loom/specification survey. As written, the note points readers to work that does not exist; please add the actual checklist item (and its plan entry if required) or remove/reword this claim.
rather than an oversight. A formal-methods survey is queued separately in the root
[CHECKLIST.md](CHECKLIST.md) and bears on the same question. If the table-versus-constants test or a
crates/windows-platform-probes/src/queue_contention.rs:358
- These guards only reject non-positive values;
NaNbypasses every comparison and infinity is accepted, so a publicRunwith a non-finite span makesratio_boundsreturnSomecontainingNaN/inf.format_ratio_boundedthen publishes that as a bounded ratio, unlikeformat_scaling_boundedwhich explicitly rejects non-finite bounds. Reject non-finite span endpoints here and cover NaN/infinity in the API/formatter tests.
if numerator.fastest_nanos_per_op <= 0.0
|| numerator.slowest_nanos_per_op <= 0.0
|| denominator.fastest_nanos_per_op <= 0.0
|| denominator.slowest_nanos_per_op <= 0.0
- Files reviewed: 21/22 changed files
- Comments generated: 0 new
- Review effort level: Lite
The archived M4.5 entry described `spread()` as returning "zero rather than infinity when a shape failed to run -- the same guard `format_ratio` carries for the same reason". Both halves are false as shipped, and the sentence is the discredited behaviour presented as the delivered feature. Ordering the branch's own commits: `fecd352` added `spread()` returning `0.0`; `bd82bf9` archived M4.5 with that description; `28978ba` then established that `0.0` renders as `0.00x`, reads as perfect stability, and was itself the defect -- changing `spread()` to return `Option`. `format_ratio` no longer carries a zero-returning guard either; it routes through `Run::is_measured`. The archive was not revisited, so it shipped teaching that returning zero was the fix. That is premise-removed/conclusion-kept, arising wholly inside this branch, in the one document written to be read later for *why* a thing was done. The intermediate state never existed on main and never will, so correcting it before merge records the only state that ships rather than rewriting landed history. The archive is append-only, so the correction is appended rather than substituted: the original wording is named in the note, because it did not merely go stale, it inverted the lesson. Swept the proposition across the crate and the root design notes before committing: one site stated it, this one. The code, the tests and the `spread()` rustdoc all already said `None`. Nothing detected the drift, which is what `M2.13` (lint the completed checklist archive mechanically in CI) is already queued to fix. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Review round (Claude Opus, fresh model),
|
There was a problem hiding this comment.
🔵 Needs a closer look
Two moderate findings and two documentation nits remain unresolved.
Review details
Suppressed comments (4)
DESIGN-NOTES.md:2009
- This section explicitly records a new repository-wide principle, but the matching Tier 2 rationale is missing. The root
DESIGN-RATIONALE.mdidentifies itself as the rationale for decisions in this file, and the repository's tiering convention requires a new decision to be recorded in both tiers in the same change; please add the corresponding rationale or move this material out of the canonical decision notes.
**The mechanism is undecided and no work is scheduled here.** The reader-experience trade is real --
a figure behind a link is a figure most readers will not look at -- and it has not been settled.
Recorded as a principle so the next person choosing where to paste a number has the argument in front
of them, not as a queued change. Per "design notes are not a work queue", the absence of a checklist
item is deliberate.
DESIGN-NOTES.md:1882
- The new section says exact counts, including file counts, are deliberately computed rather than quoted, but this sentence still hard-codes that the ceiling appears in five files. That is the same drift-prone restatement this section is documenting; please remove the number or keep the census in a single authoritative artifact.
any of them. The ceiling is the worst: it appears in five separate files.
crates/windows-platform-probes/src/queue_contention.rs:359
Runand its fields are public, so a row with a positive median but aNaNor infinite repetition bound can reach this function. The<= 0.0checks do not rejectNaN;ratio_boundsthen returnsSome((NaN, ...))andformat_ratio_boundedpublishes a misleading... [NaN-NaN]interval instead of the--marker used for unmeasured data. Validate the span values as finite (and reject malformed spans) before rendering the bounded ratio.
if numerator.fastest_nanos_per_op <= 0.0
|| numerator.slowest_nanos_per_op <= 0.0
|| denominator.fastest_nanos_per_op <= 0.0
|| denominator.slowest_nanos_per_op <= 0.0
{
crates/windows-waitable-queues/src/reserving_mpsc.rs:604
- This sentence is incomplete: "about two" does not state the unit, so the public documentation does not explain the resulting horizon. Since the preceding value is 20 years and the example is a tenfold rate increase, this should say "about two years."
/// it scales with the caller's rate: a deployment pushing an order of magnitude
/// faster reaches it in about two.
- Files reviewed: 21/22 changed files
- Comments generated: 0 new
- Review effort level: Lite
…ts cells Two renderer defects, both cases of a guard that stops one step short of where the value is actually used. `layouts_measured` asked whether a row was *present*, not whether it ran. A row can be present and carry the did-not-run sentinel, so the report could state "4 apportionments ... measured" directly above a table in which `render_table` marked one of them `--` in every measured cell. The count is now `Observation::count_measured`, which asks `Run::is_measured` and is testable, rather than a `find(..).is_some()` in the binary that no test could reach. `RATIO_COLUMN_WIDTH` was treated as a bound when it is only a floor. The interval endpoints `format_ratio_bounded` prints come from measured spans, so the cell's width is a function of data: a slow repetition against a fast one renders `10.00x [6.67-1500.00]`, 21 characters, which a width of 20 does not truncate -- it pushes the next two columns out of line with their headers, silently. Outliers of that size are ordinary on a loaded or virtualized host, and surviving them is why `median_run` takes a median at all. The width is now derived per table by `ratio_column_width` from the cells it must hold, with the constant as a floor so a narrow table still looks right. That requires rendering every cell before emitting the header, which is the only ordering that can get it right. The previous test asserted `cell.len() <= RATIO_COLUMN_WIDTH` and passed only because its fixtures were narrow -- it pinned an invariant that was never available. It now pins the derivation, and carries an assertion that the overrunning fixture still overruns, so the case cannot stop being exercised without failing. Verified by sabotage: reverting `count_measured` to `.is_some()` and `ratio_column_width` to the bare constant fails exactly the two tests written for them, and nothing else. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Third sweep of the same proposition, and the third to find sites the previous one missed -- because each swept the phrasings already written rather than the claim they encode. These three share no keyword with "unreachable" or "no deployment reaches", which is what the earlier sweeps grepped for: - The probe's own horizon table gives 8/56 twenty years and 64/64 5,039 at the same rate, while the paragraph above it said 8/56 "reaches the same practical headroom a 128-bit word gives". They differ by a factor of 250. - The same section called 12/52 "the first row that is not" reachable. The table gives it 202 days at the conservative floor, which a long-lived process reaches comfortably. - `Balanced`'s rustdoc said `Wide` moves the recurrence to 2^64 pushes "rather than to a horizon in years", contradicting `Wide`'s own rustdoc twenty lines below, which says 2^64 is about 5,000 years and calls it "Longer, not unbounded". Every layout recurs. What changes down the column is how long it takes and at what rate, so the prose now says that and leaves the durations to the table that computes them. Worth noting where these survived: the table is correct and always was. It was the prose around it drawing conclusions the table contradicts -- the argument for a figure having one home, made against itself. Swept across both crates: 3 sites found, 3 corrected. The remaining "unreachable" hits are a different proposition (a capacity ceiling of 2^31 slots, which is tens of gigabytes) or describe prior art's claims rather than ours, and are left alone. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Review round (GPT Sol),
|
There was a problem hiding this comment.
🔵 Needs a closer look
Public probe helpers need non-finite span validation, and one documentation cross-reference remains unresolved.
Review details
Suppressed comments (3)
DESIGN-NOTES.md:1984
- This new reference points readers at a repository capture directory but leaves it as inline code, so it is not navigable under the repository's Markdown cross-reference convention. Link it to the directory's README (or to the specific capture) so the stated artifact can be opened directly.
`mutation-sweeps/2026-09-02/` is a dated, committed capture directory: data as an artifact, cited
crates/windows-platform-probes/src/queue_contention.rs:243
Runand all of its timing fields are public, so callers can construct a row with a non-finite span. Whenslowest_nanos_per_opisNaNor infinity, this> 0.0check still passes if the fastest value is positive, andspread()returnsSome(NaN)/Some(inf)instead of the documented absence of a measurable spread. That value can then leak into public callers; require both span endpoints to be finite and positive before returningSome.
if self.fastest_nanos_per_op > 0.0 {
Some(self.slowest_nanos_per_op / self.fastest_nanos_per_op)
crates/windows-platform-probes/src/queue_contention.rs:381
- The four
<= 0.0checks do not rejectNaN, because every comparison withNaNis false. SinceRunis public, a caller can pass a non-finite span and makeratio_boundsreturnSome((NaN, NaN));format_ratio_boundedthen rendersNaNx [NaN-NaN]rather than--, contradicting the renderer's non-finite-value handling. Reject non-finite endpoints here as well as non-positive ones.
if numerator.fastest_nanos_per_op <= 0.0
|| numerator.slowest_nanos_per_op <= 0.0
|| denominator.fastest_nanos_per_op <= 0.0
|| denominator.slowest_nanos_per_op <= 0.0
- Files reviewed: 21/22 changed files
- Comments generated: 0 new
- Review effort level: Lite
Peeled from
mikegrier/deferred-namespace-ops, where it was written alongside work that is not ready.It lands on its own because it is an instrument: useful before the plan that consumes it exists, and landing it first is what lets that decision be made against a measurement rather than an argument.
What it measures
Two questions a queue-shape decision is waiting on:
reserving_mpsc's extra read of the consumer's position actually costs.Two regimes, and the pair is the point. Isolated gives producers capacity large enough that nothing is refused and runs no consumer, so whatever curve appears against N is the claim and nothing else. Drained runs a consumer popping continuously -- the only regime that can price the read of
head, because that read is cheap until a consumer is writing the line. Measuring it in isolation would report it as free.Each row carries the refusal count from the queue's own
Observablecounters, so a consumer-bound plateau at high producer counts is visible as a fact rather than mistaken for contention.Verified by running it, not by building it
Seven runs on
x86_64 16p/8c smt+ L2[2,2,2,2,2,2,2,2] ec[0:16] numa[16], release, exit 0, ~65s each. Isolated, at sixteen producers, median of seven:baseline_fetch_addpermit_mpscreserving_mpscslotwise_mpscThese are not the figures the README publishes, and that is deliberate. This
seven-run sweep was taken to size the probe's noise floor -- it is the capture
behind the 0.68-1.27x same-code control quoted below. The README's table is a
separate, fully attributed three-run capture, retaken at
fecd352once the probelearned to carry its own dispersion; its sixteen-producer medians are
14.8 / 21.8 / 47.9 / 218.0, each published with the range across all fifteen
repetitions. Neither supersedes the other: the README's is
the attributed figure that crate ships, and this one is the evidence about how far such
a figure moves between runs. That the two disagree on the same host and
the same code is the sweep's finding, not a discrepancy to reconcile.
(An earlier revision of this paragraph cited the capture at
a99108fwith medians of15.3 / 21.4 / 51.1 / 246.9. That capture was superseded when the dispersion columns
landed and the table was retaken; the README and the crate rustdoc both carry the
fecd352figures. This description was the last copy still naming the old one.)Gate: fmt, clippy
--all-targets, lib tests and doctests for both affected crates (the latter including the compiled README), all green.A timing defect found in review, and what it moved
The first version of the probe released a
Barrier, calledInstant::now()on the coordinator, and readelapsed()afterthread::scopereturned. Both ends were wrong:thread::scopejoins before returning, so exit and join cost sat inside the window.Fixed with per-worker timestamps and a span of
min(start)..max(end). Measured effect:reserving_mpscat sixteen producers moved 35.0 -> 52.3 ns/push. An earlier review round had explicitly cleared this code as correct.That correction shipped without a test, which a later round caught.
measured_spanis now pinned by four unit tests built from constructed
Instants, and the guard wasverified by sabotage: reverting
mintomaxon the start fails three of them.The report's four rendering helpers moved out of the binary into the library for the
same reason -- nothing could reach them where they were, so the non-finite case the
tests documented was never actually checked. Dropping
format_ratio'szero-denominator guard now renders
infxand fails.Any figure in the design notes taken before that correction is marked as predating it.
The claim this probe withdrew
The notes had said the
u64re-apportionments "track the default within noise", soPerpetual's twenty years of counter headroom was free. Re-measuring seven times says otherwise, and in a way worth stating precisely:reserving_mpscandreserving(32/32)are the same code at the same layout, measured twice per run, so their ratio is an empirical "no difference" -- and it spans 0.68-1.27x.Against that control the 128-bit word separates decisively in isolation (3.45x / 3.81x at 16 / 32 producers); the
u64re-apportionments do not. The claim is withdrawn in both directions rather than inverted: 1.23-1.30x against a control reaching 1.12x, on one host, is a flag to measure locally, not a cost.That withdrawal had to sweep out of this crate, because the claim had propagated into
windows-waitable-queues-- its README, its public rustdoc, andClaimLayout's own doc comment, which is what a caller reads while choosing a layout. The mechanical argument is kept (samelock cmpxchg, sameu64, shift constants only, so no structural reason for one to be slower); only the claim that this was measured to cost nothing is gone.Perpetualis not described as free, and this PR does not name a preferred layout.What the layout does is stated; which one to pick is the caller's, per
D-no-client-prescriptions.Why it is NOT in the CI probe job
Deliberate, and the reason is a measurement rather than a preference. In a debug build
slotwise_mpscandreserving_mpsccome out indistinguishable (249.7 vs 254.0 ns/push at sixteen producers); in release, 193.5 vs 52.2. A debug run does not merely lose precision -- it reports the two shapes as equivalent, which is a confident wrong answer.(Those four figures predate the timing correction above and have not been retaken. The qualitative finding is unaffected -- a debug build still swamps the effect.)
It also wants more cores than a hosted runner has, and costs about a minute against a job whose other probes take seconds. So it is run by hand, on a known machine, with the numbers recorded against that machine.
A CI hole this PR opened, and closed
Adding
windows-waitable-queueswithdwcas+experimental-permit-claimunified those features workspace-wide. CI built that crate only via--workspace, so nothing compiled the no-dwcaspath any more -- anddwcasis additive, gatingWideandClaimLayoutitems that would have stopped being checked.Restored with a dedicated default-features job, modelled on the existing
placement-probe-no-serdejob.Feature flags
experimental-permit-claimis enabled on the dependency because this probe is what decides its fate -- it has to be measured against the shipping shapes on the same host, in the same run, by the same harness.dwcasis what lets it instantiate the 128-bit claim layout.Review history
Eighteen rounds. The first four each found something in the code: the feature-unification hole, the timing window, four unguarded retry loops, and three prose sites naming
mpscfor a module actually calledslotwise_mpsc. The fifth ran the probe end-to-end and found nothing in the code -- only the documentation contradiction that produced the withdrawal sweep above.The rounds after that were almost entirely restatement drift: a claim corrected in
one place and left standing in five others. The pattern held often enough to be worth
naming -- the reported site is a sample, not the population, so each round ended with a
sweep of the claim rather than a fix to the line cited. Two rounds found real evidence
problems instead: one withdrew a refusal-count argument that three re-measurements
showed does not reproduce in direction or magnitude, and the last found the two test
gaps addressed above.