summaryrefslogtreecommitdiffstats
AgeCommit message (Collapse)Author
2019-11-01runtime: merge multi & single threaded runtimes (#1716)Carl Lerche
Simplify Tokio's runtime construct by combining both Runtime variants into a single type. The execution style can be controlled by a configuration setting on `Builder`. The implication of this change is that there is no longer any way to spawn `!Send` futures. This, however, is a temporary limitation. A different strategy will be employed for supporting `!Send` futures. Included in this patch is a rework of `task::JoinHandle` to support using this type from both the thread-pool and current-thread executors.
2019-11-01Fix delay construction from non-lazy Handles (#1720)Steven Fackler
Closes #1719.
2019-11-01compat: extract crate to a dedicated git repo (#1723)Carl Lerche
The compat crate is moved to https://github.com/tokio-rs/tokio-compat. This allows pinning it to specific revisions of the Tokio git repository. The master branch is intended to go through significant churn and it will be easier to update the compat layer in batches.
2019-11-01compat: add a compat runtime (#1663)Eliza Weisman
## Motivation The `futures` crate's [`compat` module][futures-compat] provides interoperability between `futures` 0.1 and `std::future` _future types_ (e.g. implementing `std::future::Future` for a type that implements the `futures` 0.1 `Future` trait). However, this on its own is insufficient to run code written against `tokio` 0.1 on a `tokio` 0.2 runtime, if that code also relies on `tokio`'s runtime services. If legacy tasks are executed that rely on `tokio::timer`, perform IO using `tokio`'s reactor, or call `tokio::spawn`, those API calls will fail unless there is also a runtime compatibility layer. ## Solution As proposed in #1549, this branch introduces a new `tokio-compat` crate, with implementations of the thread pool and current-thread runtimes that are capable of running both tokio 0.1 and tokio 0.2 tasks. The compat runtime creates a background thread that runs a `tokio` 0.1 timer and reactor, and sets itself as the `tokio` 0.1 executor as well as the default 0.2 executor. This allows 0.1 futures that use 0.1 timer, reactor, and executor APIs may run alongside `std::future` tasks on the 0.2 runtime. ### Examples Spawning both `tokio` 0.1 and `tokio` 0.2 futures: ```rust use futures_01::future::lazy; tokio_compat::run(lazy(|| { // spawn a `futures` 0.1 future using the `spawn` function from the // `tokio` 0.1 crate: tokio_01::spawn(lazy(|| { println!("hello from tokio 0.1!"); Ok(()) })); // spawn an `async` block future on the same runtime using `tokio` // 0.2's `spawn`: tokio_02::spawn(async { println!("hello from tokio 0.2!"); }); Ok(()) })) ``` Futures on the compat runtime can use `timer` APIs from both 0.1 and 0.2 versions of `tokio`: ```rust use std::time::{Duration, Instant}; use futures_01::future::lazy; use tokio_compat::prelude::*; tokio_compat::run_03(async { // Wait for a `tokio` 0.1 `Delay`... let when = Instant::now() + Duration::from_millis(10); tokio_01::timer::Delay::new(when) // convert the delay future into a `std::future` that we can `await`. .compat() .await .expect("tokio 0.1 timer should work!"); println!("10 ms have elapsed"); // Wait for a `tokio` 0.2 `Delay`... let when = Instant::now() + Duration::from_millis(20); tokio_02::timer::delay(when).await; println!("20 ms have elapsed"); }); ``` ## Future Work This is just an initial implementation of a `tokio-compat` crate; there are more compatibility layers we'll want to provide before that crate is complete. For example, we should also provide compatibility between `tokio` 0.2's `AsyncRead` and `AsyncWrite` traits and the `futures` 0.1 and `futures` 0.3 versions of those traits. In #1549, @carllerche also suggests that the `compat` crate provide reimplementations of APIs that were removed from `tokio` 0.2 proper, such as the `tcp::Incoming` future. Additionally, there is likely extra work required to get the `tokio-threadpool` 0.1 `blocking` APIs to work on the compat runtime. This will be addressed in a follow-up PR. Fixes: #1605 Fixes: #1552 Refs: #1549 [futures-compat]: https://rust-lang-nursery.github.io/futures-api-docs/0.3.0-alpha.19/futures/compat/index.html
2019-11-01chore: remove dead files (#1718)Carl Lerche
The `codec` module has been moved to `tokio-util`. Some files were left, but they were never activated.
2019-10-31runtime: test creating a single-threaded runtime. (#1717)Carl Lerche
2019-10-31chore: check each feature works properly (#1695)Taiki Endo
It is hard to maintain features list manually, so use cargo-hack's `--each-feature` flag. And cargo-hack provides a workaround for an issue that dev-dependencies leaking into normal build (`--no-dev-deps` flag), so removed own ci tool. Also, compared to running tests on all features, there is not much advantage in running tests on each feature, so only the default features and all features are tested. If the behavior changes depending on the feature, we need to test it as another job in CI.
2019-10-31Allow non-destructive access to the read buffer. (#1600)Jonathan Bastien-Filiatrault
I need this to implement SMTP pipelining checks. I mostly need to flush my send buffer when the read buffer is empty before waiting for the next command.
2019-10-30timere: make Delay must_use (#1714)Steven Fackler
Closes #1711
2019-10-30process: refactor OrphanQueue to use a Mutex instead fo SegQueue (#1712)Sean McArthur
2019-10-30thread-pool: in-place blocking with new scheduler (#1681)Jon Gjengset
The initial new scheduler PR omitted in-place blocking support. This patch brings it back.
2019-10-29timer: inline CachePadded type (#1706)Sean McArthur
2019-10-29sync: move into `tokio` crate (#1705)Carl Lerche
A step towards collapsing Tokio sub crates into a single `tokio` crate (#1318). The sync implementation is now provided by the main `tokio` crate. Functionality can be opted out of by using the various net related feature flags.
2019-10-28executor: move into `tokio` crate (#1702)Carl Lerche
A step towards collapsing Tokio sub crates into a single `tokio` crate (#1318). The executor implementation is now provided by the main `tokio` crate. Functionality can be opted out of by using the various net related feature flags.
2019-10-28net: replace RwLock<Slab> with a lock free slab (#1625)Eliza Weisman
## Motivation The `tokio_net::driver` module currently stores the state associated with scheduled IO resources in a `Slab` implementation from the `slab` crate. Because inserting items into and removing items from `slab::Slab` requires mutable access, the slab must be placed within a `RwLock`. This has the potential to be a performance bottleneck especially in the context of the work-stealing scheduler where tasks and the reactor are often located on the same thread. `tokio-net` currently reimplements the `ShardedRwLock` type from `crossbeam` on top of `parking_lot`'s `RwLock` in an attempt to squeeze as much performance as possible out of the read-write lock around the slab. This introduces several dependencies that are not used elsewhere. ## Solution This branch replaces the `RwLock<Slab>` with a lock-free sharded slab implementation. The sharded slab is based on the concept of _free list sharding_ described by Leijen, Zorn, and de Moura in [_Mimalloc: Free List Sharding in Action_][mimalloc], which describes the implementation of a concurrent memory allocator. In this approach, the slab is sharded so that each thread has its own thread-local list of slab _pages_. Objects are always inserted into the local slab of the thread where the insertion is performed. Therefore, the insert operation needs not be synchronized. However, since objects can be _removed_ from the slab by threads other than the one on which they were inserted, removal operations can still occur concurrently. Therefore, Leijen et al. introduce a concept of _local_ and _global_ free lists. When an object is removed on the same thread it was originally inserted on, it is placed on the local free list; if it is removed on another thread, it goes on the global free list for the heap of the thread from which it originated. To find a free slot to insert into, the local free list is used first; if it is empty, the entire global free list is popped onto the local free list. Since the local free list is only ever accessed by the thread it belongs to, it does not require synchronization at all, and because the global free list is popped from infrequently, the cost of synchronization has a reduced impact. A majority of insertions can occur without any synchronization at all; and removals only require synchronization when an object has left its parent thread. The sharded slab was initially implemented in a separate crate (soon to be released), vendored in-tree to decrease `tokio-net`'s dependencies. Some code from the original implementation was removed or simplified, since it is only necessary to support `tokio-net`'s use case, rather than to provide a fully generic implementation. [mimalloc]: https://www.microsoft.com/en-us/research/uploads/prod/2019/06/mimalloc-tr-v1.pdf ## Performance These graphs were produced by out-of-tree `criterion` benchmarks of the sharded slab implementation. The first shows the results of a benchmark where an increasing number of items are inserted and then removed into a slab concurrently by five threads. It compares the performance of the sharded slab implementation with a `RwLock<slab::Slab>`: <img width="1124" alt="Screen Shot 2019-10-01 at 5 09 49 PM" src="https://user-images.githubusercontent.com/2796466/66078398-cd6c9f80-e516-11e9-9923-0ed6292e8498.png"> The second graph shows the results of a benchmark where an increasing number of items are inserted and then removed by a _single_ thread. It compares the performance of the sharded slab implementation with an `RwLock<slab::Slab>` and a `mut slab::Slab`. <img width="925" alt="Screen Shot 2019-10-01 at 5 13 45 PM" src="https://user-images.githubusercontent.com/2796466/66078469-f0974f00-e516-11e9-95b5-f65f0aa7e494.png"> Note that while the `mut slab::Slab` (i.e. no read-write lock) is (unsurprisingly) faster than the sharded slab in the single-threaded benchmark, the sharded slab outperforms the un-contended `RwLock<slab::Slab>`. This case, where the lock is uncontended and only accessed from a single thread, represents the best case for the current use of `slab` in `tokio-net`, since the lock cannot be conditionally removed in the single-threaded case. These benchmarks demonstrate that, while the sharded approach introduces a small constant-factor overhead, it offers significantly better performance across concurrent accesses. ## Notes This branch removes the following dependencies `tokio-net`: - `parking_lot` - `num_cpus` - `crossbeam_util` - `slab` This branch adds the following dev-dependencies: - `proptest` - `loom` Note that these dev dependencies were used to implement tests for the sharded-slab crate out-of-tree, and were necessary in order to vendor the existing tests. Alternatively, since the implementation is tested externally, we _could_ remove these tests in order to avoid picking up dev-dependencies. However, this means that we should try to ensure that `tokio-net`'s vendored implementation doesn't diverge significantly from upstream's, since it would be missing a majority of its tests. Signed-off-by: Eliza Weisman <eliza@buoyant.io>
2019-10-27Fix docs links: Redux (#1698)Geoff Shannon
2019-10-26thread-pool: test additional shutdown cases (#1697)Carl Lerche
This adds an extra spawned task during the thread-pool shutdown loom test. This results in additional cases being tested, primarily tasks being stolen.
2019-10-26chore: use argument position impl trait (#1690)Linus Färnstrand
2019-10-26io: move into `tokio` crate (#1691)Carl Lerche
A step towards collapsing Tokio sub crates into a single `tokio` crate (#1318). The `io` implementation is now provided by the main `tokio` crate. Functionality can be opted out of by using the various net related feature flags.
2019-10-25net: move into tokio crate (#1683)Carl Lerche
A step towards collapsing Tokio sub crates into a single `tokio` crate (#1318). The `net` implementation is now provided by the main `tokio` crate. Functionality can be opted out of by using the various net related feature flags.
2019-10-24Make blocking pool non-static and use for thread pool (#1678)Jon Gjengset
Previously, support for `blocking` was done through a static `POOL` that would spawn threads on demand. While this made the pool accessible at all times, it made it hard to configure, and it was impossible to keep multiple blocking pools. This patch changes `blocking` to instead use a "default" global like the ones used for timers, executors, and the like. There is now `blocking::with_pool`, which is used by both thread-pool workers and the current-thread runtime to ensure that a pool is available to tasks. This patch also changes `ThreadPool` to spawn its worker threads on the blocking pool rather than as free-standing threads. This is in preparation for the coming in-place blocking work. One downside of this change is that thread names are no longer "semantic". All threads are named by the pool name, and individual threads are not (currently) given names with numerical suffixes like before.
2019-10-23chore: remove tracing. (#1680)Carl Lerche
Historically, logging has been added haphazardly. Here, we entirely remove logging as none of it is particularly useful. In the future, we will add tracing back in order to expose useful data to the user of Tokio.
2019-10-22codec: move into tokio-util (#1675)Carl Lerche
Related to #1318, Tokio APIs that are "less stable" are moved into a new `tokio-util` crate. This crate will mirror `tokio` and provide additional APIs that may require a greater rate of breaking changes. As examples require `tokio-util`, they are moved into a separate crate (`examples`). This has the added advantage of being able to avoid example only dependencies in the `tokio` crate.
2019-10-21timer: move `tokio-timer` into `tokio` crate (#1674)Carl Lerche
A step towards collapsing Tokio sub crates into a single `tokio` crate (#1318). The `timer` implementation is now provided by the main `tokio` crate. The `timer` functionality may still be excluded from the build by skipping the `timer` feature flag.
2019-10-21net: Eagerly bind resources to reactors (#1666)Kevin Leimkuhler
## Motivation The `tokio_net` resources can be created outside of a runtime due to how tokio has been used with futures to date. For example, this allows a `TcpStream` to be created, and later passed into a runtime: ``` let stream = TcpStream::connect(...).and_then(|socket| { // do something }); tokio::run(stream); ``` In order to support this functionality, the reactor was lazily bound to the resource on the first call to `poll_read_ready`/`poll_write_ready`. This required a lot of additional complexity in the binding logic to support. With the tokio 0.2 common case, this is no longer necessary and can be removed. All resources are expected to be created from within a runtime, and should panic if not done so. Closes #1168 ## Solution The `tokio_net` crate now assumes there to be a `CURRENT_REACTOR` set on the worker thread creating a resource; this can be assumed if called within a tokio runtime. If there is no current reactor, the application will panic with a "no current reactor" message. With this assumption, all the unsafe and atomics have been removed from `tokio_net::driver::Registration` as it is no longer needed. There is no longer any reason to pass in handles to the family of `from_std` methods on `net` resources. `Handle::current` has therefore a more restricted private use where it is only used in `driver::Registration::new`. Signed-off-by: Kevin Leimkuhler <kleimkuhler@icloud.com>
2019-10-21fs: move into `tokio` (#1672)Carl Lerche
A step towards collapsing Tokio sub crates into a single `tokio` crate (#1318). The `fs` implementation is now provided by the main `tokio` crate. The `fs` functionality may still be excluded from the build by skipping the `fs` feature flag.
2019-10-21io: `Take` struct re-export to main crate (#1670)madmaxio
2019-10-21runtime: update doc regarding `runtime::run` function helper (#1671)Jonathas Conceição
2019-10-19executor: rewrite the work-stealing thread pool (#1657)Carl Lerche
This patch is a ground up rewrite of the existing work-stealing thread pool. The goal is to reduce overhead while simplifying code when possible. At a high level, the following architectural changes were made: - The local run queues were switched for bounded circle buffer queues. - Reduce cross-thread synchronization. - Refactor task constructs to use a single allocation and always include a join handle (#887). - Simplify logic around putting workers to sleep and waking them up. **Local run queues** Move away from crossbeam's implementation of the Chase-Lev deque. This implementation included unnecessary overhead as it supported capabilities that are not needed for the work-stealing thread pool. Instead, a fixed size circle buffer is used for the local queue. When the local queue is full, half of the tasks contained in it are moved to the global run queue. **Reduce cross-thread synchronization** This is done via many small improvements. Primarily, an upper bound is placed on the number of concurrent stealers. Limiting the number of stealers results in lower contention. Secondly, the rate at which workers are notified and woken up is throttled. This also reduces contention by preventing many threads from racing to steal work. **Refactor task structure** Now that Tokio is able to target a rust version that supports `std::alloc` as well as `std::task`, the pool is able to optimize how the task structure is laid out. Now, a single allocation per task is required and a join handle is always provided enabling the spawner to retrieve the result of the task (#887). **Simplifying logic** When possible, complexity is reduced in the implementation. This is done by using locks and other simpler constructs in cold paths. The set of sleeping workers is now represented as a `Mutex<VecDeque<usize>>`. Instead of optimizing access to this structure, we reduce the amount the pool must access this structure. Secondly, we have (temporarily) removed `threadpool::blocking`. This capability will come back later, but the original implementation was way more complicated than necessary. **Results** The thread pool benchmarks have improved significantly: Old thread pool: ``` test chained_spawn ... bench: 2,019,796 ns/iter (+/- 302,168) test ping_pong ... bench: 1,279,948 ns/iter (+/- 154,365) test spawn_many ... bench: 10,283,608 ns/iter (+/- 1,284,275) test yield_many ... bench: 21,450,748 ns/iter (+/- 1,201,337) ``` New thread pool: ``` test chained_spawn ... bench: 147,943 ns/iter (+/- 6,673) test ping_pong ... bench: 537,744 ns/iter (+/- 20,928) test spawn_many ... bench: 7,454,898 ns/iter (+/- 283,449) test yield_many ... bench: 16,771,113 ns/iter (+/- 733,424) ``` Real-world benchmarks improve significantly as well. This is testing the hyper hello world server using: `wrk -t1 -c50 -d10`: Old scheduler: ``` Running 10s test @ http://127.0.0.1:3000 1 threads and 50 connections Thread Stats Avg Stdev Max +/- Stdev Latency 371.53us 99.05us 1.97ms 60.53% Req/Sec 114.61k 8.45k 133.85k 67.00% 1139307 requests in 10.00s, 95.61MB read Requests/sec: 113923.19 Transfer/sec: 9.56MB ``` New scheduler: ``` Running 10s test @ http://127.0.0.1:3000 1 threads and 50 connections Thread Stats Avg Stdev Max +/- Stdev Latency 275.05us 69.81us 1.09ms 73.57% Req/Sec 153.17k 10.68k 171.51k 71.00% 1522671 requests in 10.00s, 127.79MB read Requests/sec: 152258.70 Transfer/sec: 12.78MB ```
2019-10-16fs: add read_to_string (#1664)Steven Fackler
2019-10-15fs: remove unnecessary trait and lifetime bounds (#1655)Taiki Endo
2019-10-12macros: Use more consistent runtime names (#1628)Jon Gjengset
As discussed in #1620, the attribute names for `#[tokio::main]` and `#[tokio::test]` aren't great. Specifically, they both use `single_thread` and `multi_thread`, as opposed to names that match the runtime names: `current_thread` and `threadpool`. This PR changes the former to the latter. Fixes #1627.
2019-10-11Remove incorrect FusedFuture impl on Delay (#1652)John-John Tedro
`is_terminated` must return `true` until the future has been polled at least once to make sure that the associated block in select is called even after the delay has elapsed. You use `Delay` in a `select!` by [fusing it](https://docs.rs/futures-preview/0.3.0-alpha.19/futures/future/trait.FutureExt.html#method.fuse): ```rust let delay = tokio::timer::delay(/* ... */); let delay = delay.fuse(); select! { _ = delay => { /* work here */ } } ```
2019-10-11tokio: move `signal` and `process` reexports to crate root (#1643)Ivan Petkov
2019-10-10sync: fix mem leak in oneshot on task migration (#1648)Carl Lerche
When polling the task, the current waker is saved to the oneshot state. When the handle is migrated to a new task and polled again, the waker must be swaped from the old waker to the new waker. In some cases, there is a potential for the old waker to leak. This bug was caught by loom with the recently added memory leak detection.
2019-10-09io: add `AsyncBufReadExt::split` (#1642)Eliza Weisman
add a `split` method to `AsyncBufReadExt`, analogous to `std::io::BufRead::split`.
2019-10-07executor: accurate idle thread tracking for the blocking pool (#1621)Jonathan Bastien-Filiatrault
Use a counter to count notifications. This protects against spurious wakeups by pthreads and other libraries. The state transitions now track num_idle precisely.
2019-10-07io: add missing utility functions (#1632)Eliza Weisman
The standard library's `io` module has small utilities such as `repeat`, `empty`, and `sink`, which return `Read` and `Write` implementations. These can come in handy in some circiumstances. `tokio::io` has no equivalents that implement `AsyncRead`/`AsyncWrite`. This commit adds `repeat`, `empty`, and `sink` helpers to `tokio::io`.
2019-10-07chore: fix a comment typo (#1633)Nick Stott
2019-10-07timer: test arm on targets with target_has_atomic less than 64 (#1634)Taiki Endo
2019-10-07chore: update Cirrus CI config to test on beta (#1636)Taiki Endo
2019-10-07chore: do not trigger CI on std-future branch (#1635)Taiki Endo
2019-10-02tcp: export Incoming type (#1602)Vojtech Kral
2019-10-02macros: allow selecting runtime in tokio::test attr (#1620)Jon Gjengset
In the past, it was not possible to choose to use the multi-threaded tokio `Runtime` in tests, which meant that any test that transitively used `executor::threadpool::blocking` would fail with ``` 'blocking' annotation used from outside the context of a thread pool ``` This patch adds a runtime annotation attribute to `#[tokio::test]` just like `#[tokio::main]` has, which lets users opt in to the threadpool runtime over `current_thread` (the default).
2019-10-02chore: annotate prelude re-exports as `doc(no_inline)` (#1601)Jonathan Bastien-Filiatrault
Fixes #1593 by making "use as _" linked in the documentation.
2019-10-01chore: update rust-toolchain to use beta (#1619)Taiki Endo
2019-10-01macros: Allow arguments in non-main functionsDouman
2019-09-30Prepare for release of 0.2.0-alpha.6 (#1617)Jon Gjengset
Note that `tokio-timer` and `tokio-tls` become 0.3.0-alpha.6 (not 0.2.0)
2019-09-30Fix for rust-lang/rust#64477 (#1618)Jon Gjengset
`foo(format!(...)).await` no longer compiles. There's a fix in rust-lang/rust#64856, but this works around the problem.
2019-09-30Create BufStream from a BufReader + BufWriter (#1609)Jon Gjengset
This is handy if developers want to construct the inner buffers with a particular capacity, and still end up with a `BufStream` at the end.