Commit bbdc7000 authored by Hai Dang's avatar Hai Dang
Browse files

extend dlist_arc example

parent 47c40f8a
Pipeline #42401 passed with stage
in 25 minutes and 31 seconds
use ghostcell::dlist_arc::*;
use ghostcell::GhostToken;
use std::fmt;
use std::sync::RwLock;
use std::{fmt, thread, time};
fn print_list<'id, T: fmt::Debug>(list: &NodePtr<'id, T>, token: &GhostToken<'id>) {
print!("[");
......@@ -12,11 +13,13 @@ fn print_list<'id, T: fmt::Debug>(list: &NodePtr<'id, T>, token: &GhostToken<'id
fn main() {
GhostToken::new(|mut token| {
let list_size = 1000;
let list_size = 50;
// Allocate a list from 0 to list_size - 1
let list: NodePtr<u32> = Node::alloc(Node::new(0));
let mut tail = list.clone();
// To append to the list, we need a &mut GhostToken
(1..list_size).for_each(|i| {
let node = Node::alloc(Node::new(i));
// Could replace this `clone` by a `take`...
......@@ -24,10 +27,30 @@ fn main() {
tail = node;
});
// Print the list we created
print!("Numbers: ");
// 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(
|| for d in Node::iter(&list, &token) {
print!("a{:?} ", d);
},
|| for d in Node::iter(&list, &token) {
print!("b{:?} ", d);
}
);
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() {
let prev = prev.clone();
......@@ -38,5 +61,51 @@ fn main() {
print!("Post deletion: ");
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();
for d in Node::iter(&list, token) {
print!("a{:?} ", d);
}
},
|| {
let token : &GhostToken = &token.read().unwrap();
for d in Node::iter(&list, token) {
print!("b{:?} ", d);
}
}
);
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(10));
let token : &GhostToken = &token.read().unwrap();
for d in Node::iter(&list, token) {
print!("r{:?} ", d);
}
},
|| {
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