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