Merge pull request #1748 from lorislibralato/main

Avoid calling pend() when waking expired timers
This commit is contained in:
Dario Nieuwenhuis 2023-08-10 15:10:10 +00:00 committed by GitHub
commit 43e2edfbda
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -409,7 +409,7 @@ impl SyncExecutor {
#[allow(clippy::never_loop)] #[allow(clippy::never_loop)]
loop { loop {
#[cfg(feature = "integrated-timers")] #[cfg(feature = "integrated-timers")]
self.timer_queue.dequeue_expired(Instant::now(), |task| wake_task(task)); self.timer_queue.dequeue_expired(Instant::now(), wake_task_no_pend);
self.run_queue.dequeue_all(|p| { self.run_queue.dequeue_all(|p| {
let task = p.header(); let task = p.header();
@ -573,6 +573,31 @@ pub fn wake_task(task: TaskRef) {
} }
} }
/// Wake a task by `TaskRef` without calling pend.
///
/// You can obtain a `TaskRef` from a `Waker` using [`task_from_waker`].
pub fn wake_task_no_pend(task: TaskRef) {
let header = task.header();
let res = header.state.fetch_update(Ordering::SeqCst, Ordering::SeqCst, |state| {
// If already scheduled, or if not started,
if (state & STATE_RUN_QUEUED != 0) || (state & STATE_SPAWNED == 0) {
None
} else {
// Mark it as scheduled
Some(state | STATE_RUN_QUEUED)
}
});
if res.is_ok() {
// We have just marked the task as scheduled, so enqueue it.
unsafe {
let executor = header.executor.get().unwrap_unchecked();
executor.run_queue.enqueue(task);
}
}
}
#[cfg(feature = "integrated-timers")] #[cfg(feature = "integrated-timers")]
struct TimerQueue; struct TimerQueue;