low_latency_data_structures/spmc/
producer.rs1use std::marker::PhantomData;
2use std::sync::Arc;
3use std::sync::atomic::AtomicUsize;
4
5use crossbeam_utils::CachePadded;
6
7use crate::mem::Allocator;
8use crate::spmc::queue::{Queue, Slot};
9
10pub(super) type ProducerState = CachePadded<ProducerStateInner>;
11
12pub(super) struct ProducerStateInner {
13 pub(super) write_cursor: AtomicUsize,
14}
15
16pub struct Producer<T, const CAPACITY: usize, A>
28where
29 T: bytemuck::AnyBitPattern,
30 A: Allocator,
31{
32 inner: Arc<Queue<T, CAPACITY, A>>,
33 _not_sync: PhantomData<*const ()>,
34}
35
36impl<T, const CAPACITY: usize, A> std::fmt::Debug for Producer<T, CAPACITY, A>
37where
38 T: bytemuck::AnyBitPattern,
39 A: Allocator,
40{
41 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
42 f.debug_struct("Producer")
43 .field("capacity", &CAPACITY)
44 .finish_non_exhaustive()
45 }
46}
47
48unsafe impl<T, const CAPACITY: usize, A> Send for Producer<T, CAPACITY, A>
50where
51 A: Allocator,
52 T: bytemuck::AnyBitPattern + Send,
53 A::Allocation<Slot<T>>: Send,
54{
55}
56
57#[cfg(test)]
58mod tests {
59 use super::*;
60 use crate::mem::test_util::NeverAllocator;
61
62 static_assertions::assert_impl_all!(Producer<u32, 1, NeverAllocator>: Send);
63 static_assertions::assert_not_impl_any!(Producer<u32, 1, NeverAllocator>: Sync, Clone, Copy);
64}
65
66impl<T, const CAPACITY: usize, A> Producer<T, CAPACITY, A>
67where
68 T: bytemuck::AnyBitPattern,
69 A: Allocator,
70{
71 pub(super) fn new(queue: Arc<Queue<T, CAPACITY, A>>) -> Self {
72 Self {
73 inner: queue,
74 _not_sync: PhantomData,
75 }
76 }
77
78 #[inline]
98 pub fn publish(&self, value: T) {
99 self.inner.publish(value)
100 }
101}