diff --git a/tokio/src/runtime/io/registration_set.rs b/tokio/src/runtime/io/registration_set.rs index 2796796de..dda706744 100644 --- a/tokio/src/runtime/io/registration_set.rs +++ b/tokio/src/runtime/io/registration_set.rs @@ -20,7 +20,7 @@ pub(super) struct Synced { is_shutdown: bool, // List of all registrations tracked by the set - registrations: LinkedList, ScheduledIo>, + registrations: LinkedList>, // Registrations that are pending drop. When a `Registration` is dropped, it // stores its `ScheduledIo` in this list. The I/O driver is responsible for diff --git a/tokio/src/runtime/io/scheduled_io.rs b/tokio/src/runtime/io/scheduled_io.rs index 62194ad2c..713d74cbe 100644 --- a/tokio/src/runtime/io/scheduled_io.rs +++ b/tokio/src/runtime/io/scheduled_io.rs @@ -107,12 +107,10 @@ pub(crate) struct ScheduledIo { waiters: Mutex, } -type WaitList = LinkedList::Target>; - #[derive(Debug, Default)] struct Waiters { /// List of all current waiters. - list: WaitList, + list: LinkedList, /// Waker used for `AsyncRead`. reader: Option, diff --git a/tokio/src/runtime/task/list.rs b/tokio/src/runtime/task/list.rs index e4efa242a..6eb8ec800 100644 --- a/tokio/src/runtime/task/list.rs +++ b/tokio/src/runtime/task/list.rs @@ -9,8 +9,8 @@ use crate::future::Future; use crate::loom::cell::UnsafeCell; use crate::runtime::task::{JoinHandle, LocalNotified, Notified, Schedule, SpawnLocation, Task}; -use crate::util::linked_list::{Link, LinkedList}; -use crate::util::sharded_list; +use crate::util::linked_list::LinkedList; +use crate::util::sharded_list::ShardedList; use crate::loom::sync::atomic::{AtomicBool, Ordering}; use std::marker::PhantomData; @@ -56,13 +56,11 @@ cfg_not_has_atomic_u64! { } pub(crate) struct OwnedTasks { - list: List, + list: ShardedList>, pub(crate) id: NonZeroU64, closed: AtomicBool, } -type List = sharded_list::ShardedList, as Link>::Target>; - pub(crate) struct LocalOwnedTasks { inner: UnsafeCell>, pub(crate) id: NonZeroU64, @@ -70,7 +68,7 @@ pub(crate) struct LocalOwnedTasks { } struct OwnedTasksInner { - list: LinkedList, as Link>::Target>, + list: LinkedList>, closed: bool, } @@ -78,7 +76,7 @@ impl OwnedTasks { pub(crate) fn new(num_cores: usize) -> Self { let shard_size = Self::gen_shared_list_size(num_cores); Self { - list: List::new(shard_size), + list: ShardedList::new(shard_size), closed: AtomicBool::new(false), id: get_next_id(), } diff --git a/tokio/src/runtime/time/entry.rs b/tokio/src/runtime/time/entry.rs index bfb465eee..5cc3ff606 100644 --- a/tokio/src/runtime/time/entry.rs +++ b/tokio/src/runtime/time/entry.rs @@ -322,8 +322,6 @@ pub(crate) struct TimerHandle { inner: NonNull, } -pub(super) type EntryList = crate::util::linked_list::LinkedList; - /// The shared state structure of a timer. This structure is shared between the /// frontend (`Entry`) and driver backend. /// diff --git a/tokio/src/runtime/time/mod.rs b/tokio/src/runtime/time/mod.rs index cecd5d0f2..bbdb664c1 100644 --- a/tokio/src/runtime/time/mod.rs +++ b/tokio/src/runtime/time/mod.rs @@ -8,7 +8,7 @@ mod entry; pub(crate) use entry::TimerEntry; -use entry::{EntryList, TimerHandle, TimerShared, MAX_SAFE_MILLIS_DURATION}; +use entry::{TimerHandle, TimerShared, MAX_SAFE_MILLIS_DURATION}; mod handle; pub(crate) use self::handle::Handle; diff --git a/tokio/src/runtime/time/wheel/level.rs b/tokio/src/runtime/time/wheel/level.rs index 2fd20e56f..27b288911 100644 --- a/tokio/src/runtime/time/wheel/level.rs +++ b/tokio/src/runtime/time/wheel/level.rs @@ -1,4 +1,5 @@ -use crate::runtime::time::{EntryList, TimerHandle, TimerShared}; +use crate::runtime::time::{TimerHandle, TimerShared}; +use crate::util::linked_list::LinkedList; use std::{array, fmt, ptr::NonNull}; @@ -16,7 +17,7 @@ pub(crate) struct Level { occupied: u64, /// Slots. We access these via the EntryInner `current_list` as well, so this needs to be an `UnsafeCell`. - slot: [EntryList; LEVEL_MULT], + slot: [LinkedList; LEVEL_MULT], } /// Indicates when a slot must be processed next. @@ -42,7 +43,7 @@ impl Level { Level { level, occupied: 0, - slot: array::from_fn(|_| EntryList::default()), + slot: array::from_fn(|_| LinkedList::default()), } } @@ -140,7 +141,7 @@ impl Level { } } - pub(crate) fn take_slot(&mut self, slot: usize) -> EntryList { + pub(crate) fn take_slot(&mut self, slot: usize) -> LinkedList { self.occupied &= !occupied_bit(slot); std::mem::take(&mut self.slot[slot]) diff --git a/tokio/src/runtime/time/wheel/mod.rs b/tokio/src/runtime/time/wheel/mod.rs index 53ea95958..5c6d8407e 100644 --- a/tokio/src/runtime/time/wheel/mod.rs +++ b/tokio/src/runtime/time/wheel/mod.rs @@ -1,5 +1,6 @@ use crate::runtime::time::{TimerHandle, TimerShared}; use crate::time::error::InsertError; +use crate::util::linked_list::LinkedList; mod level; pub(crate) use self::level::Expiration; @@ -8,7 +9,6 @@ use self::level::Level; use std::ptr::NonNull; use super::entry::STATE_DEREGISTERED; -use super::EntryList; /// Timing wheel implementation. /// @@ -36,7 +36,7 @@ pub(crate) struct Wheel { levels: Box<[Level; NUM_LEVELS]>, /// Entries queued for firing - pending: EntryList, + pending: LinkedList, } /// Number of levels. Each level has 64 slots. By using 6 levels with 64 slots @@ -54,7 +54,7 @@ impl Wheel { Wheel { elapsed: 0, levels: levels.try_into().unwrap(), - pending: EntryList::new(), + pending: LinkedList::new(), } } @@ -263,7 +263,7 @@ impl Wheel { } /// Obtains the list of entries that need processing for the given expiration. - fn take_entries(&mut self, expiration: &Expiration) -> EntryList { + fn take_entries(&mut self, expiration: &Expiration) -> LinkedList { self.levels[expiration.level].take_slot(expiration.slot) } diff --git a/tokio/src/runtime/time_alt/cancellation_queue.rs b/tokio/src/runtime/time_alt/cancellation_queue.rs index 167078e3d..5fe286963 100644 --- a/tokio/src/runtime/time_alt/cancellation_queue.rs +++ b/tokio/src/runtime/time_alt/cancellation_queue.rs @@ -1,12 +1,10 @@ -use super::{CancellationQueueEntry, Entry, EntryHandle}; +use super::{CancellationQueueEntry, EntryHandle}; use crate::loom::sync::{Arc, Mutex}; -use crate::util::linked_list; - -type EntryList = linked_list::LinkedList; +use crate::util::linked_list::LinkedList; #[derive(Debug, Default)] struct Inner { - list: EntryList, + list: LinkedList, } impl Drop for Inner { @@ -21,7 +19,7 @@ impl Drop for Inner { impl Inner { fn new() -> Self { Self { - list: EntryList::new(), + list: LinkedList::new(), } } diff --git a/tokio/src/runtime/time_alt/entry.rs b/tokio/src/runtime/time_alt/entry.rs index ecf8cd8c5..9ebadd26d 100644 --- a/tokio/src/runtime/time_alt/entry.rs +++ b/tokio/src/runtime/time_alt/entry.rs @@ -6,8 +6,6 @@ use std::marker::PhantomPinned; use std::ptr::NonNull; use std::task::{Context, Poll, Waker}; -pub(super) type EntryList = linked_list::LinkedList; - #[derive(Debug, Default)] struct State { cancelled: bool, diff --git a/tokio/src/runtime/time_alt/mod.rs b/tokio/src/runtime/time_alt/mod.rs index 5d528461c..7396f77ea 100644 --- a/tokio/src/runtime/time_alt/mod.rs +++ b/tokio/src/runtime/time_alt/mod.rs @@ -5,8 +5,7 @@ pub(crate) mod cancellation_queue; mod entry; pub(crate) use entry::Handle as EntryHandle; -use entry::{CancellationQueueEntry, RegistrationQueueEntry, WakeQueueEntry}; -use entry::{Entry, EntryList}; +use entry::{CancellationQueueEntry, Entry, RegistrationQueueEntry, WakeQueueEntry}; mod registration_queue; pub(crate) use registration_queue::RegistrationQueue; diff --git a/tokio/src/runtime/time_alt/registration_queue.rs b/tokio/src/runtime/time_alt/registration_queue.rs index d135e5b21..3a473f307 100644 --- a/tokio/src/runtime/time_alt/registration_queue.rs +++ b/tokio/src/runtime/time_alt/registration_queue.rs @@ -1,12 +1,10 @@ -use super::{Entry, EntryHandle, RegistrationQueueEntry}; -use crate::util::linked_list; - -type EntryList = linked_list::LinkedList; +use super::{EntryHandle, RegistrationQueueEntry}; +use crate::util::linked_list::LinkedList; /// A queue of entries that need to be registered in the timer wheel. #[derive(Debug)] pub(crate) struct RegistrationQueue { - list: EntryList, + list: LinkedList, } impl Drop for RegistrationQueue { @@ -21,7 +19,7 @@ impl Drop for RegistrationQueue { impl RegistrationQueue { pub(crate) fn new() -> Self { Self { - list: EntryList::new(), + list: LinkedList::new(), } } @@ -29,7 +27,7 @@ impl RegistrationQueue { /// /// Behavior is undefined if any of the following conditions are violated: /// - /// - [`Entry::extra_pointers`] of `hdl` must not being used. + /// - `Entry::extra_pointers` of `hdl` must not being used. pub(crate) unsafe fn push_front(&mut self, hdl: EntryHandle) { self.list.push_front(hdl); } diff --git a/tokio/src/runtime/time_alt/wake_queue.rs b/tokio/src/runtime/time_alt/wake_queue.rs index 90ab9f6d2..5c67d1a9d 100644 --- a/tokio/src/runtime/time_alt/wake_queue.rs +++ b/tokio/src/runtime/time_alt/wake_queue.rs @@ -1,12 +1,10 @@ -use super::{Entry, EntryHandle, WakeQueueEntry}; -use crate::util::linked_list; - -type EntryList = linked_list::LinkedList; +use super::{EntryHandle, WakeQueueEntry}; +use crate::util::linked_list::LinkedList; /// A queue of entries that need to be woken up. #[derive(Debug)] pub(crate) struct WakeQueue { - list: EntryList, + list: LinkedList, } impl Drop for WakeQueue { @@ -21,7 +19,7 @@ impl Drop for WakeQueue { impl WakeQueue { pub(crate) fn new() -> Self { Self { - list: EntryList::new(), + list: LinkedList::new(), } } @@ -33,7 +31,7 @@ impl WakeQueue { /// /// Behavior is undefined if any of the following conditions are violated: /// - /// - [`Entry::extra_pointers`] of `hdl` must not being used. + /// - `Entry::extra_pointers` of `hdl` must not being used. pub(crate) unsafe fn push_front(&mut self, hdl: EntryHandle) { self.list.push_front(hdl); } diff --git a/tokio/src/runtime/time_alt/wheel/level.rs b/tokio/src/runtime/time_alt/wheel/level.rs index 99309bfe0..6d2d57a07 100644 --- a/tokio/src/runtime/time_alt/wheel/level.rs +++ b/tokio/src/runtime/time_alt/wheel/level.rs @@ -1,4 +1,6 @@ -use super::{EntryHandle, EntryList}; +use crate::util::linked_list::LinkedList; + +use super::{Entry, EntryHandle}; use std::ptr::NonNull; use std::{array, fmt}; @@ -16,7 +18,7 @@ pub(crate) struct Level { occupied: u64, /// Slots. We access these via the EntryInner `current_list` as well, so this needs to be an `UnsafeCell`. - slot: [EntryList; LEVEL_MULT], + slot: [LinkedList; LEVEL_MULT], } /// Indicates when a slot must be processed next. @@ -42,7 +44,7 @@ impl Level { Level { level, occupied: 0, - slot: array::from_fn(|_| EntryList::default()), + slot: array::from_fn(|_| LinkedList::default()), } } @@ -142,7 +144,7 @@ impl Level { } } - pub(crate) fn take_slot(&mut self, slot: usize) -> EntryList { + pub(crate) fn take_slot(&mut self, slot: usize) -> LinkedList { self.occupied &= !occupied_bit(slot); std::mem::take(&mut self.slot[slot]) diff --git a/tokio/src/runtime/time_alt/wheel/mod.rs b/tokio/src/runtime/time_alt/wheel/mod.rs index 541eeba61..e234f71cb 100644 --- a/tokio/src/runtime/time_alt/wheel/mod.rs +++ b/tokio/src/runtime/time_alt/wheel/mod.rs @@ -3,7 +3,9 @@ pub(crate) use self::level::Expiration; use self::level::Level; use super::cancellation_queue::Sender; -use super::{EntryHandle, EntryList, WakeQueue}; +use super::{Entry, EntryHandle, WakeQueue}; + +use crate::util::linked_list::LinkedList; /// Hashed timing wheel implementation. /// @@ -202,7 +204,7 @@ impl Wheel { } /// Obtains the list of entries that need processing for the given expiration. - fn take_entries(&mut self, expiration: &Expiration) -> EntryList { + fn take_entries(&mut self, expiration: &Expiration) -> LinkedList { self.levels[expiration.level].take_slot(expiration.slot) } diff --git a/tokio/src/sync/batch_semaphore.rs b/tokio/src/sync/batch_semaphore.rs index 405cc01fe..202900028 100644 --- a/tokio/src/sync/batch_semaphore.rs +++ b/tokio/src/sync/batch_semaphore.rs @@ -41,7 +41,7 @@ pub(crate) struct Semaphore { } struct Waitlist { - queue: LinkedList::Target>, + queue: LinkedList, closed: bool, } diff --git a/tokio/src/sync/broadcast.rs b/tokio/src/sync/broadcast.rs index 50f637e15..4890b6ebe 100644 --- a/tokio/src/sync/broadcast.rs +++ b/tokio/src/sync/broadcast.rs @@ -370,7 +370,7 @@ struct Tail { closed: bool, /// Receivers waiting for a value. - waiters: LinkedList::Target>, + waiters: LinkedList, } /// Slot in the buffer. @@ -943,7 +943,7 @@ fn new_receiver(shared: Arc>) -> Receiver { /// and gates the access to it on the `Shared.tail` mutex. It also empties /// the list on drop. struct WaitersList<'a, T> { - list: GuardedLinkedList::Target>, + list: GuardedLinkedList, is_empty: bool, shared: &'a Shared, } @@ -961,7 +961,7 @@ impl<'a, T> Drop for WaitersList<'a, T> { impl<'a, T> WaitersList<'a, T> { fn new( - unguarded_list: LinkedList::Target>, + unguarded_list: LinkedList, guard: Pin<&'a Waiter>, shared: &'a Shared, ) -> Self { diff --git a/tokio/src/sync/notify.rs b/tokio/src/sync/notify.rs index 1af800e79..c8270f17d 100644 --- a/tokio/src/sync/notify.rs +++ b/tokio/src/sync/notify.rs @@ -20,9 +20,6 @@ use std::sync::atomic::Ordering::{self, Acquire, Relaxed, Release, SeqCst}; use std::sync::Arc; use std::task::{Context, Poll, Waker}; -type WaitList = LinkedList::Target>; -type GuardedWaitList = GuardedLinkedList::Target>; - /// Notifies a single task to wake up. /// /// `Notify` provides a basic mechanism to notify a single task of an event. @@ -211,7 +208,7 @@ pub struct Notify { // - number of times `notify_waiters` was called can // be modified only if `waiters` lock is held state: AtomicUsize, - waiters: Mutex, + waiters: Mutex>, } #[derive(Debug)] @@ -327,14 +324,14 @@ enum Notification { /// and gates the access to it on `notify.waiters` mutex. It also empties /// the list on drop. struct NotifyWaitersList<'a> { - list: GuardedWaitList, + list: GuardedLinkedList, is_empty: bool, notify: &'a Notify, } impl<'a> NotifyWaitersList<'a> { fn new( - unguarded_list: WaitList, + unguarded_list: LinkedList, guard: Pin<&'a Waiter>, notify: &'a Notify, ) -> NotifyWaitersList<'a> { @@ -349,7 +346,7 @@ impl<'a> NotifyWaitersList<'a> { /// Removes the last element from the guarded list. Modifying this list /// requires an exclusive access to the main list in `Notify`. - fn pop_back_locked(&mut self, _waiters: &mut WaitList) -> Option> { + fn pop_back_locked(&mut self, _waiters: &mut LinkedList) -> Option> { let result = self.list.pop_back(); if result.is_none() { // Save information about emptiness to avoid waiting for lock @@ -747,7 +744,7 @@ impl Notify { fn inner_notify_waiters<'a>( &'a self, curr: usize, - mut waiters: crate::loom::sync::MutexGuard<'a, LinkedList>, + mut waiters: crate::loom::sync::MutexGuard<'a, LinkedList>, ) { if matches!(get_state(curr), EMPTY | NOTIFIED) { // There are no waiting tasks. All we need to do is increment the @@ -842,7 +839,7 @@ impl UnwindSafe for Notify {} impl RefUnwindSafe for Notify {} fn notify_locked( - waiters: &mut WaitList, + waiters: &mut LinkedList, state: &AtomicUsize, curr: usize, strategy: NotifyOneStrategy, @@ -1403,7 +1400,7 @@ fn is_unpin() {} /// While this guard is held, the `Notify` instance's waiter list is locked. pub(crate) struct NotifyGuard<'a> { guarded_notify: &'a Notify, - guarded_waiters: crate::loom::sync::MutexGuard<'a, WaitList>, + guarded_waiters: crate::loom::sync::MutexGuard<'a, LinkedList>, current_state: usize, } diff --git a/tokio/src/util/idle_notified_set.rs b/tokio/src/util/idle_notified_set.rs index ad2660875..4c5177c56 100644 --- a/tokio/src/util/idle_notified_set.rs +++ b/tokio/src/util/idle_notified_set.rs @@ -13,12 +13,9 @@ use std::task::{Context, Waker}; use crate::loom::cell::UnsafeCell; use crate::loom::sync::{Arc, Mutex}; -use crate::util::linked_list::{self, Link}; +use crate::util::linked_list::{self, Link, LinkedList}; use crate::util::{waker_ref, Wake}; -type LinkedList = - linked_list::LinkedList, as linked_list::Link>::Target>; - /// This is the main handle to the collection. pub(crate) struct IdleNotifiedSet { lists: Arc>, @@ -47,8 +44,8 @@ type Lists = Mutex>; /// the destructor of the `IdleNotifiedSet` will clear the two lists, so once /// that object is destroyed, no ref-cycles will remain. struct ListsInner { - notified: LinkedList, - idle: LinkedList, + notified: LinkedList>, + idle: LinkedList>, /// Whenever an element in the `notified` list is woken, this waker will be /// notified and consumed, if it exists. waker: Option, @@ -233,7 +230,7 @@ impl IdleNotifiedSet { /// Call a function on every element in this list. pub(crate) fn for_each(&mut self, mut func: F) { - fn get_ptrs(list: &mut LinkedList, ptrs: &mut Vec<*mut T>) { + fn get_ptrs(list: &mut LinkedList>, ptrs: &mut Vec<*mut T>) { let mut node = list.last(); while let Some(entry) = node { @@ -291,7 +288,7 @@ impl IdleNotifiedSet { // has `my_list` set to `Neither` and that the value has not yet been // dropped. struct AllEntries { - all_entries: LinkedList, + all_entries: LinkedList>, func: F, } @@ -346,7 +343,10 @@ impl IdleNotifiedSet { /// /// The mutex for the entries must be held, and the target list must be such /// that setting `my_list` to `Neither` is ok. -unsafe fn move_to_new_list(from: &mut LinkedList, to: &mut LinkedList) { +unsafe fn move_to_new_list( + from: &mut LinkedList>, + to: &mut LinkedList>, +) { while let Some(entry) = from.pop_back() { entry.my_list.with_mut(|ptr| { // Safety: pointer is accessed while holding the mutex. diff --git a/tokio/src/util/linked_list.rs b/tokio/src/util/linked_list.rs index eba767f16..602526af8 100644 --- a/tokio/src/util/linked_list.rs +++ b/tokio/src/util/linked_list.rs @@ -15,7 +15,7 @@ use core::cell::UnsafeCell; use core::fmt; -use core::marker::{PhantomData, PhantomPinned}; +use core::marker::PhantomPinned; use core::mem::ManuallyDrop; use core::ptr::{self, NonNull}; @@ -23,19 +23,16 @@ use core::ptr::{self, NonNull}; /// /// Currently, the list is not emptied on drop. It is the caller's /// responsibility to ensure the list is empty before dropping it. -pub(crate) struct LinkedList { +pub(crate) struct LinkedList { /// Linked list head - head: Option>, + head: Option>, /// Linked list tail - tail: Option>, - - /// Node type marker. - _marker: PhantomData<*const L>, + tail: Option>, } -unsafe impl Send for LinkedList where L::Target: Send {} -unsafe impl Sync for LinkedList where L::Target: Sync {} +unsafe impl Send for LinkedList where L::Target: Send {} +unsafe impl Sync for LinkedList where L::Target: Sync {} /// Defines how a type is tracked within a linked list. /// @@ -57,7 +54,6 @@ pub(crate) unsafe trait Link { type Target; /// Convert the handle to a raw pointer without consuming the handle. - #[allow(clippy::wrong_self_convention)] fn as_raw(handle: &Self::Handle) -> NonNull; /// Convert the raw pointer to a handle @@ -112,18 +108,15 @@ unsafe impl Sync for Pointers {} // ===== impl LinkedList ===== -impl LinkedList { +impl LinkedList { /// Creates an empty linked list. - pub(crate) const fn new() -> LinkedList { + pub(crate) const fn new() -> LinkedList { LinkedList { head: None, tail: None, - _marker: PhantomData, } } -} -impl LinkedList { /// Adds an element first in the list. pub(crate) fn push_front(&mut self, val: L::Handle) { // The value should not be dropped, it is being inserted into the list @@ -241,7 +234,7 @@ impl LinkedList { } } -impl fmt::Debug for LinkedList { +impl fmt::Debug for LinkedList { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_struct("LinkedList") .field("head", &self.head) @@ -257,14 +250,14 @@ impl fmt::Debug for LinkedList { feature = "signal", feature = "sync", ))] -impl LinkedList { +impl LinkedList { pub(crate) fn last(&self) -> Option<&L::Target> { let tail = self.tail.as_ref()?; unsafe { Some(&*tail.as_ptr()) } } } -impl Default for LinkedList { +impl Default for LinkedList { fn default() -> Self { Self::new() } @@ -273,16 +266,16 @@ impl Default for LinkedList { // ===== impl DrainFilter ===== cfg_io_driver_impl! { - pub(crate) struct DrainFilter<'a, T: Link, F> { - list: &'a mut LinkedList, + pub(crate) struct DrainFilter<'a, L: Link, F> { + list: &'a mut LinkedList, filter: F, - curr: Option>, + curr: Option>, } - impl LinkedList { - pub(crate) fn drain_filter(&mut self, filter: F) -> DrainFilter<'_, T, F> + impl LinkedList { + pub(crate) fn drain_filter(&mut self, filter: F) -> DrainFilter<'_, L, F> where - F: FnMut(&T::Target) -> bool, + F: FnMut(&L::Target) -> bool, { let curr = self.head; DrainFilter { @@ -293,17 +286,16 @@ cfg_io_driver_impl! { } } - impl<'a, T, F> Iterator for DrainFilter<'a, T, F> + impl<'a, L: Link, F> Iterator for DrainFilter<'a, L, F> where - T: Link, - F: FnMut(&T::Target) -> bool, + F: FnMut(&L::Target) -> bool, { - type Item = T::Handle; + type Item = L::Handle; fn next(&mut self) -> Option { while let Some(curr) = self.curr { // safety: the pointer references data contained by the list - self.curr = unsafe { T::pointers(curr).as_ref() }.get_next(); + self.curr = unsafe { L::pointers(curr).as_ref() }.get_next(); // safety: the value is still owned by the linked list. if (self.filter)(unsafe { &mut *curr.as_ptr() }) { @@ -317,18 +309,18 @@ cfg_io_driver_impl! { } cfg_taskdump! { - impl LinkedList { + impl LinkedList { pub(crate) fn for_each(&mut self, mut f: F) where - F: FnMut(&T::Handle), + F: FnMut(&L::Handle), { let mut next = self.head; while let Some(curr) = next { unsafe { - let handle = ManuallyDrop::new(T::from_raw(curr)); + let handle = ManuallyDrop::new(L::from_raw(curr)); f(&handle); - next = T::pointers(curr).as_ref().get_next(); + next = L::pointers(curr).as_ref().get_next(); } } } @@ -352,19 +344,16 @@ feature! { /// /// If a list is empty, then both pointers of the guard node are pointing /// at the guard node itself. - pub(crate) struct GuardedLinkedList { + pub(crate) struct GuardedLinkedList { /// Pointer to the guard node. - guard: NonNull, - - /// Node type marker. - _marker: PhantomData<*const L>, + guard: NonNull, } - impl LinkedList { + impl LinkedList { /// Turns a linked list into the guarded version by linking the guard node /// with the head and tail nodes. Like with other nodes, you should guarantee /// that the guard node is pinned in memory. - pub(crate) fn into_guarded(self, guard_handle: L::Handle) -> GuardedLinkedList { + pub(crate) fn into_guarded(self, guard_handle: L::Handle) -> GuardedLinkedList { // `guard_handle` is a NonNull pointer, we don't have to care about dropping it. let guard = L::as_raw(&guard_handle); @@ -386,11 +375,11 @@ feature! { } } - GuardedLinkedList { guard, _marker: PhantomData } + GuardedLinkedList { guard } } } - impl GuardedLinkedList { + impl GuardedLinkedList { fn tail(&self) -> Option> { let tail_ptr = unsafe { L::pointers(self.guard).as_ref().get_prev().unwrap() @@ -515,7 +504,7 @@ pub(crate) mod tests { r.as_ref().get_ref().into() } - fn collect_list(list: &mut LinkedList<&'_ Entry, <&'_ Entry as Link>::Target>) -> Vec { + fn collect_list(list: &mut LinkedList<&'_ Entry>) -> Vec { let mut ret = vec![]; while let Some(entry) = list.pop_back() { @@ -525,10 +514,7 @@ pub(crate) mod tests { ret } - fn push_all<'a>( - list: &mut LinkedList<&'a Entry, <&'_ Entry as Link>::Target>, - entries: &[Pin<&'a Entry>], - ) { + fn push_all<'a>(list: &mut LinkedList<&'a Entry>, entries: &[Pin<&'a Entry>]) { for entry in entries.iter() { list.push_front(*entry); } @@ -552,7 +538,7 @@ pub(crate) mod tests { #[test] fn const_new() { - const _: LinkedList<&Entry, <&Entry as Link>::Target> = LinkedList::new(); + const _: LinkedList<&Entry> = LinkedList::new(); } #[test] @@ -580,7 +566,7 @@ pub(crate) mod tests { let a = entry(5); let b = entry(7); - let mut list = LinkedList::<&Entry, <&Entry as Link>::Target>::new(); + let mut list = LinkedList::<&Entry>::new(); list.push_front(a.as_ref()); @@ -737,7 +723,7 @@ pub(crate) mod tests { unsafe { // Remove missing - let mut list = LinkedList::<&Entry, <&Entry as Link>::Target>::new(); + let mut list = LinkedList::<&Entry>::new(); list.push_front(b.as_ref()); list.push_front(a.as_ref()); @@ -766,7 +752,7 @@ pub(crate) mod tests { }) .collect::>(); - let mut ll = LinkedList::<&Entry, <&Entry as Link>::Target>::new(); + let mut ll = LinkedList::<&Entry>::new(); let mut reference = VecDeque::new(); let entries: Vec<_> = (0..ops.len()).map(|i| entry(i as i32)).collect(); diff --git a/tokio/src/util/sharded_list.rs b/tokio/src/util/sharded_list.rs index 4fccab693..9249ffede 100644 --- a/tokio/src/util/sharded_list.rs +++ b/tokio/src/util/sharded_list.rs @@ -12,8 +12,8 @@ use super::linked_list::{Link, LinkedList}; /// responsibility to ensure the list is empty before dropping it. /// /// Note: Due to its inner sharded design, the order of nodes cannot be guaranteed. -pub(crate) struct ShardedList { - lists: Box<[Mutex>]>, +pub(crate) struct ShardedList { + lists: Box<[Mutex>]>, added: MetricAtomicU64, count: MetricAtomicUsize, shard_mask: usize, @@ -32,7 +32,15 @@ pub(crate) unsafe trait ShardedListItem: Link { unsafe fn get_shard_id(target: NonNull) -> usize; } -impl ShardedList { +/// Used to get the lock of shard. +pub(crate) struct ShardGuard<'a, L: Link> { + lock: MutexGuard<'a, LinkedList>, + added: &'a MetricAtomicU64, + count: &'a MetricAtomicUsize, + id: usize, +} + +impl ShardedList { /// Creates a new and empty sharded linked list with the specified size. pub(crate) fn new(sharded_size: usize) -> Self { assert!(sharded_size.is_power_of_two()); @@ -46,17 +54,7 @@ impl ShardedList { shard_mask, } } -} -/// Used to get the lock of shard. -pub(crate) struct ShardGuard<'a, L, T> { - lock: MutexGuard<'a, LinkedList>, - added: &'a MetricAtomicU64, - count: &'a MetricAtomicUsize, - id: usize, -} - -impl ShardedList { /// Removes the last element from a list specified by `shard_id` and returns it, or None if it is /// empty. pub(crate) fn pop_back(&self, shard_id: usize) -> Option { @@ -89,7 +87,7 @@ impl ShardedList { } /// Gets the lock of `ShardedList`, makes us have the write permission. - pub(crate) fn lock_shard(&self, val: &L::Handle) -> ShardGuard<'_, L, L::Target> { + pub(crate) fn lock_shard(&self, val: &L::Handle) -> ShardGuard<'_, L> { let id = unsafe { L::get_shard_id(L::as_raw(val)) }; ShardGuard { lock: self.shard_inner(id), @@ -126,13 +124,13 @@ impl ShardedList { } #[inline] - fn shard_inner(&self, id: usize) -> MutexGuard<'_, LinkedList::Target>> { + fn shard_inner(&self, id: usize) -> MutexGuard<'_, LinkedList> { // Safety: This modulo operation ensures that the index is not out of bounds. unsafe { self.lists.get_unchecked(id & self.shard_mask).lock() } } } -impl<'a, L: ShardedListItem> ShardGuard<'a, L, L::Target> { +impl<'a, L: ShardedListItem> ShardGuard<'a, L> { /// Push a value to this shard. pub(crate) fn push(mut self, val: L::Handle) { let id = unsafe { L::get_shard_id(L::as_raw(&val)) }; @@ -144,7 +142,7 @@ impl<'a, L: ShardedListItem> ShardGuard<'a, L, L::Target> { } cfg_taskdump! { - impl ShardedList { + impl ShardedList { pub(crate) fn for_each(&self, mut f: F) where F: FnMut(&L::Handle),