barriers 0.2.0

A barrier spin lock implementation
Documentation
use std::sync::atomic::{AtomicUsize,Ordering,AtomicBool};

pub struct Barrier {
    initial_count: usize,
    count: AtomicUsize,
    sense: AtomicBool,
}

impl Barrier {
    pub fn init(initial_count: usize) -> Barrier {
        Barrier {
            initial_count,
            count: AtomicUsize::new(initial_count),
            sense: AtomicBool::new(true),
        }
    }
    pub fn arrive(&self) {
        let priv_sense = self.sense.load(Ordering::SeqCst);
        if self.count.fetch_sub(1, Ordering::SeqCst) == 1 {
            self.count.store(self.initial_count, Ordering::SeqCst);
            self.sense.store(!priv_sense, Ordering::SeqCst);
        } else {
            while priv_sense == self.sense.load(Ordering::SeqCst) {}
        }
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use std::time::{Instant};
    use std::thread;
    use std::thread::JoinHandle;
    use std::sync::Arc;

    static ITERS: u128 = 10000000;

    #[test]
    fn bench_it_works() {
        let mut threads: Vec<JoinHandle<()>> = Vec::new();
        let num_threads = 4;
        let b = Arc::new(Barrier::init(num_threads));
        let now = Instant::now();
        for _ in 0..num_threads {
            let b_clone = Arc::clone(&b);
            threads.push(
                thread::spawn(move || {
                    for _ in 0..ITERS {
                        b_clone.arrive();
                    }
                })
            )
        }
    
        for t in threads {
            t.join().unwrap();
        }
        println!("ran for {}ns", now.elapsed().as_nanos() / ITERS);
        assert_eq!(4, 4);
    }

}