low_latency_data_structures/spsc/
consumer.rs1use std::marker::PhantomData;
2
3use crate::mem::Allocation;
4use crate::shim::cell::Cell;
5use crate::shim::sync::Arc;
6use crate::shim::sync::atomic::AtomicUsize;
7use crate::spsc::queue::Queue;
8
9#[repr(C, align(128))]
10#[derive(Default)]
11pub(super) struct ConsumerState {
12 pub head: AtomicUsize,
13 pub cached_tail: Cell<usize>,
14}
15
16pub struct Consumer<T, const CAPACITY: usize, AllocT: Allocation<T>> {
23 inner: Arc<Queue<T, CAPACITY, AllocT>>,
24 _not_sync: PhantomData<*const ()>,
25}
26
27impl<T, const CAPACITY: usize, AllocT: Allocation<T>> std::fmt::Debug
28 for Consumer<T, CAPACITY, AllocT>
29{
30 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
31 f.debug_struct("Consumer")
32 .field("capacity", &CAPACITY)
33 .finish_non_exhaustive()
34 }
35}
36
37unsafe impl<T: Send, const CAPACITY: usize, AllocT: Allocation<T> + Send> Send
40 for Consumer<T, CAPACITY, AllocT>
41{
42}
43
44impl<T, const CAPACITY: usize, AllocT: Allocation<T>> Consumer<T, CAPACITY, AllocT> {
45 pub(super) fn new(queue: Arc<Queue<T, CAPACITY, AllocT>>) -> Self {
46 Self {
47 inner: queue,
48 _not_sync: PhantomData,
49 }
50 }
51
52 #[inline]
71 #[must_use = "ignoring the popped item silently drops it"]
72 pub fn pop(&self) -> Option<T> {
73 self.inner.pop()
74 }
75}
76
77#[cfg(test)]
78mod tests {
79 use super::*;
80 use crate::mem::test_util::NeverAlloc;
81
82 static_assertions::assert_not_impl_any!(Consumer<u32, 0, NeverAlloc>: Sync);
85}