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
//! Hardware-clock source polymorphism, expressed as [`proxima_primitives`]
//! pipes instead of a bespoke clock trait — principle 5 ("source
//! polymorphism", today applied to the reactor's readiness sources)
//! applied to time.
//!
//! # Why this is a pipe, not a trait
//!
//! A monotonic tick source — a `read_volatile` on a memory-mapped
//! register, `mrs CNTVCT_EL0`, `rdtsc`, a DMA'd timestamp a device writes
//! into memory — takes nothing and produces a reading. That is exactly
//! [`proxima_primitives::pipe::primitives::Pipe`]'s source shape (`In =
//! (), Out = Ticks`), already in the workspace, already `no_std` +
//! no-alloc, already box-free. Binding a new hardware backend is
//! "implement `Pipe` for your type" — zero edits to this crate, and not
//! even this crate's own trait: it is the workspace's general pipe
//! algebra, the same one the reactor's readiness sources, HTTP handlers,
//! and codec frame pipelines already speak.
//!
//! This crate therefore does **not** define a `MonotonicClock` or
//! `Sleeper` capability trait. Both shapes were checked against the
//! binary rule ("can this be expressed with a pipe? If yes, it does not
//! get a type") by writing the composition, not by arguing about it:
//!
//! - A tick source is `Pipe<In = (), Out = Ticks, Err = Infallible>` —
//! the source form from `Pipe`'s own module doc's "four forms" table.
//! - A sleeper is `Pipe<In = Ticks, Out = (), Err = Infallible>` whose
//! future genuinely pends until the deadline — the sink form, mirrored.
//! Any type implementing this shape, with a future that registers a
//! real waker (a timer interrupt, `prime`'s timer wheel), is a sleeper;
//! there is nothing else to implement. This crate ships no reference
//! sleeper — a correct one needs an interrupt or a runtime's timer
//! wheel, which is a runtime-tier concern, not a leaf crate's.
//! - Converting ticks to wall-clock time is `Pipe<In = Ticks, Out =
//! UnixNanos, Err = Infallible>` — [`anchor::ToUnixNanos`], composed
//! with a source via `.and_then`. There is no `WallClock<C>` wrapper
//! type: the transform stage IS the monotonic-to-wall-clock bridge.
//! - Arbitrating between redundant tick sources (a GPS PPS signal, a PTP
//! grandmaster, a local oscillator, each potentially going stale) is
//! [`proxima_primitives::pipe::fan_in::FanIn`] — see
//! `tests/fan_in_multi_source.rs` for a worked example. No bespoke
//! arbitration machinery needed.
//!
//! What this crate *does* provide: two domain value types
//! ([`ticks::Ticks`], [`unix_nanos::UnixNanos`]) so a caller cannot
//! accidentally mix tick-domain and wall-clock-domain arithmetic, and two
//! small stateful cells ([`coarse::TickCell`], [`anchor::AnchorCell`])
//! that a hardware-facing `Pipe` impl or the wall-clock bridge can hold —
//! plain data-and-synchronization types, not a parallel API to `Pipe`.
//!
//! # Tiers
//!
//! - **Bare `no_std` + no-alloc floor**: [`ticks`], [`unix_nanos`],
//! [`coarse`], [`anchor`] — zero `alloc::`, zero `Box`/`Vec`/`Arc`/
//! `String`. `--no-default-features` both builds for
//! `thumbv7m-none-eabi` and RUNS the crate's unit tests; only the tests
//! that genuinely need threads or an allocator are `std`-gated.
//! - **`std` feature (on by default)**: no extra surface of its own — it
//! turns off `no_std` and admits the thread- and `format!`-using tests.
//! - **`config` feature (std, opt-in)**: `config` — the principle-4
//! config + fluent-builder surface for [`anchor::AnchorCell`]'s initial
//! `(ticks, unix_nanos)` pair. `conflaguration` is std-only, so this
//! lives at the std composition boundary; the no-alloc core never
//! depends on it.