rcu-clean 0.1.0

Smart pointers using RCU with Deref support.
Documentation
use std::rc::Rc;
use std::sync::{Arc, Mutex, RwLock};
use std::cell::RefCell;

use rcu_clean::{BoxRcu, RcRcu, ArcRcu};

use criterion::{Criterion, criterion_group, criterion_main};

type RcRefCell<T> = Rc<RefCell<T>>;
type BoxRefCell<T> = Box<RefCell<T>>;
type BoxMutex<T> = Box<Mutex<T>>;
type BoxRwLock<T> = Box<RwLock<T>>;
type ArcMutex<T> = Arc<Mutex<T>>;
type ArcRwLock<T> = Arc<RwLock<T>>;

macro_rules! benchme {
    ($name:expr, $t:ident, $new:expr, $deref:expr) => {
        criterion::Fun::new($name, |b,&n_to_copy| {
            b.iter_with_setup(|| {
                let mut data: Vec<$t<usize>> = Vec::new();
                for i in 0..n_to_copy {
                    data.push($new(i));
                }
                let mut total: usize = 0;
                for x in data.iter() {
                    total += $deref(x);
                }
                data[0] = $new(total);
                (data, total)
            }, |(data, truetot)| {
                let mut total: usize = 0;
                for x in data.iter() {
                    total += $deref(x);
                }
                assert_eq!(total, truetot*2);
            });
        })
    }
}

fn criterion_benchmark(c: &mut Criterion) {
    let mut funs: Vec<criterion::Fun<usize>> = Vec::new();
    funs.push(benchme!("BoxRefCell", BoxRefCell, |a| Box::new(RefCell::new(a)),
                       |x: &BoxRefCell<usize>| -> usize { *x.borrow() }));
    funs.push(benchme!("RcRefCell", RcRefCell, |a| Rc::new(RefCell::new(a)),
                       |x: &RcRefCell<usize>| -> usize { *x.borrow() }));

    funs.push(benchme!("BoxMutex", BoxMutex, |a| Box::new(Mutex::new(a)),
                       |x: &BoxMutex<usize>| -> usize { *x.lock().unwrap() }));
    funs.push(benchme!("ArcMutex", ArcMutex, |a| Arc::new(Mutex::new(a)),
                       |x: &ArcMutex<usize>| -> usize { *x.lock().unwrap() }));

    funs.push(benchme!("BoxRwLock", BoxRwLock, |a| Box::new(RwLock::new(a)),
                       |x: &BoxRwLock<usize>| -> usize { *x.read().unwrap() }));
    funs.push(benchme!("ArcRwLock", ArcRwLock, |a| Arc::new(RwLock::new(a)),
                       |x: &ArcRwLock<usize>| -> usize { *x.read().unwrap() }));

    funs.push(benchme!("Box", Box, Box::new, |x: &Box<usize>| **x));
    funs.push(benchme!("Rc", Rc, Rc::new, |x: &Rc<usize>| **x));
    funs.push(benchme!("Arc", Arc, Arc::new, |x: &Arc<usize>| **x));


    funs.push(benchme!("RcRcu", RcRcu, RcRcu::new,
                       |x: &RcRcu<usize>| **x as usize));
    funs.push(benchme!("ArcRcu", ArcRcu, ArcRcu::new,
                       |x: &ArcRcu<usize>| **x as usize));
    funs.push(benchme!("BoxRcu", BoxRcu, BoxRcu::new,
                       |x: &BoxRcu<usize>| **x as usize));

    funs.reverse();
    c.bench_functions("sum", funs, 1000);
}

criterion_group!(benches, criterion_benchmark);
criterion_main!(benches);