ach_linked/
lib.rs

1#![no_std]
2use core::marker::PhantomPinned;
3use core::ops::{Deref, DerefMut};
4use core::ptr::{self, NonNull};
5use core::sync::atomic::{AtomicPtr, Ordering::Relaxed};
6
7pub struct Node<T> {
8    val: T,
9    next: Option<NonNull<Node<T>>>,
10    _pin: PhantomPinned,
11}
12impl<T> Node<T> {
13    pub const fn new(val: T) -> Self {
14        Self {
15            val,
16            next: None,
17            _pin: PhantomPinned,
18        }
19    }
20    pub fn next(&mut self) -> Option<&mut Node<T>> {
21        unsafe { Some(self.next?.as_mut()) }
22    }
23    pub fn take_next<'a,'b>(&'a mut self) -> Option<&'b mut Node<T>> {
24        unsafe { Some(self.next.take()?.as_mut()) }
25    }
26    pub fn last(&mut self) -> &mut Node<T> {
27        let mut now = self;
28        loop {
29            if let Some(next) = &mut now.next {
30                now = unsafe { next.as_mut() };
31            } else {
32                return now;
33            }
34        }
35    }
36    /// Adds a node to the LinkedList.
37    ///  
38    /// Safety:
39    /// This function is only safe as long as `node` is guaranteed to
40    /// get removed from the list before it gets moved or dropped.
41    pub unsafe fn push(&mut self, node: &mut Node<T>) {
42        assert!(node.next.is_none());
43        node.next = self.next;
44        self.next = Some(node.into());
45    }
46    /// Adds a list to the LinkedList.
47    ///
48    /// Safety:
49    /// This function is only safe as long as `node` is guaranteed to
50    /// get removed from the list before it gets moved or dropped.
51    pub unsafe fn push_list(&mut self, node: &mut Node<T>) {
52        let last = node.last() as *mut Node<T>;
53        (*last).next = self.next;
54        self.next = Some(node.into());
55    }
56    /// remove child which eq node.
57    ///
58    /// Notice: can't remove head node.
59    pub fn remove_node(&mut self, node: &mut Node<T>) -> bool {
60        let mut now = self;
61        loop {
62            if let Some(next) = &mut now.next {
63                let next = unsafe { next.as_mut() };
64                if next as *const _ == node as *const _ {
65                    now.next = next.next;
66                    return true;
67                }
68                now = next;
69            } else {
70                return false;
71            }
72        }
73    }
74    pub fn into_iter(&mut self) -> NodeIter<T> {
75        NodeIter { node: Some(self) }
76    }
77}
78impl<T> Deref for Node<T> {
79    type Target = T;
80    fn deref(&self) -> &Self::Target {
81        &self.val
82    }
83}
84impl<T> DerefMut for Node<T> {
85    fn deref_mut(&mut self) -> &mut Self::Target {
86        &mut self.val
87    }
88}
89
90pub struct NodeIter<'a, T> {
91    node: Option<&'a mut Node<T>>,
92}
93impl<'a, T> Iterator for NodeIter<'a, T> {
94    type Item = &'a mut Node<T>;
95    fn next(&mut self) -> Option<Self::Item> {
96        let node = self.node.as_mut().map(|x| *x as *mut Node<T>);
97        if let Some(node) = node.map(|x| unsafe { &mut *x }) {
98            let next = node.take_next();
99            self.node = next;
100            Some(node)
101        } else {
102            None
103        }
104    }
105}
106
107pub struct LinkedList<T> {
108    head: AtomicPtr<Node<T>>,
109    will_remove: [AtomicPtr<Node<T>>; 4],
110}
111impl<T> LinkedList<T> {
112    const NONE_NODE: AtomicPtr<Node<T>> = AtomicPtr::new(ptr::null_mut());
113    pub const fn new() -> Self {
114        Self {
115            head: Self::NONE_NODE,
116            will_remove: [Self::NONE_NODE; 4],
117        }
118    }
119
120    pub fn is_empty(&self) -> bool {
121        let head = self.head.load(Relaxed);
122        head.is_null()
123    }
124
125    /// delete all entries from LinkedList
126    ///
127    /// If list is empty, return NULL, otherwise, delete all entries and return the pointer to the first entry.
128    pub fn take_all(&self) -> Option<&mut Node<T>> {
129        unsafe { self.head.swap(ptr::null_mut(), Relaxed).as_mut() }
130    }
131
132    /// Adds a node to the LinkedList.
133    ///  
134    /// Safety:
135    /// This function is only safe as long as `node` is guaranteed to
136    /// get removed from the list before it gets moved or dropped.
137    pub unsafe fn push(&self, node: &mut Node<T>) {
138        assert!(node.next.is_none());
139        self.head
140            .fetch_update(Relaxed, Relaxed, |p| {
141                node.next = p.as_mut().map(|x| x.into());
142                Some(node)
143            })
144            .unwrap();
145    }
146    /// Adds a list to the LinkedList.
147    ///
148    /// Safety:
149    /// This function is only safe as long as `node` is guaranteed to
150    /// get removed from the list before it gets moved or dropped.
151    pub unsafe fn push_list(&self, node: &mut Node<T>) {
152        let last = node.last() as *mut Node<T>;
153        self.head
154            .fetch_update(Relaxed, Relaxed, |p| {
155                (*last).next = p.as_mut().map(|x| x.into());
156                Some(node)
157            })
158            .unwrap();
159    }
160
161    /// Removes a node from the LinkedList.
162    pub fn remove(&self, node: &mut Node<T>) {
163        let my_node = loop {
164            let node = self.will_remove.iter().find(|x| {
165                x.compare_exchange(ptr::null_mut(), node as *mut _, Relaxed, Relaxed)
166                    .is_ok()
167            });
168            if let Some(node) = node {
169                break node;
170            }
171            spin_loop::spin();
172        };
173
174        let mut root = self.take_all();
175        loop {
176            while let Some(node) = &mut root {
177                let next = node.take_next();
178                if self
179                    .will_remove
180                    .iter()
181                    .find(|x| {
182                        x.compare_exchange((*node) as *mut _, ptr::null_mut(), Relaxed, Relaxed)
183                            .is_ok()
184                    })
185                    .is_none()
186                {
187                    unsafe { self.push(*node) };
188                }
189                drop(node);
190                root = next;
191            }
192            if my_node.load(Relaxed) != node as *mut _ {
193                return;
194            }
195            spin_loop::spin();
196            let new_root = self.take_all();
197            root = new_root;
198        }
199    }
200}