Expand description

Lock-free data-structures

Implements a lock-free thread-safe appendable list with a lock-free iterator

Features

Single thread


let (a, b, c) = (0usize, 1usize, 2usize);
// VS alias to VoluntaryServitude
// vs! alias to voluntary_servitude! (and operate like vec!)
let list = vs![a, b, c];
assert_eq!(list.iter().collect::<Vec<_>>(), vec![&a, &b, &c]);

// Current VS's length
// Be careful with data-races since the value, when used, may not be true anymore
assert_eq!(list.len(), 3);

// The 'iter' method makes a one-time lock-free iterator (VSIter)
for (index, element) in list.iter().enumerate() {
    assert_eq!(index, *element);
}

// You can get the current iteration index
// iter.next() == iter.len() means iteration ended (iter.next() == None)
let mut iter = list.iter();
assert_eq!(iter.index(), 0);
assert_eq!(iter.next(), Some(&0));
assert_eq!(iter.index(), 1);

// List can also be cleared (but current iterators are not affected)
list.clear();

assert_eq!(iter.len(), 3);
assert_eq!(list.len(), 0);
assert_eq!(list.iter().len(), 0);
assert_eq!(list.iter().next(), None);

println!("Single thread example ended without errors");

Multi producer, multi consumer

#[macro_use] extern crate voluntary_servitude;
use std::{sync::Arc, thread::spawn};

const CONSUMERS: usize = 8;
const PRODUCERS: usize = 4;
const ELEMENTS: usize = 10000;

let list = Arc::new(vs![]);
let mut handlers = vec![];

// Creates producer threads to insert 10k elements
for _ in 0..PRODUCERS {
    let l = Arc::clone(&list);
    handlers.push(spawn(move || { let _ = (0..ELEMENTS).map(|i| l.append(i)).count(); }));
}

// Creates consumer threads to print number of elements until all of them are inserted
for _ in 0..CONSUMERS {
    let consumer = Arc::clone(&list);
    handlers.push(spawn(move || {
        loop {
            let count = consumer.iter().count();
            println!("{} elements", count);
            if count == PRODUCERS * ELEMENTS { break; }
        }
    }));
}

// Join threads
for handler in handlers.into_iter() {
    handler.join().expect("Failed to join thread");
}

println!("Multi thread example ended without errors");

Modules

Voluntary Servitude Foreign Function Interface (FFI)
serdeserde-traits
Serde’s Serialize/Deserialize trait implementations behind the ‘serde-traits’ feature

Macros

Creates new VS with specified elements as in the ‘vec!’ macro
Creates new VS with specified elements as in the ‘vec!’ macro

Structs

Lock-free iterator based on VS
Lock-free appendable list (also called VS)

Statics

GLOBAL_ALLOCsystem-alloc
Represents the use of the system’s allocator instead of rust’s default

Functions

Setup logger according to RUST_LOG env var (must enable “logs” feature)

Type Definitions