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
//! L1: synchronization primitives for the `pragma.core` scheduler.
//!
//! The only workspace crate where `unsafe` is allowed (see `layers.toml`,
//! `DECISIONS.md` #6). Rules: every block carries a `// SAFETY:` comment,
//! tests run under `cargo +nightly miri test -p pragma_sync`, and atomic protocols are
//! model-checked via `RUSTFLAGS="--cfg loom" cargo test -p pragma_sync --release --lib --tests`.
//!
//! | Primitive | Purpose |
//! |---|---|
//! | [`CountLatch`] | Wait for N events |
//! | [`AtomicCounter`] | Task counter of a group; wait for zero while helping to run work |
//! | [`current_label`] / [`TaskLabel`] | The thread's task label for the panic hook and crash reports |
//!
//! Scheduler building blocks (`ArrivalCounter`, `Parker`, `scope`, `join_on_stack`,
//! `run_labeled` and others) live in the hidden module `__private`: `pragma_jobs` uses them, they
//! change together with it and are **not covered by semver guarantees** (DECISIONS #42).
//!
//! ```
//! use pragma_sync::{AtomicCounter, CountLatch};
//! use std::sync::Arc;
//!
//! let latch = Arc::new(CountLatch::new(2));
//! let workers: Vec<_> = (0..2)
//! .map(|_| {
//! let latch = Arc::clone(&latch);
//! std::thread::spawn(move || latch.count_down())
//! })
//! .collect();
//! latch.wait();
//! assert!(latch.is_released());
//! # for w in workers { w.join().unwrap(); }
//!
//! let pending = AtomicCounter::new(0);
//! pending.increment()?;
//! assert!(pending.decrement()); // reached zero
//! pending.wait(); // returns immediately
//! # Ok::<(), pragma_sync::SyncError>(())
//! ```
pub use AtomicCounter;
pub use SyncError;
pub use ;
pub use CountLatch;
/// Scheduler internals for the `pragma.core` crates. **Not covered by semver guarantees**:
/// they change in any release together with `pragma_jobs`, which depends on this crate with an exact
/// version (DECISIONS #42).