-
-
Notifications
You must be signed in to change notification settings - Fork 2.8k
time: delay the cancellation of timers #7467
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?
Conversation
c2d5790 to
d04c22f
Compare
| } | ||
|
|
||
| #[tokio::test] | ||
| async fn reset_later_after_slot_starts() { |
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.
Note
This test was removed because it was testing the behavior of tokio::runtime::time::entry::reset, which is removed in this PR.
| } | ||
|
|
||
| #[tokio::test] | ||
| async fn reset_earlier_after_slot_starts() { |
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.
Note
This test was removed because it was testing the behavior of tokio::runtime::time::entry::reset, which is removed in this PR.
| sleep(ms(20)).await; | ||
|
|
||
| assert!(queue.is_woken()); | ||
| assert_ready_some!(poll!(queue)); |
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.
Note
queue.reset_at resets inner Sleep, however, the new implementation will drop the inner timer and create a new one. So the waker will not be called, we have to poll manually.
| sleep(ms(20)).await; | ||
|
|
||
| assert!(queue.is_woken()); | ||
| assert_ready_some!(poll!(queue)); |
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.
Note
queue.reset_at resets inner Sleep, however, the new implementation will drop the inner timer and create a new one. So the waker will not be called, we have to poll manually.
695eea8 to
e9255ee
Compare
| feature = "signal", | ||
| feature = "time", | ||
| ))] | ||
| pub(crate) use wake_list::WakeList; |
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.
Note
We no long use WakeList in the time subsystem.
Signed-off-by: ADD-SP <[email protected]>
Signed-off-by: ADD-SP <[email protected]>
| CARGO_TARGET_WASM32_WASIP1_RUNNER: "wasmtime run --" | ||
| CARGO_TARGET_WASM32_WASIP1_THREADS_RUNNER: "wasmtime run -W bulk-memory=y -W threads=y -S threads=y --" | ||
| RUSTFLAGS: --cfg tokio_unstable -Dwarnings -C target-feature=+atomics,+bulk-memory -C link-args=--max-memory=67108864 | ||
| RUSTDOCFLAGS: -C link-args=--max-memory=67108864 |
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.
Note
tokio/tokio-util/src/io/sync_bridge.rs
Line 91 in d060401
| /// let mut data = vec![0; 16 * 1024]; |
Signed-off-by: ADD-SP <[email protected]>
Signed-off-by: ADD-SP <[email protected]>
Signed-off-by: ADD-SP <[email protected]>
Signed-off-by: ADD-SP <[email protected]>
Signed-off-by: ADD-SP <[email protected]>
Remove debug print statement for new entry creation.
Signed-off-by: ADD-SP <[email protected]>
Signed-off-by: ADD-SP <[email protected]>
Signed-off-by: ADD-SP <[email protected]>
| let (core, ()) = self.enter_with_time_context(core, |time_cx| { | ||
| util::time::post_auto_advance(&handle.driver, auto_advance_duration); | ||
| util::time::process_expired_timers(&mut time_cx.wheel, &handle.driver); |
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.
Can we avoid the RefCell like this?
- Obtain linked list of timers to wake up, while holding
RefMuton core. - Release
RefMuton core. - Iterate linked list to wake up tasks, without
RefMut.
| util::time::remove_cancelled_timers(&mut time_cx.wheel, &mut time_cx.canc_rx); | ||
| let should_yield = util::time::insert_inject_timers( | ||
| &mut time_cx.wheel, | ||
| &time_cx.canc_tx, | ||
| handle.take_remote_timers(), | ||
| ); |
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.
For cancellation, we probably also have to move timers to linked list, and cancel after releasing RefMut. (I think.)
| pub(crate) fn push_remote_timer(&self, hdl: EntryHandle) { | ||
| { | ||
| let mut synced = self.shared.synced.lock(); | ||
| synced.inject_timers.push(hdl); | ||
| } | ||
| self.notify_parked_remote(); |
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.
Maybe we should use a different mutex from task injectoin queue for contention?
| /// The entry is in the pending queue of the timer wheel, | ||
| /// and not in any wheel level, which means that | ||
| /// the entry is reached its deadline and waiting to be woken up. | ||
| Pending(Sender, Waker, ThreadId), |
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.
Since block_in_place may move the Core from one thread to another, using the thread id may be a problem.
| } | ||
| } | ||
|
|
||
| pub(crate) fn register_waker(&self, waker: &Waker) { |
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.
Consider dropping old waker after releasing lock.
| if thread_id == cur_thread_id { | ||
| // Safety: | ||
| // 1. entry is either in slots or pending list | ||
| // 2. entry is registered in this thread | ||
| unsafe { | ||
| wheel.remove(entry); | ||
| } |
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.
Maybe we can just call entry.transition_to_cancelling() always here to avoid relying on thread id?
Review guide
Design document
See https://gist.github.com/ADD-SP/4037e25256b8dc8a4956962415de2356.
Benchmarks
See https://gist.github.com/ADD-SP/4037e25256b8dc8a4956962415de2356.
Signed-off-by: ADD-SP [email protected]