doubly_linked_list/
lib.rs

1#![allow(deref_nullptr)]
2#![feature(core_intrinsics)]
3#![no_std]
4//! implement list_head in linux
5use core::default::Default;
6use core::iter::Iterator;
7
8/// ListHead define
9#[derive(Debug, Copy, Clone)]
10pub struct ListHead {
11    pub prev: *mut ListHead,
12    pub next: *mut ListHead,
13}
14
15unsafe impl Sync for ListHead{}
16unsafe impl Send for ListHead{}
17
18impl Default for ListHead {
19    fn default() -> Self {
20        Self {
21            prev: core::ptr::null_mut(),
22            next: core::ptr::null_mut(),
23        }
24    }
25}
26impl ListHead {
27    pub const fn new() -> Self {
28        Self {
29            prev: core::ptr::null_mut(),
30            next: core::ptr::null_mut(),
31        }
32    }
33}
34
35
36
37#[macro_export]
38macro_rules! list_head_init {
39    ($ident:expr) => {
40        $ident.prev = &$ident as *const _ as *mut _;
41        $ident.next = &$ident as *const _ as *mut _;
42    };
43}
44
45#[macro_export]
46macro_rules! list_head {
47    ($ident:ident) => {
48        let mut $ident = ListHead::default();
49        list_head_init!($ident);
50    };
51}
52
53/// usage
54///```
55/// use doubly_linked_list::*;
56/// use core::ptr::{write_volatile, read_volatile};
57///
58/// struct Demo {
59///    pub list_head: ListHead,
60///    first:usize,
61/// }
62/// list_head!(demo);
63/// let mut demo1 = Demo {
64///    list_head: {
65///        let mut list_head = ListHead::default();
66///        list_head_init!(list_head);
67///        list_head
68///    },
69///    first: 1,
70/// };
71/// list_add!(&demo1.list_head as *const _ as *mut ListHead, &demo as *const _ as *mut ListHead);
72///
73///```
74///
75#[macro_export]
76macro_rules! list_add {
77    ($new:expr,$head:expr) => {
78        list_add_in!($new, $head, (*$head).next);
79    };
80}
81
82#[macro_export]
83macro_rules! list_add_tail {
84    ($new:expr,$head:expr) => {
85        list_add_in_tail!($new, (*$head).prev, $head);
86    };
87}
88
89#[macro_export]
90macro_rules! list_add_in_tail {
91    ($new:expr,$prev:expr,$next:expr) => {
92        // //println!("new:{:?}, prev: {:?}, next: {:?}", $new,$prev, $next);
93        // use volatile to read and write
94        unsafe {
95            (*$prev).next = $new;
96            (*$new).next = $next;
97            (*$new).prev = $prev;
98            (*$next).prev = $new;
99        }
100        // 这里不能使用如下的形式
101        // (*$new).next = $next;
102        // (*$new).prev = $prev;
103        // (*$prev).next = $new;
104        // (*$next).prev = $new;
105        // 原因是可能后面两句会被优化
106    };
107}
108#[macro_export]
109macro_rules! list_add_in {
110    ($new:expr,$prev:expr,$next:expr) => {
111        // //println!("new:{:?}, prev: {:?}, next: {:?}", $new,$prev, $next);
112        // use volatile to read and write
113        unsafe {
114            (*$next).prev = $new;
115            (*$new).next = $next;
116            (*$new).prev = $prev;
117            (*$prev).next = $new;
118            // core::intrinsics::volatile_store((*$new).next, core::intrinsics::volatile_load($next));
119            // core::intrinsics::volatile_store((*$new).prev, core::intrinsics::volatile_load($prev));
120            // core::intrinsics::volatile_store((*$prev).next, core::intrinsics::volatile_load($new));
121            // core::intrinsics::volatile_store((*$next).prev, core::intrinsics::volatile_load($new));
122        }
123        // 这里不能使用如下的形式
124        // (*$new).next = $next;
125        // (*$new).prev = $prev;
126        // (*$prev).next = $new;
127        // (*$next).prev = $new;
128        // 原因是可能后面两句会被优化
129    };
130}
131#[macro_export]
132macro_rules! list_del_check {
133    ($entry:expr) => {
134        unsafe {
135            if (*$entry).next == $entry || (*$entry).prev == $entry {
136                false
137            }else{
138                true
139            }
140        }
141    };
142}
143
144#[macro_export]
145macro_rules! is_list_empty {
146    ($entry:expr) => {
147        !list_del_check!($entry)
148    };
149}
150
151
152#[macro_export]
153macro_rules! list_del {
154    ($entry:expr) => {
155        if(!list_del_check!($entry)){
156            panic!("list_del_check failed");
157        }
158        unsafe {
159            (*(*$entry).next).prev = (*$entry).prev;
160            (*(*$entry).prev).next = (*$entry).next;
161            *$entry = ListHead {
162                prev: core::ptr::null_mut(),
163                next: core::ptr::null_mut(),
164            };
165        }
166    };
167}
168
169#[macro_export]
170macro_rules! offset_of {
171    ($type:ty,$field:ident) => {
172        unsafe { &(*(core::ptr::null::<$type>())).$field as *const _ as usize }
173    };
174}
175
176#[macro_export]
177macro_rules! container_of {
178    ($ptr:expr,$type:ty,$member:ident) => {
179        ($ptr - offset_of!($type, $member)) as *mut $type
180    };
181}
182
183#[macro_export]
184macro_rules! to_list_head_ptr {
185    ($expr:expr) => {
186        &$expr as *const _ as *mut ListHead
187    };
188}
189
190#[macro_export]
191macro_rules! align_to {
192    ($addr:expr, $align:expr) => {
193        ($addr + $align - 1) & !($align - 1)
194    };
195}
196
197impl ListHead {
198    pub fn iter(&self)->Iter{
199        Iter{
200            head:self,
201            cur:self.next,
202        }
203    }
204    pub fn len(&self)->usize{
205        let mut len = 0;
206        for _ in self.iter(){
207            len += 1;
208        }
209        len
210    }
211}
212
213
214
215
216pub struct Iter<'a>{
217    head: &'a ListHead,
218    cur: *mut ListHead,
219}
220
221impl Iterator for Iter<'_> {
222    type Item = *mut ListHead;
223    fn next(&mut self) -> Option<Self::Item> {
224        if self.cur == to_list_head_ptr!(*self.head) {
225            None
226        }else{
227            let ret = self.cur;
228            unsafe {
229                self.cur = (*self.cur).next;
230            }
231            Some(ret)
232        }
233    }
234}
235
236
237
238#[cfg(test)]
239mod test {
240    use super::ListHead;
241    use super::{list_head, list_head_init};
242    #[allow(unused)]
243    #[derive(Debug)]
244    struct Demo {
245        list_head: ListHead,
246        first: usize,
247        second: usize,
248    }
249
250
251    #[test]
252    fn test_list_head_add() {
253        list_head!(head);
254        let mut demo1 = Demo {
255            list_head: ListHead::default(),
256            first: 1,
257            second: 2,
258        };
259        list_head_init!(demo1.list_head);
260        assert_eq!(to_list_head_ptr!(head), head.prev);
261        assert_eq!(head.next, head.prev);
262
263        assert_eq!(demo1.list_head.prev, demo1.list_head.next);
264        assert_eq!(to_list_head_ptr!(demo1.list_head), demo1.list_head.prev);
265
266        // head <--> demo1
267        list_add!(to_list_head_ptr!(demo1.list_head), to_list_head_ptr!(head));
268
269        assert_eq!(head.next, to_list_head_ptr!(demo1.list_head));
270        assert_eq!(head.prev, to_list_head_ptr!(demo1.list_head));
271
272        let mut demo2 = Demo {
273            list_head: ListHead::default(),
274            first: 1,
275            second: 2,
276        };
277        list_head_init!(demo2.list_head);
278        list_add!(to_list_head_ptr!(demo2.list_head), to_list_head_ptr!(head));
279        // head <--> demo2 <--> demo1
280        assert_eq!(head.next, to_list_head_ptr!(demo2.list_head));
281        assert_eq!(head.prev, to_list_head_ptr!(demo1.list_head));
282        assert_eq!(demo1.list_head.prev, to_list_head_ptr!(demo2.list_head));
283        assert_eq!(demo2.list_head.next, to_list_head_ptr!(demo1.list_head));
284        assert_eq!(demo1.list_head.next, to_list_head_ptr!(head));
285        assert_eq!(demo2.list_head.prev, to_list_head_ptr!(head));
286
287        //println!("head.next:{:?}", head.next);
288        //println!("head.prev:{:?}", head.prev);
289        //println!("demo1_list_head:{:?}", to_list_head_ptr!(demo1.list_head));
290        //println!("demo1.prev:{:?}", demo1.list_head.prev);
291        //println!("demo1.next:{:?}", demo1.list_head.next);
292    }
293    #[test]
294    fn test_list_head_add_tail() {
295        list_head!(head);
296        let mut demo1 = Demo {
297            list_head: ListHead::default(),
298            first: 1,
299            second: 2,
300        };
301        list_head_init!(demo1.list_head);
302        assert_eq!(to_list_head_ptr!(head), head.prev);
303        assert_eq!(head.next, head.prev);
304
305        assert_eq!(demo1.list_head.prev, demo1.list_head.next);
306        assert_eq!(to_list_head_ptr!(demo1.list_head), demo1.list_head.prev);
307
308        // head <--> demo1
309        list_add_tail!(to_list_head_ptr!(demo1.list_head), to_list_head_ptr!(head));
310
311        assert_eq!(head.next, to_list_head_ptr!(demo1.list_head));
312        assert_eq!(head.prev, to_list_head_ptr!(demo1.list_head));
313
314        let mut demo2 = Demo {
315            list_head: ListHead::default(),
316            first: 1,
317            second: 2,
318        };
319        list_head_init!(demo2.list_head);
320        list_add_tail!(to_list_head_ptr!(demo2.list_head), to_list_head_ptr!(head));
321        // head <--> demo1 <--> demo2
322        assert_eq!(head.next, to_list_head_ptr!(demo1.list_head));
323        assert_eq!(head.prev, to_list_head_ptr!(demo2.list_head));
324        assert_eq!(demo1.list_head.prev, to_list_head_ptr!(head));
325        assert_eq!(demo2.list_head.next, to_list_head_ptr!(head));
326        assert_eq!(demo1.list_head.next, to_list_head_ptr!(demo2.list_head));
327        assert_eq!(demo2.list_head.prev, to_list_head_ptr!(demo1.list_head));
328
329        //println!("head.next:{:?}", head.next);
330        //println!("head.prev:{:?}", head.prev);
331        //println!("demo1_list_head:{:?}", to_list_head_ptr!(demo1.list_head));
332        //println!("demo1.prev:{:?}", demo1.list_head.prev);
333        //println!("demo1.next:{:?}", demo1.list_head.next);
334    }
335    #[test]
336    fn test_list_del() {
337        list_head!(head);
338        let mut demo1 = Demo {
339            list_head: ListHead::default(),
340            first: 1,
341            second: 2,
342        };
343        list_head_init!(demo1.list_head);
344        // head <--> demo1
345        list_add!(to_list_head_ptr!(demo1.list_head), to_list_head_ptr!(head));
346        let mut demo2 = Demo {
347            list_head: ListHead::default(),
348            first: 1,
349            second: 2,
350        };
351        list_head_init!(demo2.list_head);
352        list_add!(to_list_head_ptr!(demo2.list_head), to_list_head_ptr!(head));
353        // head <--> demo2 <--> demo1
354        list_del!(to_list_head_ptr!(demo2.list_head));
355        // head <--> demo1
356        assert_eq!(head.next, to_list_head_ptr!(demo1.list_head));
357        assert_eq!(head.prev, to_list_head_ptr!(demo1.list_head));
358        assert_eq!(demo1.list_head.next, to_list_head_ptr!(head));
359        assert_eq!(demo1.list_head.prev, to_list_head_ptr!(head));
360
361        list_del!(to_list_head_ptr!(demo1.list_head));
362        // head
363        assert_eq!(head.next, to_list_head_ptr!(head));
364        assert_eq!(head.prev, to_list_head_ptr!(head));
365
366        //println!("head.next:{:?}", head.next);
367        //println!("head.prev:{:?}", head.prev);
368        //println!("demo1_list_head:{:?}", to_list_head_ptr!(demo1.list_head));
369        //println!("demo1.prev:{:?}", demo1.list_head.prev);
370        //println!("demo1.next:{:?}", demo1.list_head.next);
371    }
372    #[test]
373    fn test_offset_of() {
374        let mut demo1 = Demo {
375            list_head: ListHead::default(),
376            first: 1,
377            second: 2,
378        };
379        let list_head_ptr = to_list_head_ptr!(demo1.list_head);
380        let list_head_offset = offset_of!(Demo, list_head);
381        let list_head_ptr2 = list_head_ptr as usize - list_head_offset;
382        let demo1_ptr = list_head_ptr2 as *mut Demo;
383        assert_eq!(demo1_ptr, &mut demo1 as *mut Demo);
384    }
385    #[test]
386    fn test_container_of() {
387        let mut demo1 = Demo {
388            list_head: ListHead::default(),
389            first: 1,
390            second: 2,
391        };
392        let list_head_ptr = to_list_head_ptr!(demo1.list_head);
393        let demo1_ptr = container_of!(list_head_ptr as usize, Demo, list_head);
394        assert_eq!(demo1_ptr, &mut demo1 as *mut Demo);
395    }
396    #[test]
397    fn test_align_to() {
398        assert_eq!(align_to!(1, 8), 8);
399        assert_eq!(align_to!(8, 8), 8);
400        assert_eq!(align_to!(9, 8), 16);
401        assert_eq!(align_to!(16, 8), 16);
402        assert_eq!(align_to!(17, 8), 24);
403    }
404
405    #[test]
406    fn test_list_head_iter(){
407        list_head!(head); //链表头
408        list_head!(head2); //链表头
409        list_head!(head3); //链表头
410        list_add_tail!(to_list_head_ptr!(head2), to_list_head_ptr!(head));
411        list_add_tail!(to_list_head_ptr!(head3), to_list_head_ptr!(head));
412        let x = &head;
413        x.iter().for_each(|_list_head|{
414            //println!("list_head:{:?}", list_head);
415        });
416        assert_eq!(x.next, to_list_head_ptr!(head2));
417        assert_eq!(x.len(), 2);
418    }
419}