Skip to content

Commit

Permalink
util: make WakeList::wake_all use FIFO ordering
Browse files Browse the repository at this point in the history
  • Loading branch information
paolobarbolini committed Apr 28, 2024
1 parent d33fdd8 commit 02d74a1
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 5 deletions.
20 changes: 20 additions & 0 deletions tokio/src/util/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,26 @@ mod wake_list;
))]
pub(crate) use wake_list::WakeList;

// Used by `wake_list`
#[cfg(any(
feature = "net",
feature = "process",
feature = "sync",
feature = "fs",
feature = "rt",
feature = "signal",
))]
mod noop_waker;
#[cfg(any(
feature = "net",
feature = "process",
feature = "sync",
feature = "fs",
feature = "rt",
feature = "signal",
))]
pub(crate) use noop_waker::noop_waker;

#[cfg(any(
feature = "fs",
feature = "net",
Expand Down
19 changes: 19 additions & 0 deletions tokio/src/util/noop_waker.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
use core::ptr::null;
use core::task::{RawWaker, RawWakerVTable, Waker};

unsafe fn noop_clone(_data: *const ()) -> RawWaker {
noop_raw_waker()
}

unsafe fn noop(_data: *const ()) {}

const NOOP_WAKER_VTABLE: RawWakerVTable = RawWakerVTable::new(noop_clone, noop, noop, noop);

fn noop_raw_waker() -> RawWaker {
RawWaker::new(null(), &NOOP_WAKER_VTABLE)
}

/// A [`Waker`] which does nothing.
pub(crate) fn noop_waker() -> Waker {
unsafe { Waker::from_raw(noop_raw_waker()) }
}
12 changes: 7 additions & 5 deletions tokio/src/util/wake_list.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ use core::mem::MaybeUninit;
use core::ptr;
use std::task::Waker;

use crate::util::noop_waker;

const NUM_WAKERS: usize = 32;

/// A list of wakers to be woken.
Expand Down Expand Up @@ -38,11 +40,11 @@ impl WakeList {

pub(crate) fn wake_all(&mut self) {
assert!(self.curr <= NUM_WAKERS);
while self.curr > 0 {
self.curr -= 1;
// SAFETY: The first `curr` elements of `WakeList` are initialized, so by decrementing
// `curr`, we can take ownership of the last item.
let waker = unsafe { ptr::read(self.inner[self.curr].as_mut_ptr()) };
for i in 0..self.curr {
// SAFETY: The first `curr` elements are initialized
let waker = unsafe {
ptr::replace(self.inner.as_mut_ptr().add(i).cast::<Waker>(), noop_waker())
};
waker.wake();
}
}
Expand Down

0 comments on commit 02d74a1

Please sign in to comment.