Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

rt(threaded): adjust transition_from_parked behavior after introducing disable_lifo_slot feature #5753

Merged
merged 3 commits into from
Jun 14, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions tokio/src/runtime/scheduler/multi_thread/queue.rs
Original file line number Diff line number Diff line change
Expand Up @@ -105,9 +105,9 @@ pub(crate) fn local<T: 'static>() -> (Steal<T>, Local<T>) {
}

impl<T> Local<T> {
/// Returns true if the queue has entries that can be stolen.
pub(crate) fn is_stealable(&self) -> bool {
!self.inner.is_empty()
/// Returns the number of entries in the queue
pub(crate) fn len(&self) -> usize {
self.inner.len() as usize
}

/// How many tasks can be pushed into the queue
Expand Down
23 changes: 17 additions & 6 deletions tokio/src/runtime/scheduler/multi_thread/worker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -718,9 +718,7 @@ impl Context {
// Place `park` back in `core`
core.park = Some(park);

// If there are tasks available to steal, but this worker is not
// looking for tasks to steal, notify another worker.
if !core.is_searching && core.run_queue.is_stealable() {
if core.should_notify_others() {
self.worker.handle.notify_parked_local();
}

Expand Down Expand Up @@ -846,12 +844,25 @@ impl Core {
worker.handle.transition_worker_from_searching();
}

fn has_tasks(&self) -> bool {
self.lifo_slot.is_some() || self.run_queue.has_tasks()
}

fn should_notify_others(&self) -> bool {
// If there are tasks available to steal, but this worker is not
// looking for tasks to steal, notify another worker.
if self.is_searching {
return false;
}
self.lifo_slot.is_some() as usize + self.run_queue.len() > 1
}

/// Prepares the worker state for parking.
///
/// Returns true if the transition happened, false if there is work to do first.
fn transition_to_parked(&mut self, worker: &Worker) -> bool {
// Workers should not park if they have work to do
if self.lifo_slot.is_some() || self.run_queue.has_tasks() || self.is_traced {
if self.has_tasks() || self.is_traced {
return false;
}

Expand All @@ -877,9 +888,9 @@ impl Core {

/// Returns `true` if the transition happened.
fn transition_from_parked(&mut self, worker: &Worker) -> bool {
// If a task is in the lifo slot, then we must unpark regardless of
// If a task is in the lifo slot/run queue, then we must unpark regardless of
// being notified
if self.lifo_slot.is_some() {
if self.has_tasks() {
// When a worker wakes, it should only transition to the "searching"
// state when the wake originates from another worker *or* a new task
// is pushed. We do *not* want the worker to transition to "searching"
Expand Down