#![feature(test)] extern crate test; use std::sync::Arc; use std::time::Duration; use test::Bencher; use crossbeam_channel::bounded; use tokio::{ runtime::{self, Runtime}, sync::Mutex, }; fn rt() -> Runtime { runtime::Builder::new_multi_thread().worker_threads(4).enable_all().build().unwrap() } #[bench] fn tokio_bench_async_mutex(b: &mut Bencher) { let rt0 = Arc::new(rt()); let rt1 = Arc::new(rt()); b.iter(|| { let rt0_copy = rt0.clone(); let rt1_copy = rt1.clone(); let (s, r) = bounded(1); let shared = Arc::new(Mutex::new(0)); for _ in 0..1 { let s0_copy = s.clone(); let shared0_copy = shared.clone(); rt0_copy.spawn(async move { for _ in 0..500 { let mut v = shared0_copy.lock().await; if *v >= 999 { *v += 1; s0_copy.send(()).unwrap(); } else { *v += 1; } } }); } for _ in 0..1 { let s1_copy = s.clone(); let shared1_copy = shared.clone(); rt1_copy.spawn(async move { for _ in 0..500 { let mut v = shared1_copy.lock().await; if *v >= 999 { *v += 1; s1_copy.send(()).unwrap(); } else { *v += 1; } } }); } if let Err(_) = r.recv_timeout(Duration::from_millis(10000)) { // println!("!!!!!!recv timeout, len: {:?}", (rt0.len(), rt1.len())); } }); }