1#![cfg_attr(not(feature = "full"), allow(dead_code))]
2
3use core::cell::UnsafeCell;
10use core::fmt;
11use core::marker::{PhantomData, PhantomPinned};
12use core::mem::ManuallyDrop;
13use core::ptr::{self, NonNull};
14
15pub(crate) struct LinkedList<L, T> {
20 head: Option<NonNull<T>>,
22
23 tail: Option<NonNull<T>>,
25
26 _marker: PhantomData<*const L>,
28}
29
30unsafe impl<L: Link> Send for LinkedList<L, L::Target> where L::Target: Send {}
31unsafe impl<L: Link> Sync for LinkedList<L, L::Target> where L::Target: Sync {}
32
33pub(crate) unsafe trait Link {
44 type Handle;
48
49 type Target;
51
52 #[allow(clippy::wrong_self_convention)]
54 fn as_raw(handle: &Self::Handle) -> NonNull<Self::Target>;
55
56 unsafe fn from_raw(ptr: NonNull<Self::Target>) -> Self::Handle;
58
59 unsafe fn pointers(target: NonNull<Self::Target>) -> NonNull<Pointers<Self::Target>>;
68}
69
70pub(crate) struct Pointers<T> {
72 inner: UnsafeCell<PointersInner<T>>,
73}
74struct PointersInner<T> {
90 prev: Option<NonNull<T>>,
92
93 next: Option<NonNull<T>>,
95
96 _pin: PhantomPinned,
99}
100
101unsafe impl<T: Send> Send for Pointers<T> {}
102unsafe impl<T: Sync> Sync for Pointers<T> {}
103
104impl<L, T> LinkedList<L, T> {
107 pub(crate) const fn new() -> LinkedList<L, T> {
109 LinkedList {
110 head: None,
111 tail: None,
112 _marker: PhantomData,
113 }
114 }
115}
116
117impl<L: Link> LinkedList<L, L::Target> {
118 pub(crate) fn push_front(&mut self, val: L::Handle) {
120 let val = ManuallyDrop::new(val);
122 let ptr = L::as_raw(&val);
123 assert_ne!(self.head, Some(ptr));
124 unsafe {
125 L::pointers(ptr).as_mut().set_next(self.head);
126 L::pointers(ptr).as_mut().set_prev(None);
127
128 if let Some(head) = self.head {
129 L::pointers(head).as_mut().set_prev(Some(ptr));
130 }
131
132 self.head = Some(ptr);
133
134 if self.tail.is_none() {
135 self.tail = Some(ptr);
136 }
137 }
138 }
139
140 pub(crate) fn pop_front(&mut self) -> Option<L::Handle> {
143 unsafe {
144 let head = self.head?;
145 self.head = L::pointers(head).as_ref().get_next();
146
147 if let Some(new_head) = L::pointers(head).as_ref().get_next() {
148 L::pointers(new_head).as_mut().set_prev(None);
149 } else {
150 self.tail = None;
151 }
152
153 L::pointers(head).as_mut().set_prev(None);
154 L::pointers(head).as_mut().set_next(None);
155
156 Some(L::from_raw(head))
157 }
158 }
159
160 pub(crate) fn pop_back(&mut self) -> Option<L::Handle> {
163 unsafe {
164 let last = self.tail?;
165 self.tail = L::pointers(last).as_ref().get_prev();
166
167 if let Some(prev) = L::pointers(last).as_ref().get_prev() {
168 L::pointers(prev).as_mut().set_next(None);
169 } else {
170 self.head = None;
171 }
172
173 L::pointers(last).as_mut().set_prev(None);
174 L::pointers(last).as_mut().set_next(None);
175
176 Some(L::from_raw(last))
177 }
178 }
179
180 pub(crate) fn is_empty(&self) -> bool {
182 if self.head.is_some() {
183 return false;
184 }
185
186 assert!(self.tail.is_none());
187 true
188 }
189
190 pub(crate) unsafe fn remove(&mut self, node: NonNull<L::Target>) -> Option<L::Handle> {
201 if let Some(prev) = L::pointers(node).as_ref().get_prev() {
202 debug_assert_eq!(L::pointers(prev).as_ref().get_next(), Some(node));
203 L::pointers(prev)
204 .as_mut()
205 .set_next(L::pointers(node).as_ref().get_next());
206 } else {
207 if self.head != Some(node) {
208 return None;
209 }
210
211 self.head = L::pointers(node).as_ref().get_next();
212 }
213
214 if let Some(next) = L::pointers(node).as_ref().get_next() {
215 debug_assert_eq!(L::pointers(next).as_ref().get_prev(), Some(node));
216 L::pointers(next)
217 .as_mut()
218 .set_prev(L::pointers(node).as_ref().get_prev());
219 } else {
220 if self.tail != Some(node) {
222 return None;
223 }
224
225 self.tail = L::pointers(node).as_ref().get_prev();
226 }
227
228 L::pointers(node).as_mut().set_next(None);
229 L::pointers(node).as_mut().set_prev(None);
230
231 Some(L::from_raw(node))
232 }
233}
234
235impl<L: Link> fmt::Debug for LinkedList<L, L::Target> {
236 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
237 f.debug_struct("LinkedList")
238 .field("head", &self.head)
239 .field("tail", &self.tail)
240 .finish()
241 }
242}
243
244#[cfg(any(
245 feature = "fs",
246 feature = "rt",
247 all(unix, feature = "process"),
248 feature = "signal",
249 feature = "sync",
250))]
251impl<L: Link> LinkedList<L, L::Target> {
252 pub(crate) fn last(&self) -> Option<&L::Target> {
253 let tail = self.tail.as_ref()?;
254 unsafe { Some(&*tail.as_ptr()) }
255 }
256}
257
258impl<L: Link> Default for LinkedList<L, L::Target> {
259 fn default() -> Self {
260 Self::new()
261 }
262}
263
264cfg_io_driver_impl! {
267 pub(crate) struct DrainFilter<'a, T: Link, F> {
268 list: &'a mut LinkedList<T, T::Target>,
269 filter: F,
270 curr: Option<NonNull<T::Target>>,
271 }
272
273 impl<T: Link> LinkedList<T, T::Target> {
274 pub(crate) fn drain_filter<F>(&mut self, filter: F) -> DrainFilter<'_, T, F>
275 where
276 F: FnMut(&T::Target) -> bool,
277 {
278 let curr = self.head;
279 DrainFilter {
280 curr,
281 filter,
282 list: self,
283 }
284 }
285 }
286
287 impl<'a, T, F> Iterator for DrainFilter<'a, T, F>
288 where
289 T: Link,
290 F: FnMut(&T::Target) -> bool,
291 {
292 type Item = T::Handle;
293
294 fn next(&mut self) -> Option<Self::Item> {
295 while let Some(curr) = self.curr {
296 self.curr = unsafe { T::pointers(curr).as_ref() }.get_next();
298
299 if (self.filter)(unsafe { &mut *curr.as_ptr() }) {
301 return unsafe { self.list.remove(curr) };
302 }
303 }
304
305 None
306 }
307 }
308}
309
310cfg_taskdump! {
311 impl<T: Link> LinkedList<T, T::Target> {
312 pub(crate) fn for_each<F>(&mut self, mut f: F)
313 where
314 F: FnMut(&T::Handle),
315 {
316 let mut next = self.head;
317
318 while let Some(curr) = next {
319 unsafe {
320 let handle = ManuallyDrop::new(T::from_raw(curr));
321 f(&handle);
322 next = T::pointers(curr).as_ref().get_next();
323 }
324 }
325 }
326 }
327}
328
329feature! {
332 #![any(
333 feature = "process",
334 feature = "sync",
335 feature = "rt",
336 feature = "signal",
337 )]
338
339 pub(crate) struct GuardedLinkedList<L, T> {
347 guard: NonNull<T>,
349
350 _marker: PhantomData<*const L>,
352 }
353
354 impl<L: Link> LinkedList<L, L::Target> {
355 pub(crate) fn into_guarded(self, guard_handle: L::Handle) -> GuardedLinkedList<L, L::Target> {
359 let guard = L::as_raw(&guard_handle);
361
362 unsafe {
363 if let Some(head) = self.head {
364 debug_assert!(L::pointers(head).as_ref().get_prev().is_none());
365 L::pointers(head).as_mut().set_prev(Some(guard));
366 L::pointers(guard).as_mut().set_next(Some(head));
367
368 let tail = self.tail.unwrap();
370 debug_assert!(L::pointers(tail).as_ref().get_next().is_none());
371 L::pointers(tail).as_mut().set_next(Some(guard));
372 L::pointers(guard).as_mut().set_prev(Some(tail));
373 } else {
374 L::pointers(guard).as_mut().set_prev(Some(guard));
376 L::pointers(guard).as_mut().set_next(Some(guard));
377 }
378 }
379
380 GuardedLinkedList { guard, _marker: PhantomData }
381 }
382 }
383
384 impl<L: Link> GuardedLinkedList<L, L::Target> {
385 fn tail(&self) -> Option<NonNull<L::Target>> {
386 let tail_ptr = unsafe {
387 L::pointers(self.guard).as_ref().get_prev().unwrap()
388 };
389
390 if tail_ptr != self.guard {
394 Some(tail_ptr)
395 } else {
396 None
397 }
398 }
399
400 pub(crate) fn pop_back(&mut self) -> Option<L::Handle> {
403 unsafe {
404 let last = self.tail()?;
405 let before_last = L::pointers(last).as_ref().get_prev().unwrap();
406
407 L::pointers(self.guard).as_mut().set_prev(Some(before_last));
408 L::pointers(before_last).as_mut().set_next(Some(self.guard));
409
410 L::pointers(last).as_mut().set_prev(None);
411 L::pointers(last).as_mut().set_next(None);
412
413 Some(L::from_raw(last))
414 }
415 }
416 }
417}
418
419impl<T> Pointers<T> {
422 pub(crate) fn new() -> Pointers<T> {
424 Pointers {
425 inner: UnsafeCell::new(PointersInner {
426 prev: None,
427 next: None,
428 _pin: PhantomPinned,
429 }),
430 }
431 }
432
433 pub(crate) fn get_prev(&self) -> Option<NonNull<T>> {
434 unsafe { ptr::addr_of!((*self.inner.get()).prev).read() }
436 }
437 pub(crate) fn get_next(&self) -> Option<NonNull<T>> {
438 unsafe { ptr::addr_of!((*self.inner.get()).next).read() }
440 }
441
442 fn set_prev(&mut self, value: Option<NonNull<T>>) {
443 unsafe {
445 ptr::addr_of_mut!((*self.inner.get()).prev).write(value);
446 }
447 }
448 fn set_next(&mut self, value: Option<NonNull<T>>) {
449 unsafe {
451 ptr::addr_of_mut!((*self.inner.get()).next).write(value);
452 }
453 }
454}
455
456impl<T> fmt::Debug for Pointers<T> {
457 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
458 let prev = self.get_prev();
459 let next = self.get_next();
460 f.debug_struct("Pointers")
461 .field("prev", &prev)
462 .field("next", &next)
463 .finish()
464 }
465}
466
467#[cfg(any(test, fuzzing))]
468#[cfg(not(loom))]
469pub(crate) mod tests {
470 use super::*;
471
472 use std::pin::Pin;
473
474 #[derive(Debug)]
475 #[repr(C)]
476 struct Entry {
477 pointers: Pointers<Entry>,
478 val: i32,
479 }
480
481 unsafe impl<'a> Link for &'a Entry {
482 type Handle = Pin<&'a Entry>;
483 type Target = Entry;
484
485 fn as_raw(handle: &Pin<&'_ Entry>) -> NonNull<Entry> {
486 NonNull::from(handle.get_ref())
487 }
488
489 unsafe fn from_raw(ptr: NonNull<Entry>) -> Pin<&'a Entry> {
490 Pin::new_unchecked(&*ptr.as_ptr())
491 }
492
493 unsafe fn pointers(target: NonNull<Entry>) -> NonNull<Pointers<Entry>> {
494 target.cast()
495 }
496 }
497
498 fn entry(val: i32) -> Pin<Box<Entry>> {
499 Box::pin(Entry {
500 pointers: Pointers::new(),
501 val,
502 })
503 }
504
505 fn ptr(r: &Pin<Box<Entry>>) -> NonNull<Entry> {
506 r.as_ref().get_ref().into()
507 }
508
509 fn collect_list(list: &mut LinkedList<&'_ Entry, <&'_ Entry as Link>::Target>) -> Vec<i32> {
510 let mut ret = vec![];
511
512 while let Some(entry) = list.pop_back() {
513 ret.push(entry.val);
514 }
515
516 ret
517 }
518
519 fn push_all<'a>(
520 list: &mut LinkedList<&'a Entry, <&'_ Entry as Link>::Target>,
521 entries: &[Pin<&'a Entry>],
522 ) {
523 for entry in entries.iter() {
524 list.push_front(*entry);
525 }
526 }
527
528 #[cfg(test)]
529 macro_rules! assert_clean {
530 ($e:ident) => {{
531 assert!($e.pointers.get_next().is_none());
532 assert!($e.pointers.get_prev().is_none());
533 }};
534 }
535
536 #[cfg(test)]
537 macro_rules! assert_ptr_eq {
538 ($a:expr, $b:expr) => {{
539 assert_eq!(Some($a.as_ref().get_ref().into()), $b)
541 }};
542 }
543
544 #[test]
545 fn const_new() {
546 const _: LinkedList<&Entry, <&Entry as Link>::Target> = LinkedList::new();
547 }
548
549 #[test]
550 fn push_and_drain() {
551 let a = entry(5);
552 let b = entry(7);
553 let c = entry(31);
554
555 let mut list = LinkedList::new();
556 assert!(list.is_empty());
557
558 list.push_front(a.as_ref());
559 assert!(!list.is_empty());
560 list.push_front(b.as_ref());
561 list.push_front(c.as_ref());
562
563 let items: Vec<i32> = collect_list(&mut list);
564 assert_eq!([5, 7, 31].to_vec(), items);
565
566 assert!(list.is_empty());
567 }
568
569 #[test]
570 fn push_pop_push_pop() {
571 let a = entry(5);
572 let b = entry(7);
573
574 let mut list = LinkedList::<&Entry, <&Entry as Link>::Target>::new();
575
576 list.push_front(a.as_ref());
577
578 let entry = list.pop_back().unwrap();
579 assert_eq!(5, entry.val);
580 assert!(list.is_empty());
581
582 list.push_front(b.as_ref());
583
584 let entry = list.pop_back().unwrap();
585 assert_eq!(7, entry.val);
586
587 assert!(list.is_empty());
588 assert!(list.pop_back().is_none());
589 }
590
591 #[test]
592 fn remove_by_address() {
593 let a = entry(5);
594 let b = entry(7);
595 let c = entry(31);
596
597 unsafe {
598 let mut list = LinkedList::new();
600
601 push_all(&mut list, &[c.as_ref(), b.as_ref(), a.as_ref()]);
602 assert!(list.remove(ptr(&a)).is_some());
603 assert_clean!(a);
604 assert!(list.remove(ptr(&a)).is_none());
606 assert!(!list.is_empty());
607
608 assert!(list.remove(ptr(&b)).is_some());
609 assert_clean!(b);
610 assert!(list.remove(ptr(&b)).is_none());
612 assert!(!list.is_empty());
613
614 assert!(list.remove(ptr(&c)).is_some());
615 assert_clean!(c);
616 assert!(list.remove(ptr(&c)).is_none());
618 assert!(list.is_empty());
619 }
620
621 unsafe {
622 let mut list = LinkedList::new();
624
625 push_all(&mut list, &[c.as_ref(), b.as_ref(), a.as_ref()]);
626
627 assert!(list.remove(ptr(&a)).is_some());
628 assert_clean!(a);
629
630 assert_ptr_eq!(b, list.head);
631 assert_ptr_eq!(c, b.pointers.get_next());
632 assert_ptr_eq!(b, c.pointers.get_prev());
633
634 let items = collect_list(&mut list);
635 assert_eq!([31, 7].to_vec(), items);
636 }
637
638 unsafe {
639 let mut list = LinkedList::new();
641
642 push_all(&mut list, &[c.as_ref(), b.as_ref(), a.as_ref()]);
643
644 assert!(list.remove(ptr(&b)).is_some());
645 assert_clean!(b);
646
647 assert_ptr_eq!(c, a.pointers.get_next());
648 assert_ptr_eq!(a, c.pointers.get_prev());
649
650 let items = collect_list(&mut list);
651 assert_eq!([31, 5].to_vec(), items);
652 }
653
654 unsafe {
655 let mut list = LinkedList::new();
658
659 push_all(&mut list, &[c.as_ref(), b.as_ref(), a.as_ref()]);
660
661 assert!(list.remove(ptr(&c)).is_some());
662 assert_clean!(c);
663
664 assert!(b.pointers.get_next().is_none());
665 assert_ptr_eq!(b, list.tail);
666
667 let items = collect_list(&mut list);
668 assert_eq!([7, 5].to_vec(), items);
669 }
670
671 unsafe {
672 let mut list = LinkedList::new();
674
675 push_all(&mut list, &[b.as_ref(), a.as_ref()]);
676
677 assert!(list.remove(ptr(&a)).is_some());
678
679 assert_clean!(a);
680
681 assert!(list.remove(ptr(&a)).is_none());
683
684 assert_ptr_eq!(b, list.head);
685 assert_ptr_eq!(b, list.tail);
686
687 assert!(b.pointers.get_next().is_none());
688 assert!(b.pointers.get_prev().is_none());
689
690 let items = collect_list(&mut list);
691 assert_eq!([7].to_vec(), items);
692 }
693
694 unsafe {
695 let mut list = LinkedList::new();
697
698 push_all(&mut list, &[b.as_ref(), a.as_ref()]);
699
700 assert!(list.remove(ptr(&b)).is_some());
701
702 assert_clean!(b);
703
704 assert_ptr_eq!(a, list.head);
705 assert_ptr_eq!(a, list.tail);
706
707 assert!(a.pointers.get_next().is_none());
708 assert!(a.pointers.get_prev().is_none());
709
710 let items = collect_list(&mut list);
711 assert_eq!([5].to_vec(), items);
712 }
713
714 unsafe {
715 let mut list = LinkedList::new();
717
718 push_all(&mut list, &[a.as_ref()]);
719
720 assert!(list.remove(ptr(&a)).is_some());
721 assert_clean!(a);
722
723 assert!(list.head.is_none());
724 assert!(list.tail.is_none());
725 let items = collect_list(&mut list);
726 assert!(items.is_empty());
727 }
728
729 unsafe {
730 let mut list = LinkedList::<&Entry, <&Entry as Link>::Target>::new();
732
733 list.push_front(b.as_ref());
734 list.push_front(a.as_ref());
735
736 assert!(list.remove(ptr(&c)).is_none());
737 }
738 }
739
740 #[cfg(fuzzing)]
742 pub fn fuzz_linked_list(ops: &[u8]) {
743 enum Op {
744 Push,
745 Pop,
746 Remove(usize),
747 }
748 use std::collections::VecDeque;
749
750 let ops = ops
751 .iter()
752 .map(|i| match i % 3u8 {
753 0 => Op::Push,
754 1 => Op::Pop,
755 2 => Op::Remove((i / 3u8) as usize),
756 _ => unreachable!(),
757 })
758 .collect::<Vec<_>>();
759
760 let mut ll = LinkedList::<&Entry, <&Entry as Link>::Target>::new();
761 let mut reference = VecDeque::new();
762
763 let entries: Vec<_> = (0..ops.len()).map(|i| entry(i as i32)).collect();
764
765 for (i, op) in ops.iter().enumerate() {
766 match op {
767 Op::Push => {
768 reference.push_front(i as i32);
769 assert_eq!(entries[i].val, i as i32);
770
771 ll.push_front(entries[i].as_ref());
772 }
773 Op::Pop => {
774 if reference.is_empty() {
775 assert!(ll.is_empty());
776 continue;
777 }
778
779 let v = reference.pop_back();
780 assert_eq!(v, ll.pop_back().map(|v| v.val));
781 }
782 Op::Remove(n) => {
783 if reference.is_empty() {
784 assert!(ll.is_empty());
785 continue;
786 }
787
788 let idx = n % reference.len();
789 let expect = reference.remove(idx).unwrap();
790
791 unsafe {
792 let entry = ll.remove(ptr(&entries[expect as usize])).unwrap();
793 assert_eq!(expect, entry.val);
794 }
795 }
796 }
797 }
798 }
799}