1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
//! Loom enumeration test for the SPSC ring.
//!
//! Loom intercepts atomic ops + thread scheduling and exhaustively explores
//! every legal interleaving of `Producer::push` / `Consumer::pop`, asserting
//! the SPSC invariants hold under *every* observed reordering — not just the
//! ones a stress test happened to hit. This catches the kind of bug that
//! survives a million iterations of a real-thread stress test because the
//! racy interleaving only manifests once in a billion.
//!
//! ## Charter
//!
//! `loom` is a charter-exempted dev-only crate (same status as `cargo-fuzz`
//! and `cargo-llvm-cov`): it never enters the runtime dependency closure of
//! `kevy-ring`. The `[target.'cfg(loom)'.dependencies]` gate in Cargo.toml
//! means it only resolves when building under `--cfg loom`. A normal
//! `cargo build` / `cargo test` resolves the std atomics / UnsafeCell / Arc
//! and the loom crate is not even downloaded.
//!
//! ## How to run
//!
//! ```bash
//! RUSTFLAGS="--cfg loom" cargo test -p kevy-ring --test loom --release
//! ```
//!
//! `--release` is recommended: loom's exhaustive search explores tens of
//! thousands of interleavings, and debug builds make each one painfully slow.
//! Total wall-clock is on the order of 1-10s for the cases below.
//!
//! `LOOM_MAX_PREEMPTIONS` (default 2) bounds how aggressive the preemption
//! search is; bumping to 3+ explodes the state space combinatorially. The
//! invariants here are small enough that the default suffices.
use ring;
/// Push N items, pop N items. Loom enumerates every observable interleaving
/// of the producer's `tail.store(Release)` and the consumer's `tail.load(Acquire)`,
/// and the symmetric `head` pair, and asserts:
///
/// - Every push that the API reports as successful corresponds to exactly
/// one observed pop with the same value (no message lost, no duplicated).
/// - Items pop in the exact insertion order (FIFO).
/// - The consumer never reads an uninitialized slot (UB; loom catches this
/// via the underlying UnsafeCell tracking — would panic the model).
/// Capacity-2 ring with wrap-around: push 3 items (one wraps), pop all 3.
/// Stresses the `tail & mask` slot-index computation across a wrap event,
/// where a naïve impl might race the cached-cursor fast path against the
/// shared store/load on the wrap iteration.