Skip to main content

Crate proxima_clock

Crate proxima_clock 

Source
Expand description

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.

Modules§

anchor
coarse
ticks
unix_nanos