use cooptex::{retry_loop, CoopMutex}; use std::sync::{ atomic::{AtomicUsize, Ordering}, Arc, }; fn main() { let num_items = 10; let num_threads = 100; let items = (0..num_items) .map(|_| Arc::new(CoopMutex::new(0))) .collect::>(); let started = Arc::new(AtomicUsize::new(0)); (0..num_threads) .map(|i| { let mut items = items.clone(); let started = started.clone(); std::thread::spawn(move || { use rand::prelude::SliceRandom; items.shuffle(&mut rand::thread_rng()); started.fetch_add(1, Ordering::SeqCst); while started.load(Ordering::SeqCst) < num_threads { std::thread::yield_now(); } retry_loop(|| { let locks = items .iter() .map(|mutex| mutex.lock()) .collect::, _>>()?; eprintln!("Thread {:>3} acquired locks", i); for lock in locks { *lock.unwrap() += 1; } Ok(()) }); }) }) .collect::>() .into_iter() .for_each(|t| t.join().unwrap()); for item in items { assert_eq!(*item.lock().unwrap().unwrap(), num_threads); } eprintln!("All threads complete"); }