-
Notifications
You must be signed in to change notification settings - Fork 0
8010: runtime: optional eager I/O driver/timer handoff when polling tasks #92
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
base: master
Are you sure you want to change the base?
Changes from all commits
054a5eb
066bfeb
2c80455
e95f046
224f9dc
a5e2bb7
d77de00
8749f32
568d4b0
87257ae
65de590
e277211
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -59,7 +59,7 @@ | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| use crate::loom::sync::{Arc, Mutex}; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| use crate::runtime; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| use crate::runtime::scheduler::multi_thread::{ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| idle, queue, Counters, Handle, Idle, Overflow, Parker, Stats, TraceStatus, Unparker, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| idle, park, queue, Counters, Handle, Idle, Overflow, Parker, Stats, TraceStatus, Unparker, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| use crate::runtime::scheduler::{inject, Defer, Lock}; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| use crate::runtime::task::OwnedTasks; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -132,6 +132,15 @@ struct Core { | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| /// True if the scheduler is being traced | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| is_traced: bool, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| /// Whether or not the worker has just returned from a park in which we | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| /// parked on the I/O driver. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| had_driver: park::HadDriver, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| /// If `true`, the worker should eagerly notify another worker when polling | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| /// the first task after returning from a park in which it parked on the I/O | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| /// or time driver. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| enable_eager_driver_handoff: bool, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| /// Parker | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| /// | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| /// Stored in an `Option` as the parker is added / removed to make the | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -280,6 +289,8 @@ pub(super) fn create( | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| is_searching: false, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| is_shutdown: false, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| is_traced: false, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| enable_eager_driver_handoff: config.enable_eager_driver_handoff, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| had_driver: park::HadDriver::No, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| park: Some(park), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| global_queue_interval: stats.tuned_global_queue_interval(&config), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| stats, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -616,7 +627,30 @@ impl Context { | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // Make sure the worker is not in the **searching** state. This enables | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // another idle worker to try to steal work. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| core.transition_from_searching(&self.worker); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| let notified_parked_worker = core.transition_from_searching(&self.worker); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // If the setting to wake eagerly when releasing the I/O driver is | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // enabled, and this worker had the driver, wake a parked worker to come | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // grab it from us. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // Note that this is only done when we are *actually* about to poll a | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // task, rather than whenever the worker has unparked. When the worker | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // has been unparked, it may not actually have any tasks to poll, and if | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // it's still holding the I/O driver, it should just go back to polling | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // the driver again, rather than trying to wake someone else spuriously. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // Note that this explicitly checks `cfg!(tokio_unstable)` in addition, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // as that should result in this whole expression being eliminated at | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // compile-time when unstable features are disabled. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if cfg!(tokio_unstable) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| && core.enable_eager_driver_handoff | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| && core.had_driver == park::HadDriver::Yes | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| && !notified_parked_worker | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // don't do it a second time | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| core.had_driver = park::HadDriver::No; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| self.worker.handle.notify_parked_local(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| let notified_parked_worker = core.transition_from_searching(&self.worker); | |
| // If the setting to wake eagerly when releasing the I/O driver is | |
| // enabled, and this worker had the driver, wake a parked worker to come | |
| // grab it from us. | |
| // | |
| // Note that this is only done when we are *actually* about to poll a | |
| // task, rather than whenever the worker has unparked. When the worker | |
| // has been unparked, it may not actually have any tasks to poll, and if | |
| // it's still holding the I/O driver, it should just go back to polling | |
| // the driver again, rather than trying to wake someone else spuriously. | |
| // | |
| // Note that this explicitly checks `cfg!(tokio_unstable)` in addition, | |
| // as that should result in this whole expression being eliminated at | |
| // compile-time when unstable features are disabled. | |
| if cfg!(tokio_unstable) | |
| && core.enable_eager_driver_handoff | |
| && core.had_driver == park::HadDriver::Yes | |
| && !notified_parked_worker | |
| // don't do it a second time | |
| { | |
| core.had_driver = park::HadDriver::No; | |
| self.worker.handle.notify_parked_local(); | |
| } | |
| let notified_parked_worker = core.transition_from_searching(&self.worker); | |
| let had_driver = core.had_driver == park::HadDriver::Yes; | |
| core.had_driver = park::HadDriver::No; | |
| // If the setting to wake eagerly when releasing the I/O driver is | |
| // enabled, and this worker had the driver, wake a parked worker to come | |
| // grab it from us. | |
| // | |
| // Note that this is only done when we are *actually* about to poll a | |
| // task, rather than whenever the worker has unparked. When the worker | |
| // has been unparked, it may not actually have any tasks to poll, and if | |
| // it's still holding the I/O driver, it should just go back to polling | |
| // the driver again, rather than trying to wake someone else spuriously. | |
| // | |
| // Note that this explicitly checks `cfg!(tokio_unstable)` in addition, | |
| // as that should result in this whole expression being eliminated at | |
| // compile-time when unstable features are disabled. | |
| if cfg!(tokio_unstable) | |
| && core.enable_eager_driver_handoff | |
| && had_driver | |
| && !notified_parked_worker | |
| { | |
| self.worker.handle.notify_parked_local(); | |
| } |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@tokio/src/runtime/scheduler/multi_thread/worker.rs` around lines 630 - 653,
transition_from_searching() can return true meaning the post-driver state was
already consumed, but core.had_driver remains Yes and can cause a second notify
later; change the logic so that when cfg!(tokio_unstable) &&
core.enable_eager_driver_handoff && core.had_driver == park::HadDriver::Yes you
always reset core.had_driver = park::HadDriver::No immediately, and only call
self.worker.handle.notify_parked_local() conditionally when
notified_parked_worker is false. In other words, move or duplicate the
core.had_driver = No assignment out of the inner conditional so the had_driver
flag is cleared on the first post-park task, and keep notify_parked_local
guarded by !notified_parked_worker; refer to transition_from_searching,
core.had_driver, core.enable_eager_driver_handoff, notified_parked_worker, and
self.worker.handle.notify_parked_local.


There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The
had_driverstate should be reset toNoeven ifnotified_parked_workeris true. If a worker transitions from searching and notifies another worker, it has already fulfilled the "handoff" requirement. Ifhad_driveris not reset in this case, the worker might trigger a redundant notification when polling the next task in its queue, asnotified_parked_workerwill be false for subsequent tasks whilehad_driverremainsYes.