Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
112 commits
Select commit Hold shift + click to select a range
5c9f1d8
Explore bounded CountedSignal saturation
swgiacomelli Aug 11, 2026
e21c7fa
Develop complete block handoff candidate
swgiacomelli Aug 11, 2026
445c2b0
Develop EventFlags decision package
swgiacomelli Aug 11, 2026
fd7816d
Prototype freshness-first LatestBuf channel
swgiacomelli Aug 11, 2026
72a5546
Add LatestBuf implementation evaluation scaffold
swgiacomelli Aug 11, 2026
3065335
Strengthen LatestBuf evaluation evidence
swgiacomelli Aug 11, 2026
72cb22f
Validate LatestBuf ordering mutations
swgiacomelli Aug 11, 2026
bc54a9a
Measure BlockBuf publication costs
swgiacomelli Aug 11, 2026
6f46da3
Measure and optimize LatestBuf costs
swgiacomelli Aug 11, 2026
0a22ada
Complete CountedSignal admission evidence
swgiacomelli Aug 11, 2026
8593b4a
Measure LatestBuf block composition
swgiacomelli Aug 11, 2026
f26d4c3
Finalize CountedSignal promotion decision
swgiacomelli Aug 11, 2026
e9859d4
Implement EventFlags candidate
swgiacomelli Aug 11, 2026
af1c7a6
Reword the D1 surfaces from deferred-default to closed-decision framing
swgiacomelli Aug 11, 2026
b1e1b76
Reword the D2 surfaces to closed and pin the absent Source impl
swgiacomelli Aug 11, 2026
798f635
Reword the D3 surfaces to closed - all three decision points settled
swgiacomelli Aug 11, 2026
deac0f5
Mark the D3 type-identity recommendation confirmed
swgiacomelli Aug 11, 2026
f8bff27
Reword the A.3 surfaces to closed and document the X8 role boundary
swgiacomelli Aug 11, 2026
99d2386
Align the skipped rustdoc with the corrected C3 formula and trigger
swgiacomelli Aug 11, 2026
6554e78
Merge remote-tracking branch 'origin/master' into candidate/latest-buf
swgiacomelli Aug 11, 2026
8433bf5
Merge remote-tracking branch 'origin/master' into candidate/block-buf
swgiacomelli Aug 11, 2026
d8cc531
Merge remote-tracking branch 'origin/master' into candidate/event-flags
swgiacomelli Aug 11, 2026
143e64b
Merge remote-tracking branch 'origin/master' into candidate/counted-s…
swgiacomelli Aug 11, 2026
618c5d2
Add event-flags engineering record for Track 1 acceptance package
cursoragent Aug 11, 2026
2008350
Add counted-signal engineering record for Track 1 acceptance package
cursoragent Aug 11, 2026
735e9ab
Add block-buf engineering record for Track 1 acceptance package
cursoragent Aug 11, 2026
48d41fb
Record the P closure: Copy composition selected, baselines directed
swgiacomelli Aug 11, 2026
a3d0d19
Merge remote-tracking branch 'origin/candidate/block-buf' into candid…
swgiacomelli Aug 11, 2026
5ec002e
Update the engineering record for the P and S closures
swgiacomelli Aug 11, 2026
132339d
Merge remote-tracking branch 'origin/master' into candidate/latest-buf
swgiacomelli Aug 11, 2026
5858854
Merge remote-tracking branch 'origin/master' into candidate/block-buf
swgiacomelli Aug 11, 2026
2858644
Merge remote-tracking branch 'origin/master' into candidate/counted-s…
swgiacomelli Aug 11, 2026
b368883
Merge remote-tracking branch 'origin/candidate/counted-signal' into HEAD
swgiacomelli Aug 11, 2026
c62ee7f
Merge remote-tracking branch 'origin/master' into HEAD
swgiacomelli Aug 11, 2026
947a28f
Address PR #36 review findings with evidence-backed fixes.
swgiacomelli Aug 11, 2026
8f7f41e
Merge remote-tracking branch 'origin/master' into HEAD
swgiacomelli Aug 11, 2026
aac70c9
Merge remote-tracking branch 'origin/master' into HEAD
swgiacomelli Aug 11, 2026
c800f6a
Merge remote-tracking branch 'origin/master' into HEAD
swgiacomelli Aug 11, 2026
2b692bb
Merge remote-tracking branch 'origin/master' into HEAD
swgiacomelli Aug 11, 2026
c9dd471
Scope ESP32-S3 S32C1I gate to EventFlags hot paths.
swgiacomelli Aug 11, 2026
9d65bdf
Fix CountedSignal stale-MAX short-circuit that dropped post-take incr…
swgiacomelli Aug 11, 2026
329a53a
Confirm CountedSignal Cortex-M3 cycle rows remain 8/7 after the senti…
swgiacomelli Aug 11, 2026
a629eb6
Address the candidate-review findings on the acceptance package
swgiacomelli Aug 11, 2026
2d6f93d
Fail LatestBuf matrices on .data and pin handle !Sync.
swgiacomelli Aug 11, 2026
8ffe532
Pin the handle !Sync compile_fail doctests to E0277
swgiacomelli Aug 11, 2026
203028d
Reconcile the P closure across every surface and pin must_use
swgiacomelli Aug 11, 2026
62a6962
Land the bound block-payload documentation obligations
swgiacomelli Aug 11, 2026
965601f
Add engineering records for SeqRing and EventBuf
swgiacomelli Aug 11, 2026
6d8a9c9
Address the round-2 Codex findings on the acceptance package
swgiacomelli Aug 11, 2026
060ea7c
Correct README: the panicking constructors were removed in 0.3.0
swgiacomelli Aug 11, 2026
fa84c2c
Mirror the X6 silent-zero disclosure in the README
swgiacomelli Aug 11, 2026
2bbae0f
Widen the thumbv6m branch detector to CBZ/CBNZ
swgiacomelli Aug 11, 2026
5941e60
Replace the sentinel CAS with a no-op RMW re-read (P1 fix)
swgiacomelli Aug 11, 2026
34b169c
Address round-3 findings: REGEN recovery hints and honest DMA guidance
swgiacomelli Aug 11, 2026
184a202
Address round-3 findings: Xtensa calls, README tense, test count
swgiacomelli Aug 11, 2026
1cb57b9
Correct the Common Traits section for LatestBuf
swgiacomelli Aug 11, 2026
1af401a
Address the round-1 Codex findings on the SeqRing record
swgiacomelli Aug 11, 2026
609f2e0
Purge the stale sentinel-CAS wording from the public claim surface
swgiacomelli Aug 11, 2026
0348f7c
Correct the record's DMA guidance and measured unit-test count
swgiacomelli Aug 11, 2026
f6587af
Assert generation monotonicity and skipped conservation in the Loom m…
swgiacomelli Aug 11, 2026
d49a2ab
Close three round-4 verification gaps: vacuous filters, section count…
swgiacomelli Aug 11, 2026
2a0b64b
Bound both SeqRing headline guarantees at the sequence span
swgiacomelli Aug 11, 2026
f093364
Carry the span bound to every earlier claim site and fix two precisio…
swgiacomelli Aug 11, 2026
520a6ca
Purge the impossible DMA-target advice from the proposal and changelog
swgiacomelli Aug 11, 2026
0b33b11
Measure the saturated sentinel arm and finish the RMW claim sweep
swgiacomelli Aug 11, 2026
c21836b
Make the slot-reuse Loom model require the reuse it exists to check
swgiacomelli Aug 11, 2026
91aef80
Scope the loop-free claim to source level; count what the harness act…
swgiacomelli Aug 11, 2026
d04f6da
State what the seqlock evidence actually proves, and where .bss cover…
swgiacomelli Aug 11, 2026
2bbccd5
Keep EventFlags Debug opaque — no non-clearing peek through formatting
swgiacomelli Aug 11, 2026
803f523
Pin the producer-side loss ledger in the Loom models
swgiacomelli Aug 11, 2026
320d377
Gate the block-payload baseline from CI
swgiacomelli Aug 11, 2026
3c4608d
Scope B1 to source level with the per-ISA realisation disclosed (P1)
swgiacomelli Aug 11, 2026
48d872c
Make the EventBuf record's numbers and citations verifiable
swgiacomelli Aug 11, 2026
9664762
Retire the last two CAS references and the wait-free label
swgiacomelli Aug 11, 2026
bbc6823
Fail the cycle run when EventFlags state costs diverge
swgiacomelli Aug 11, 2026
7ea2703
Bump version to 0.3.0 on the release branch
swgiacomelli Aug 12, 2026
2db4587
Merge pull request #35 from photon-circus/candidate/latest-buf
swgiacomelli Aug 12, 2026
defc5f6
Merge release/0.3.0 (latest-buf accepted) into candidate/block-buf
swgiacomelli Aug 12, 2026
95d5da9
Merge pull request #34 from photon-circus/candidate/block-buf
swgiacomelli Aug 12, 2026
c35ab25
Bless the block-payload code-size baseline at promotion
swgiacomelli Aug 12, 2026
590ec28
Merge release/0.3.0 (latest-buf and block-buf accepted) into candidat…
swgiacomelli Aug 12, 2026
a62dac5
Merge release/0.3.0 (latest-buf and block-buf accepted) into candidat…
swgiacomelli Aug 12, 2026
b11d713
Merge release/0.3.0 (latest-buf and block-buf accepted) into the reco…
swgiacomelli Aug 12, 2026
a07ead3
Bound the aliasing escape hatch at the resume cursor; carry the span …
swgiacomelli Aug 12, 2026
7db7a9e
Qualify the README's 8-instruction increment row as the below-MAX path
swgiacomelli Aug 12, 2026
1e8e362
State both increment arms in the canonical guide; fix the doctest inv…
swgiacomelli Aug 12, 2026
f0e6994
Scope the state-pair gate to the default probe; match Xtensa narrow b…
swgiacomelli Aug 12, 2026
065c9e2
State the aliasing bound at the resume cursor everywhere; fix skip_to…
swgiacomelli Aug 12, 2026
f41f456
Merge pull request #33 from photon-circus/candidate/counted-signal
swgiacomelli Aug 12, 2026
e8b3130
Merge release/0.3.0 (counted-signal accepted) into candidate/event-flags
swgiacomelli Aug 12, 2026
b0db775
Merge pull request #36 from photon-circus/candidate/event-flags
swgiacomelli Aug 12, 2026
b9b2aa4
Merge release/0.3.0 (counted-signal and event-flags accepted) into th…
swgiacomelli Aug 12, 2026
e9eac03
Merge pull request #39 from photon-circus/claude/feature-dev-issue-ev…
swgiacomelli Aug 12, 2026
49cf88a
Integration pass: coherent 0.3.0 changelog, assembled-tree counts, Se…
swgiacomelli Aug 12, 2026
f72c6ad
Close 0.3.0 changelog and fix adversarial packaging/doc pins.
swgiacomelli Aug 12, 2026
cf77ead
Gate LatestBuf codesize matrices and close Bugbot findings.
swgiacomelli Aug 12, 2026
b849751
Fix both review P1s: clippy SAFETY comment; bound poll_up_to at a fro…
swgiacomelli Aug 12, 2026
354922d
Untrack the maintainer's local verification log
swgiacomelli Aug 12, 2026
7848f59
Close the six review P2s: span propagation, builder span alias, Send …
swgiacomelli Aug 12, 2026
c1699c0
Close the two review P3s: complete the atomic-shim list and the trait…
swgiacomelli Aug 12, 2026
5617f25
Close the six live legacy threads from the component-PR history
swgiacomelli Aug 12, 2026
3ba7cdd
Record headers reflect acceptance: the four 0.3.0 types ship, not await
swgiacomelli Aug 12, 2026
8ce2647
Keep the consumer-handoff model inside loom's path budget under the g…
swgiacomelli Aug 12, 2026
9863d3a
Documentation freshness pass: records current, 0.3.0 value statement,…
swgiacomelli Aug 12, 2026
8c51336
Proposal documents speak as closed design-decision records
swgiacomelli Aug 12, 2026
0114394
Final freshness sweep: AGENTS.md and CONTRIBUTING.md current with the…
swgiacomelli Aug 12, 2026
269b806
Bring the security policy and crate metadata up to the 0.3.0 surface
swgiacomelli Aug 12, 2026
7f86fe8
Rustdoc example sweep: no anti-patterns, no vacuous asserts
swgiacomelli Aug 12, 2026
a4af6ab
GitHub templates current with the 0.3.0 surface
swgiacomelli Aug 12, 2026
4c1ca7d
Script documentation sweep: headers describe the scripts that exist
swgiacomelli Aug 12, 2026
4d3ae42
Release checklist carries the reference-image publish; record links r…
swgiacomelli Aug 12, 2026
d3d4585
docs/ gets a map: README at the root, planning record in docs/planning/
swgiacomelli Aug 13, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 10 additions & 2 deletions .github/ISSUE_TEMPLATE/bug_report.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,15 @@ body:
This includes Miri runs in *your* project — a test that drives the ring
from two threads will report UB pointing into this crate. See the
`seq_ring` module docs for why, and for the alternatives. `EventBuf`
has no such caveat.
and `LatestBuf` have no such caveat — both pass Miri with the race
detector on.

Finally, the **counter-width span boundaries** are documented
limitations, not bugs: `SeqRing` loss accounting, `LatestBuf::skipped`,
and `BlockBuilder` contiguity are each exact below one `2^32 − 1`
span and alias beyond it — see "Known issues" in the changelog and the
module docs for the reachability arithmetic. A case that misbehaves
*within* a documented bound is very much a bug; please file it.

- type: textarea
id: what-happened
Expand All @@ -40,7 +48,7 @@ body:
id: version
attributes:
label: ph-eventing version
placeholder: "0.1.3"
placeholder: "0.3.0"
validations:
required: true

Expand Down
17 changes: 13 additions & 4 deletions .github/ISSUE_TEMPLATE/feature_request.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,13 @@ body:
Constraints any proposal has to live within:

- `#![no_std]`, zero heap allocation, and **zero runtime dependencies**.
- Fixed-size, `T: Copy`, stack-allocated.
- The buffers are SPSC by design. Multi-producer or multi-consumer is a
different data structure, not a flag on this one.
- Fixed-size and zero-allocation; payload-carrying types are `T: Copy`.
- The concurrent primitives are SPSC by design. Multi-producer or
multi-consumer is a different data structure, not a flag on one of
these.
- Every guarantee ships with measured evidence: expect a proposal to be
asked for its cost story (code size, cycles) across targets, not
just its API.

- type: textarea
id: problem
Expand All @@ -36,7 +40,12 @@ body:
label: Alternatives considered
description: >
Including whether an existing type already covers it — `RingBuf`,
`SeqRing`, and `EventBuf` deliberately trade off differently.
`SeqRing`, `EventBuf`, `LatestBuf`, `EventFlags`, `CountedSignal`, and
the `Block`/`BlockBuilder` composition deliberately trade off
differently. If this is a zero-copy / direct-to-slot request, note
that a `SlotPool` design was evaluated in full and deferred with an
adopter-gated reopening trigger (`docs/proposals/slot-pool.md`) — a
real adopter naming that trigger reopens it.

- type: checkboxes
id: constraints
Expand Down
15 changes: 12 additions & 3 deletions .github/PULL_REQUEST_TEMPLATE.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,22 @@ assuming a green check covers them.
- [ ] `./scripts/ci.sh` — all checks pass, **no `SKIP` lines**
(a skipped check is not a passed check; install the tool and re-run)

If this touches atomics, orderings, fences, `unsafe`, or anything in
`seq_ring.rs` / `event_buf.rs` / `sync.rs`:
If this touches atomics, orderings, fences, `unsafe`, or anything in the
concurrent modules (`seq_ring.rs`, `event_buf.rs`, `latest_buf.rs`,
`event_flags.rs`, `counted_signal.rs`, `sync.rs`):

- [ ] `./scripts/miri.sh` — clean
- [ ] `./scripts/loom.sh` — all models verified
- [ ] `./scripts/loom.sh` — all models verified (run via the script: it sets
the preemption bound the gate uses)
- [ ] Ordering changes are justified in a comment, not just in this PR

If this changes an API shape or a hot path:

- [ ] `./scripts/codesize.sh` (plus the relevant matrix mode) — numbers pasted
or baseline deliberately re-blessed with the reasoning stated
- [ ] `./scripts/cycles.sh` for hot-path changes — compared inside the
reference image when measuring against documented numbers

If this touches `Cargo.toml`:

- [ ] `cargo deny check` passes
Expand Down
304 changes: 278 additions & 26 deletions AGENTS.md

Large diffs are not rendered by default.

262 changes: 198 additions & 64 deletions CHANGELOG.md

Large diffs are not rendered by default.

31 changes: 22 additions & 9 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -87,8 +87,9 @@ decision, not a formality.

### Concurrency changes

If you touch atomics, orderings, fences, or unsafe blocks in `SeqRing` or
`EventBuf`, `cargo test` passing is not evidence — a strongly-ordered x86 host
If you touch atomics, orderings, fences, or unsafe blocks in any concurrent
primitive — `SeqRing`, `EventBuf`, `LatestBuf`, `EventFlags`, or
`CountedSignal` — `cargo test` passing is not evidence — a strongly-ordered x86 host
cannot exhibit the bugs that appear on ARM and RISC-V. Run both checkers:

```bash
Expand Down Expand Up @@ -129,10 +130,17 @@ If you change an API shape that embedded callers reach for -- especially
anything touching atomics -- measure it before arguing about it:

```bash
./scripts/codesize.sh # 8 upstream targets
XTENSA=1 ./scripts/codesize.sh # plus ESP32, needs the esp-rs fork
./scripts/codesize.sh # 8 upstream targets, default API rows
./scripts/codesize.sh block-matrix # Block completion/publication shapes
./scripts/codesize.sh latest-matrix # LatestBuf payload matrix
./scripts/codesize.sh latest-block-matrix # LatestBuf/Block composition matrix
XTENSA=1 ./scripts/codesize.sh # plus ESP32, needs the esp-rs fork
```

Each mode gates against its own committed `baseline*.tsv` and `ci.sh` runs all
of them — growth past the tolerance fails, and a re-bless is a deliberate,
reviewed act, never a side effect.

A design that looks cheaper on Cortex-M4 can be markedly worse on Cortex-M0+,
where portable-atomic turns each read-modify-write into an interrupt-disable
critical section, or on RISC-V, where `compare_exchange` lowers to an LR/SC
Expand All @@ -146,17 +154,21 @@ that `rust-toolchain.toml` already declares.
If you change a hot path, measure the time cost as well as the size cost:

```bash
./scripts/cycles.sh
./scripts/cycles.sh # default hot-path regions
./scripts/cycles.sh block-matrix # and the three matrix modes,
./scripts/cycles.sh latest-matrix # same names as codesize.sh
./scripts/cycles.sh latest-block-matrix
```

Needs `qemu-system-arm` (`sudo apt-get install qemu-system-arm`); it skips
cleanly without it. It is deliberately **not** part of `./scripts/ci.sh` —
every other check is satisfied by the pinned toolchain alone, and a check most
contributors cannot run would make a green `ci.sh` mean less rather than more.

The counts are deterministic per QEMU build, not across builds (two of the
eighteen regions were observed to shift by one instruction between builds), so
when comparing against the documented numbers, run inside the reference
The counts are deterministic per QEMU build, not across builds (regions have
been observed to shift by one instruction between builds), and the merged
binary's layout matters too — the documented numbers are measured on the
assembled release tree. When comparing against them, run inside the reference
environment below.

Paste the numbers into your PR, as with `codesize.sh`.
Expand All @@ -168,7 +180,8 @@ matrix with zero SKIPs — are measured in one pinned Docker image, so that
anyone can reproduce the evidence rather than take the README's word for it:

```bash
./scripts/verify.sh # ci + miri + loom + cycles, all inside the image
./scripts/verify.sh # ci + miri + loom + all four cycle modes +
# the EventFlags atomic-window gate, in the image
./scripts/verify.sh cycles # just one of them
./scripts/verify.sh shell # look around
```
Expand Down
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

13 changes: 10 additions & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
[package]
name = "ph-eventing"
version = "0.2.0"
version = "0.3.0"
edition = "2024"
rust-version = "1.92.0"
# no-std and zero-allocation are the entry fee, not the value -- plenty of
# crates clear that bar. Lead with what is actually on offer: predictable
# behaviour and a cost you can measure. See AGENTS.md § What this crate
# optimises for.
description = "Deterministic zero-allocation ring buffers for no-std embedded targets: bounded behaviour, no hidden cost, Loom-verified orderings"
description = "Deterministic zero-allocation SPSC primitives for no-std embedded targets — ring buffers, a latest-value snapshot channel, condition flags, saturating counters, and complete sample blocks: bounded behaviour, measured cost, Loom-verified orderings"
authors = ["Steven Giacomelli <steve@giacomelli.ca>"]
license = "MIT"
repository = "https://github.com/photon-circus/ph-eventing"
Expand Down Expand Up @@ -35,7 +35,9 @@ include = [
"build.rs",
"Cargo.toml",
"LICENSE",
"README.md",
# Root-anchored: a bare `README.md` is gitignore-style and matches every
# README.md in the tree (e.g. docs/records/README.md), which must not ship.
"/README.md",
]

[dependencies]
Expand All @@ -54,6 +56,11 @@ portable-atomic = { version = "1.13", optional = true, default-features = false,
# crate. Test combinations individually — `scripts/ci.sh` does.
[features]
default = []
# Internal, underscore-prefixed, and not part of the public contract: lets the
# QEMU cycle probe (scripts/cycles) construct a saturated CountedSignal so the
# sentinel arm of `increment` is a measured region rather than a source-review
# claim. Enables one #[doc(hidden)] constructor; nothing else.
_cycles-probe = []
portable-atomic = ["dep:portable-atomic"]
portable-atomic-unsafe-assume-single-core = [
"portable-atomic",
Expand Down
Loading