heapless/pool/
treiber.rs
1use core::mem::ManuallyDrop;
2
3#[cfg_attr(target_arch = "x86", path = "treiber/cas.rs")]
4#[cfg_attr(arm_llsc, path = "treiber/llsc.rs")]
5mod impl_;
6
7pub use impl_::{AtomicPtr, NonNullPtr};
8
9pub struct Stack<N>
10where
11 N: Node,
12{
13 top: AtomicPtr<N>,
14}
15
16impl<N> Stack<N>
17where
18 N: Node,
19{
20 pub const fn new() -> Self {
21 Self {
22 top: AtomicPtr::null(),
23 }
24 }
25
26 pub unsafe fn push(&self, node: NonNullPtr<N>) {
30 impl_::push(self, node)
31 }
32
33 pub fn try_pop(&self) -> Option<NonNullPtr<N>> {
34 impl_::try_pop(self)
35 }
36}
37
38pub trait Node: Sized {
39 type Data;
40
41 fn next(&self) -> &AtomicPtr<Self>;
42 fn next_mut(&mut self) -> &mut AtomicPtr<Self>;
43}
44
45pub union UnionNode<T> {
46 next: ManuallyDrop<AtomicPtr<UnionNode<T>>>,
47 pub data: ManuallyDrop<T>,
48}
49
50impl<T> Node for UnionNode<T> {
51 type Data = T;
52
53 fn next(&self) -> &AtomicPtr<Self> {
54 unsafe { &self.next }
55 }
56
57 fn next_mut(&mut self) -> &mut AtomicPtr<Self> {
58 unsafe { &mut self.next }
59 }
60}
61
62pub struct StructNode<T> {
63 pub next: ManuallyDrop<AtomicPtr<StructNode<T>>>,
64 pub data: ManuallyDrop<T>,
65}
66
67impl<T> Node for StructNode<T> {
68 type Data = T;
69
70 fn next(&self) -> &AtomicPtr<Self> {
71 &self.next
72 }
73
74 fn next_mut(&mut self) -> &mut AtomicPtr<Self> {
75 &mut self.next
76 }
77}
78
79#[cfg(test)]
80mod tests {
81 use core::mem;
82
83 use super::*;
84
85 #[test]
86 fn node_is_never_zero_sized() {
87 struct Zst;
88
89 assert_ne!(mem::size_of::<UnionNode<Zst>>(), 0);
90 }
91}