Crate voluntary_servitude
source ·Expand description
Lock-free data-structures
Implements a lock-free thread-safe appendable list with a lock-free iterator
VoluntaryServitude
(also calledVS
)
Features
Lock-free thread-safe appendable list
Serde serialization ('serde-traits' feature)
Call this code from C (FFI)
(also in ./examples)- System Allocator (‘system-alloc’ feature)
Logging ('logs' feature)
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)
serde
serde-traits
Serde’s Serialize/Deserialize trait implementations behind the ‘serde-traits’ feature
Macros
Creates new
VS
with specified elements as in the ‘vec!’ macroStructs
Lock-free appendable list (also called
VS
)Statics
GLOBAL_ALLOC
system-alloc
Represents the use of the system’s allocator instead of rust’s default
Functions
setup_logger
logs
Setup logger according to
RUST_LOG
env var (must enable “logs” feature)Type Definitions
VoluntaryServitude
’s alias