pub struct SpscQueue {
buffer: Vec<UnsafeCell<Option<MessageEnvelope>>>,
capacity: usize,
mask: usize,
head: CachePadded<AtomicU64>,
tail: CachePadded<AtomicU64>,
producer_stats: CachePadded<ProducerStats>,
consumer_stats: CachePadded<ConsumerStats>,
}Expand description
Single-producer single-consumer lock-free ring buffer.
This implementation is truly lock-free: no mutexes, no blocking. It uses atomic head/tail pointers with acquire/release ordering. Since SPSC has exactly one producer and one consumer, no CAS is needed — ordered loads and stores are sufficient.
§Memory Ordering
- Producer: writes data, then
Release-stores head (publishes the write) - Consumer:
Acquire-loads head (observes the write), reads data, thenRelease-stores tail - This matches the GPU-side H2K/K2H queue protocol (volatile + fence)
Fields§
§buffer: Vec<UnsafeCell<Option<MessageEnvelope>>>Ring buffer storage. UnsafeCell for interior mutability without Mutex.
Each slot holds an Option
capacity: usizeCapacity (power of 2).
mask: usizeMask for index wrapping (capacity - 1).
head: CachePadded<AtomicU64>Head pointer (producer writes here, only modified by producer).
Cache-line padded to avoid false sharing with tail.
tail: CachePadded<AtomicU64>Tail pointer (consumer reads from here, only modified by consumer).
Cache-line padded to avoid false sharing with head and stats.
producer_stats: CachePadded<ProducerStats>Producer-side counters (enqueued / dropped / max_depth). Separate cache line from consumer stats so the two sides do not false-share.
consumer_stats: CachePadded<ConsumerStats>Consumer-side counters (dequeued).
Implementations§
Source§impl SpscQueue
impl SpscQueue
Sourcepub fn new(capacity: usize) -> Self
pub fn new(capacity: usize) -> Self
Create a new queue with the given capacity.
Capacity will be rounded up to the next power of 2.
Sourcefn update_max_depth(&self)
fn update_max_depth(&self)
Update max depth statistic. Single producer means no
contention on max_depth — we use fetch_max which is a
single atomic RMW rather than the earlier CAS loop.