photon_ring/lib.rs
1// Copyright 2026 Photon Ring Contributors
2// SPDX-License-Identifier: Apache-2.0
3
4//! # Photon Ring
5//!
6//! Ultra-low-latency SPMC/MPMC pub/sub using stamped ring buffers.
7//!
8//! `no_std` compatible (requires `alloc`). The [`topology`] module uses
9//! OS threads and is available on Linux, macOS, Windows, and other
10//! supported platforms.
11//!
12//! ## Key design
13//!
14//! - **Seqlock per slot** — stamp and payload share a cache line; readers never
15//! take a lock, writers never allocate.
16//! - **`T: Pod`** — restricts payloads to plain-old-data types where every bit
17//! pattern is valid, making torn seqlock reads harmless (no UB).
18//! - **Per-consumer cursor** — zero contention between subscribers.
19//! - **Single-producer** — no write-side synchronisation; the seqlock invariant
20//! is upheld by `&mut self` on [`Publisher::publish`].
21//! - **`atomic-slots` feature** — formally sound variant that uses `AtomicU64` stripes
22//! instead of `write_volatile`. Zero cost on x86-64. See the `atomic-slots` feature flag.
23//! - **Arbitrary capacity** — any ring size >= 2 via Lemire fastmod; power-of-two
24//! uses bitwise AND (zero regression).
25//! - **Companion crates** — [`photon-ring-async`] for runtime-agnostic async wrappers,
26//! [`photon-ring-metrics`] for framework-agnostic observability.
27//!
28//! ## Quick start
29//!
30//! ```
31//! // Low-level SPMC channel
32//! let (mut pub_, subs) = photon_ring::channel::<u64>(64);
33//! let mut sub = subs.subscribe();
34//! pub_.publish(42);
35//! assert_eq!(sub.try_recv(), Ok(42));
36//!
37//! // Named-topic bus
38//! let bus = photon_ring::Photon::<u64>::new(64);
39//! let mut p = bus.publisher("topic-a");
40//! let mut s = bus.subscribe("topic-a");
41//! p.publish(7);
42//! assert_eq!(s.try_recv(), Ok(7));
43//! ```
44
45#![no_std]
46
47extern crate alloc;
48
49#[cfg(any(
50 target_os = "linux",
51 target_os = "macos",
52 target_os = "windows",
53 target_os = "freebsd",
54 target_os = "netbsd",
55 target_os = "android",
56))]
57pub mod affinity;
58pub mod barrier;
59mod bus;
60pub mod channel;
61#[cfg(all(target_os = "linux", feature = "hugepages"))]
62pub mod mem;
63mod pod;
64pub(crate) mod ring;
65mod shutdown;
66pub(crate) mod slot;
67#[cfg(any(
68 target_os = "linux",
69 target_os = "macos",
70 target_os = "windows",
71 target_os = "freebsd",
72 target_os = "netbsd",
73 target_os = "android",
74))]
75pub mod topology;
76mod typed_bus;
77pub mod wait;
78
79pub use barrier::DependencyBarrier;
80pub use bus::Photon;
81pub use channel::{
82 channel, channel_bounded, channel_mpmc, Drain, MpPublisher, PublishError, Publisher,
83 Subscribable, Subscriber, SubscriberGroup, TryRecvError,
84};
85pub use pod::Pod;
86pub use ring::Padded;
87
88/// Derive macro for the [`Pod`] trait. Requires the `derive` feature.
89///
90/// ```ignore
91/// #[derive(photon_ring::DerivePod, Clone, Copy)]
92/// #[repr(C)]
93/// struct Quote { price: f64, volume: u32 }
94/// ```
95#[cfg(feature = "derive")]
96pub use photon_ring_derive::Pod as DerivePod;
97
98/// Derive macro that generates a Pod-compatible wire struct from a domain struct.
99///
100/// Given a struct with `bool`, `Option<numeric>`, `usize`/`isize`, and
101/// `#[repr(u8)]` enum fields, generates `{Name}Wire` plus `From` conversions.
102/// Structs without enum fields get safe `From` impls in both directions;
103/// structs with enum fields get `From<Domain> for Wire` (safe) and
104/// `Wire::into_domain()` (unsafe). Requires the `derive` feature.
105///
106/// ```ignore
107/// #[derive(photon_ring::DeriveMessage)]
108/// struct Order { price: f64, side: Side, filled: bool, tag: Option<u32> }
109/// // Generates: OrderWire, From<Order> for OrderWire, From<OrderWire> for Order
110/// ```
111#[cfg(feature = "derive")]
112pub use photon_ring_derive::Message as DeriveMessage;
113
114pub use shutdown::Shutdown;
115pub use typed_bus::TypedBus;
116pub use wait::WaitStrategy;