summaryrefslogtreecommitdiffstats
path: root/tokio/src/time/driver
AgeCommit message (Collapse)Author
2020-12-08time: Fix race condition in timer drop (#3229)bdonlan
Dropping a timer on the millisecond that it was scheduled for, when it was on the pending list, could result in a panic previously, as we did not record the pending-list state in cached_when. Hopefully fixes: ZcashFoundation/zebra#1452
2020-12-07rt: fix deadlock in shutdown (#3228)bdonlan
Previously, the runtime shutdown logic would first-hand control over all cores to a single thread, which would sequentially shut down all tasks on the core and then wait for them to complete. This could deadlock when one task is waiting for a later core's task to complete. For example, in the newly added test, we have a `block_in_place` task that is waiting for another task to be dropped. If the latter task adds its core to the shutdown list later than the former, we end up waiting forever for the `block_in_place` task to complete. Additionally, there also was a bug wherein we'd attempt to park on the parker after shutting it down which was fixed as part of the refactors above. This change restructures the code to bring all tasks to a halt (and do any parking needed) before we collapse to a single thread to avoid this deadlock. There was also an issue in which canceled tasks would not unpark the originating thread, due to what appears to be some sort of optimization gone wrong. This has been fixed to be much more conservative in selecting when not to unpark the source thread (this may be too conservative; please take a look at the changes to `release()`). Fixes: #2789
2020-11-24time: replace 'ouClockTimeide' in internal docs with 'outside' (#3171)Max Sharnoff
2020-11-23time: use intrusive lists for timer tracking (#3080)bdonlan
More-or-less a half-rewrite of the current time driver, supporting the use of intrusive futures for timer registration. Fixes: #3028, #3069
2020-10-12rt: simplify rt-* features (#2949)Taiki Endo
tokio: merge rt-core and rt-util as rt rename rt-threaded to rt-multi-thread tokio-util: rename rt-core to rt Closes #2942
2020-10-12rt: Remove `threaded_scheduler()` and `basic_scheduler()` (#2876)Lucio Franco
Co-authored-by: Alice Ryhl <alice@ryhl.io> Co-authored-by: Carl Lerche <me@carllerche.com>
2020-10-12time: move error types into `time::error` (#2938)Juan Alvarez
2020-10-08time: rename `Delay` future to `Sleep` (#2932)Juan Alvarez
2020-10-06time: clean time driver (#2905)greenwoodcm
* remove unnecessary wheel::Poll the timer wheel uses the `wheel::Poll` struct as input when advancing the timer to the next time step. the `Poll` struct contains an instant representing the time step to advance to and also contains an optional and mutable reference to an `Expiration` struct. from what I can tell, the latter field is only used in the context of polling the wheel and does not need to be exposed outside of that method. without the expiration field the `Poll` struct is nothing more than a wrapper around the instant being polled. this change removes the `Poll` struct and updates integration points accordingly. * remove Stack trait in favor of concrete Stack implementation * remove timer Registration struct
2020-10-01time: introduce `sleep` and `sleep_until` functions (#2826)Juan Alvarez
2020-09-05tokio: document missing timer panics (#2801)Blas Rodriguez Irizar
Fixes: #2696 Co-authored-by: Mikail Bagishov <bagishov.mikail@yandex.ru>
2020-07-28rt: fix potential leak during runtime shutdown (#2649)Émile Grégoire
JoinHandle of threads created by the pool are now tracked and properly joined at shutdown. If the thread does not return within the timeout, then it's not joined and left to the OS for cleanup. Also, break a cycle between wakers held by the timer and the runtime. Fixes #2641, #2535
2020-07-24time: report correct error for timers that exceed max duration (#2023)Nikhil Benesch
Closes #1953
2020-07-20Update doc comments (#2572)Mikail Bagishov
* Update doc comments * Remove trailing whitespace
2020-07-20time: improve Entry field comment (#2671)Blas Rodriguez Irizar
Applying a suggestion from #2617 to make the sentence more clear.
2020-05-21coop: Undo budget decrement on Pending (#2549)Jon Gjengset
This patch updates the coop logic so that the budget is only decremented if a future makes progress (that is, if it returns `Ready`). This is realized by restoring the budget to its former value after `poll_proceed` _unless_ the caller indicates that it made progress. The thinking here is that we always want tasks to make progress when we poll them. With the way things were, if a task polled 128 resources that could make no progress, and just returned `Pending`, then a 129th resource that _could_ make progress would not be polled. Worse yet, this could manifest as a deadlock, if the first 128 resources were all _waiting_ for the 129th resource, since it would _never_ be polled. The downside of this change is that `Pending` resources now do not take up any part of the budget, even though they _do_ take up time on the executor. If a task is particularly aggressive (or unoptimized), and polls a large number of resources that cannot make progress whenever it is polled, then coop will allow it to run potentially much longer before yielding than it could before. The impact of this should be relatively contained though, because tasks that behaved in this way in the past probably ignored `Pending` _anyway_, so whether a resource returned `Pending` due to coop or due to lack of progress may not make a difference to it.
2020-04-29time: notify when resetting a Delay to a time in the past (#2290)Thomas Whiteway
If a Delay has been polled, then the task that polled it may be waiting for a notification. If the delay gets reset to a time in the past, then it immediately becomes elapsed, so it should notify the relevant task.
2020-03-26timer: fix loom test (#2346)Carl Lerche
Fixes a test from a PR that was written before the recent loom upgrade. A change in the details how loom executes models resulted in the test to start failing. The fix is to reduce the number of iterations performed by the test.
2020-03-26timer: improve memory ordering in Inner's increment (#2107)Brian L. Troutwine
This commit improves the memory ordering in the implementation of Inner's increment function. The former code did a sequentially consistent load of self.num, then entered a loop with a sequentially consistent compare and swap on the same, bailing out with and Err only if the loaded value was MAX_TIMEOUTS. The use of SeqCst means that all threads must observe all relevant memory operations in the same order, implying synchronization between all CPUs. This commit adjusts the implementation in two key ways. First, the initial load of self.num is now down with Relaxed ordering. If two threads entered this code simultaneously, formerly, tokio required that one proceed before the other, negating their parallelism. Now, either thread may proceed without coordination. Second, the SeqCst compare_and_swap is changed to a Release, Relaxed compare_exchange_weak. The first memory ordering referrs to success: if the value is swapped the load of that value for comparison will be Relaxed and the store will be Release. The second memory ordering referrs to failure: if the value is not swapped the load is Relaxed. The _weak variant may spuriously fail but will generate better code. These changes mean that it is possible for more loops to be taken per call than strictly necessary but with greater parallelism available on this operation, improved energy consumption as CPUs don't have to coordinate as much.
2020-03-23time: fix repeated pause/resume of time (#2253)Tudor Sidea
The resume function was breaking the guarantee that Instants should never be less than any previously measured Instants when created. Altered the pause and resume function such that they will not break this guarantee. After resume, the time should continue from where it left off. Created test to prove that the advanced function still works as expected. Added additional tests for the pause/advance/resume functions.
2020-03-16Add cooperative task yielding (#2160)Jon Gjengset
A single call to `poll` on a top-level task may potentially do a lot of work before it returns `Poll::Pending`. If a task runs for a long period of time without yielding back to the executor, it can starve other tasks waiting on that executor to execute them, or drive underlying resources. See for example rust-lang/futures-rs#2047, rust-lang/futures-rs#1957, and rust-lang/futures-rs#869. Since Rust does not have a runtime, it is difficult to forcibly preempt a long-running task. Consider a future like this one: ```rust use tokio::stream::StreamExt; async fn drop_all<I: Stream>(input: I) { while let Some(_) = input.next().await {} } ``` It may look harmless, but consider what happens under heavy load if the input stream is _always_ ready. If we spawn `drop_all`, the task will never yield, and will starve other tasks and resources on the same executor. This patch adds a `coop` module that provides an opt-in mechanism for futures to cooperate with the executor to avoid starvation. This alleviates the problem above: ``` use tokio::stream::StreamExt; async fn drop_all<I: Stream>(input: I) { while let Some(_) = input.next().await { tokio::coop::proceed().await; } } ``` The call to [`proceed`] will coordinate with the executor to make sure that every so often control is yielded back to the executor so it can run other tasks. The implementation uses a thread-local counter that simply counts how many "cooperation points" we have passed since the task was first polled. Once the "budget" has been spent, any subsequent points will return `Poll::Pending`, eventually making the top-level task yield. When it finally does yield, the executor resets the budget before running the next task. The budget per task poll is currently hard-coded to 128. Eventually, we may want to make it dynamic as more cooperation points are added. The number 128 was chosen more or less arbitrarily to balance the cost of yielding unnecessarily against the time an executor may be "held up". At the moment, all the tokio leaf futures ("resources") call into coop, but external futures have no way of doing so. We probably want to continue limiting coop points to leaf futures in the future, but may want to also enable third-party leaf futures to cooperate to benefit the ecosystem as a whole. This is reflected in the methods marked as `pub` in `mod coop` (even though the module is only `pub(crate)`). We will likely also eventually want to expose `coop::limit`, which enables sub-executors and manual `impl Future` blocks to avoid one sub-task spending all of their poll budget. Benchmarks (see tokio-rs/tokio#2160) suggest that the overhead of `coop` is marginal.
2020-01-26chore: bump nightly version used in CI (#2178)Carl Lerche
This requires fixing a few warnings.
2020-01-24rt: improve "no runtime" panic messages (#2145)Avery Harnish
2020-01-24docs: use third form in API docs (#2027)Oleg Nosov
2020-01-07rt: cleanup runtime::context (#2063)Carl Lerche
Tweak context to remove more fns and usage of `Option`. Remove `ThreadContext` struct as it is reduced to just `Handle`. Avoid passing around individual driver handles and instead limit to the `runtime::Handle` struct.
2020-01-06time: advance frozen time in `park_timeout` (#2059)Carl Lerche
This patch improves the behavior of frozen time (a testing utility made available with the `test-util` feature flag). Instead of of requiring `time::advance` to be called in order to advance the value returned by `Instant::now`, calls to `time::Driver::park_timeout` will use the provided duration to advance the time. This is the desired behavior as the timeout is used to indicate when the next scheduled delay needs to be fired.
2019-12-24rt: coalesce thread-locals used by the runtime (#1925)Gardner Vickers
Previously, thread-locals used by the various drivers were situated with the driver code. This resulted in state being spread out and many thread-locals being required to run a runtime. This PR coalesces the thread-locals into a single struct.
2019-12-22doc: fill out `fs` and remove html links (#2015)Carl Lerche
also add an async version of `fs::canonicalize`
2019-12-04time: Remove `HandlePriv` (#1896)Kevin Leimkuhler
## Motivation #1800 removed the lazy binding of `Delay`s to timers. With the removal of the logic required for that, `HandlePriv` is no longer needed. This PR removes the use of `HandlePriv`. A `TODO` was also removed that would panic if when registering a new `Delay` the current timer handle was full. That has been fixed to now immediately transition that `Delay` to an error state that can be handled in a similar way to other error states. Signed-off-by: Kevin Leimkuhler <kleimkuhler@icloud.com>
2019-11-27doc: misc API documentation fixes (#1834)Oleg Nosov
2019-11-21runtime: cleanup and add config options (#1807)Carl Lerche
* runtime: cleanup and add config options This patch finishes the cleanup as part of the transition to Tokio 0.2. A number of changes were made to take advantage of having all Tokio types in a single crate. Also, fixes using Tokio types from `spawn_blocking`. * Many threads, one resource driver Previously, in the threaded scheduler, a resource driver (mio::Poll / timer combo) was created per thread. This was more or less fine, except it required balancing across the available drivers. When using a resource driver from **outside** of the thread pool, balancing is tricky. The change was original done to avoid having a dedicated driver thread. Now, instead of creating many resource drivers, a single resource driver is used. Each scheduler thread will attempt to "lock" the resource driver before parking on it. If the resource driver is already locked, the thread uses a condition variable to park. Contention should remain low as, under load, the scheduler avoids using the drivers. * Add configuration options to enable I/O / time New configuration options are added to `runtime::Builder` to allow enabling I/O and time drivers on a runtime instance basis. This is useful when wanting to create lightweight runtime instances to execute compute only tasks. * Bug fixes The condition variable parker is updated to the same algorithm used in `std`. This is motivated by some potential deadlock cases discovered by `loom`. The basic scheduler is fixed to fairly schedule tasks. `push_front` was accidentally used instead of `push_back`. I/O, time, and spawning now work from within `spawn_blocking` closures. * Misc cleanup The threaded scheduler is no longer generic over `P :Park`. Instead, it is hard coded to a specific parker. Tests, including loom tests, are updated to use `Runtime` directly. This provides greater coverage. The `blocking` module is moved back into `runtime` as all usage is within `runtime` itself.
2019-11-20time: Eagerly bind delays to timer (#1800)Kevin Leimkuhler
## Motivation Similar to #1666, it is no longer necessary to lazily register delays with the executions default timer. All delays are expected to be created from within a runtime, and should panic if not done so. ## Solution `tokio::time` now assumes there to be a `CURRENT_TIMER` set when creating a delay; this can be assumed if called within a tokio runtime. If there is no current timer, the application will panic with a "no current timer" message. ## Follow-up Similar to #1666, `HandlePriv` can probably be removed, but this mainly prepares for 0.2 API changes. Because it is not in the public API, this can be done in a following change. Signed-off-by: Kevin Leimkuhler <kleimkuhler@icloud.com>
2019-11-15Limit `futures` dependency to `Stream` via feature flag (#1774)Carl Lerche
In an effort to reach API stability, the `tokio` crate is shedding its _public_ dependencies on crates that are either a) do not provide a stable (1.0+) release with longevity guarantees or b) match the `tokio` release cadence. Of course, implementing `std` traits fits the requirements. The on exception, for now, is the `Stream` trait found in `futures_core`. It is expected that this trait will not change much and be moved into `std. Since Tokio is not yet going reaching 1.0, I feel that it is acceptable to maintain a dependency on this trait given how foundational it is. Since the `Stream` implementation is optional, types that are logically streams provide `async fn next_*` functions to obtain the next value. Avoiding the `next()` name prevents fn conflicts with `StreamExt::next()`. Additionally, some misc cleanup is also done: - `tokio::io::io` -> `tokio::io::util`. - `delay` -> `delay_until`. - `Timeout::new` -> `timeout(...)`. - `signal::ctrl_c()` returns a future instead of a stream. - `{tcp,unix}::Incoming` is removed (due to lack of `Stream` trait). - `time::Throttle` is removed (due to lack of `Stream` trait). - Fix: `mpsc::UnboundedSender::send(&self)` (no more conflict with `Sink` fns).
2019-11-12reorganize modules (#1766)Carl Lerche
This patch started as an effort to make `time::Timer` private. However, in an effort to get the build compiling again, more and more changes were made. This probably should have been broken up, but here we are. I will attempt to summarize the changes here. * Feature flags are reorganized to make clearer. `net-driver` becomes `io-driver`. `rt-current-thread` becomes `rt-core`. * The `Runtime` can be created without any executor. This replaces `enter`. It also allows creating I/O / time drivers that are standalone. * `tokio::timer` is renamed to `tokio::time`. This brings it in line with `std`. * `tokio::timer::Timer` is renamed to `Driver` and made private. * The `clock` module is removed. Instead, an `Instant` type is provided. This type defaults to calling `std::time::Instant`. A `test-util` feature flag can be used to enable hooking into time. * The `blocking` module is moved to the top level and is cleaned up. * The `task` module is moved to the top level. * The thread-pool's in-place blocking implementation is cleaned up. * `runtime::Spawner` is renamed to `runtime::Handle` and can be used to "enter" a runtime context.