Commit 40945d1c authored by Hai Dang's avatar Hai Dang
Browse files

duplicate example for dlist_arena

parent 977e8493
Pipeline #42403 passed with stage
in 26 minutes and 55 seconds
use ghostcell::dlist_arena::*;
use ghostcell::GhostToken;
use std::fmt;
use std::sync::RwLock;
use std::{fmt, thread, time};
use typed_arena::Arena as TypedArena;
fn print_list<'arena, 'id, T: fmt::Debug>(list: NodeRef<'arena, 'id, T>, token: &GhostToken<'id>) {
fn print_list<'arena, 'id, T: fmt::Debug>(tag : char, list: NodeRef<'arena, 'id, T>, token: &GhostToken<'id>) {
print!("[");
for d in Node::iter(list, token) {
print!("{:?}, ", d);
print!("{}{:?}, ", tag, d);
}
print!("]");
}
fn main() {
GhostToken::new(|mut token| {
let list_size = 1000;
let list_size = 50;
let arena = TypedArena::with_capacity(list_size as usize);
let list = &*Node::alloc(Node::new(0), &arena);
// Allocate a list from 0 to list_size - 1
let list = Node::alloc(Node::new(0), &arena);
let mut tail = list;
// To append to the list, we need a &mut GhostToken
(1..list_size).for_each(|i| {
let node = Node::alloc(Node::new(i), &arena);
Node::insert_next(tail, node, &mut token);
Node::insert_next(tail, &node, &mut token);
tail = node;
});
// Print the list we created
print!("Numbers: ");
print_list(&list, &token);
// This only needs a &GhostToken
print_list(' ', &list, &token);
println!();
// Oh, let's print it in parallel with thread `a` and thread `b`.
// Both threads only need a shared reference &token
// You should try rerunning several times to see that the `a`'s and
// `b`'s can interleave.
println!("Parallel printing: ");
rayon::join(
|| print_list('a', &list, &token),
|| print_list('b', &list, &token),
);
println!();
// Upon rejoining, we can mutate the list again.
// Delete the second half of the list, by deleting what tail points to.
// Mutation requires &mut GhostToken
(1..list_size / 2).for_each(|_| {
if let Some(prev) = tail.borrow(&token).prev() {
Node::remove(prev, &mut token)
let prev = prev.clone();
Node::remove(&prev, &mut token)
};
});
print!("Post deletion: ");
print_list(&list, &token);
print_list(' ', &list, &token);
println!();
// RwLock on the token to allow concurrent writes and reads.
let token : RwLock<GhostToken> = RwLock::new(token);
// Let's do concurrent reads first.
// You should try rerunning several times to see that the `a`'s and
// `b`'s can interleave.
println!("RwLock Concurrent Reads: ");
rayon::join(
|| {
let token : &GhostToken = &token.read().unwrap();
print_list('a', &list, &token);
},
|| {
let token : &GhostToken = &token.read().unwrap();
print_list('b', &list, &token);
}
);
println!();
println!("RwLock Concurrent Reads and Writes: ");
// You should rerun this several times to see that the read may come in
// before or after the write. If the read comes in later, it should
// print the updated data.
rayon::join(
|| {
// Sleeps to allow the writer thread to acquire a writer lock.
thread::sleep(time::Duration::from_micros(1));
let token : &GhostToken = &token.read().unwrap();
print_list('r', &list, token);
},
|| {
let token : &mut GhostToken = &mut token.write().unwrap();
Node::iter_mut(&list, token, |n| {
// add a 100 to the nodes' data
*n += 100; print!("w{:?} ", n);
});
},
);
println!();
});
}
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment