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