cooptex 0.1.1

Deadlock free Mutexes
Documentation
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::<Vec<_>>();

    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::<Result<Vec<_>, _>>()?;
                    eprintln!("Thread {:>3} acquired locks", i);
                    for lock in locks {
                        *lock.unwrap() += 1;
                    }
                    Ok(())
                });
            })
        })
        .collect::<Vec<_>>()
        .into_iter()
        .for_each(|t| t.join().unwrap());

    for item in items {
        assert_eq!(*item.lock().unwrap().unwrap(), num_threads);
    }

    eprintln!("All threads complete");
}