mirror of
https://github.com/tokio-rs/tokio.git
synced 2025-09-28 12:10:37 +00:00

Introduce a tokio-sync crate containing useful synchronization primitives for programs written using Tokio. The initial release contains: * An mpsc channel * A oneshot channel * A semaphore implementation * An `AtomicTask` primitive. The `oneshot` and `mpsc` channels are new implementations providing improved performance characteristics. In some benchmarks, the new mpsc channel shows up to 7x improvement over the version provided by the `futures` crate. Unfortunately, the `oneshot` implementation only provides a slight performance improvement as it is mostly limited by the `futures` 0.1 task system. Once updated to the `std` version of `Future` (currently nightly only), much greater performance improvements should be achievable by `oneshot`. Additionally, he implementations provided here are checked using [Loom](http://github.com/carllerche/loom/), which provides greater confidence of correctness.
55 lines
1.1 KiB
Rust
55 lines
1.1 KiB
Rust
extern crate futures;
|
|
#[macro_use]
|
|
extern crate loom;
|
|
|
|
#[path = "../src/task/atomic_task.rs"]
|
|
mod atomic_task;
|
|
|
|
use atomic_task::AtomicTask;
|
|
|
|
use loom::futures::block_on;
|
|
use loom::sync::atomic::AtomicUsize;
|
|
use loom::thread;
|
|
|
|
use futures::Async;
|
|
use futures::future::poll_fn;
|
|
|
|
use std::sync::Arc;
|
|
use std::sync::atomic::Ordering::Relaxed;
|
|
|
|
struct Chan {
|
|
num: AtomicUsize,
|
|
task: AtomicTask,
|
|
}
|
|
|
|
#[test]
|
|
fn basic_notification() {
|
|
const NUM_NOTIFY: usize = 2;
|
|
|
|
loom::fuzz(|| {
|
|
let chan = Arc::new(Chan {
|
|
num: AtomicUsize::new(0),
|
|
task: AtomicTask::new(),
|
|
});
|
|
|
|
for _ in 0..NUM_NOTIFY {
|
|
let chan = chan.clone();
|
|
|
|
thread::spawn(move || {
|
|
chan.num.fetch_add(1, Relaxed);
|
|
chan.task.notify();
|
|
});
|
|
}
|
|
|
|
block_on(poll_fn(move || {
|
|
chan.task.register();
|
|
|
|
if NUM_NOTIFY == chan.num.load(Relaxed) {
|
|
return Ok(Async::Ready(()));
|
|
}
|
|
|
|
Ok::<_, ()>(Async::NotReady)
|
|
})).unwrap();
|
|
});
|
|
}
|