rsgc 1.1.0

Concurrent GC library for Rust
Documentation
use rsgc::{
    heap::{region::HeapArguments, thread::Thread},
    system::object::{Allocation, Handle},
    system::traits::Object,
};

#[allow(dead_code)]
pub struct TreeNode {
    item: i64,
    left: Option<Handle<Self>>,
    right: Option<Handle<Self>>,
}


unsafe impl Object for TreeNode {
    fn trace(&self, visitor: &mut dyn rsgc::system::traits::Visitor) {
        if let Some(ref left) = self.left {
            left.trace(visitor);
        }

        if let Some(ref right) = self.right {
            right.trace(visitor);
        }
    }
}

unsafe impl Allocation for TreeNode {
    const FINALIZE: bool = false;
    const DESTRUCTIBLE: bool = false;
}

impl TreeNode {
    fn check_tree(&self) -> usize {
        if self.left.is_none() {
            return 1;
        }

        1 + self.left.unwrap().check_tree() + self.right.unwrap().check_tree()
    }
}


fn create_tree(thread: &mut Thread, depth: i64) -> Handle<TreeNode> {
    thread.safepoint();
    let node = if 0 < depth {
        let mut node = thread.allocate(TreeNode {
            item: 0,
            left: None,
            right: None,
        });

        let left = create_tree(thread, depth - 1);
        let right = create_tree(thread, depth - 1);

        thread.write_barrier(node);
        node.left = Some(left);
        node.right = Some(right);

        node 
    } else {
        let node = TreeNode {
            item: 0,
            left: None,
            right: None,
        };

        thread.allocate(node)
    };
    
    
    node
}


fn bench() {
    let mut n = 0;
    if let Some(arg) = std::env::args().skip(1).next() {
        if let Ok(x) = arg.parse::<usize>() {
            n = x;
        }
    }

    let min_depth = 4;
    let max_depth = if n < (min_depth + 2) {
        min_depth + 2
    } else {
        n 
    };

    let start = std::time::Instant::now();
    let stretch_depth = max_depth + 1;

    {
        println!(
            "stretch tree of depth {}\t check: {}",
            stretch_depth,
            create_tree(Thread::current(), stretch_depth as _)
                .as_ref()
                .check_tree()
        );
    }

    let long_lasting_tree = create_tree(Thread::current(), max_depth as _);
    let thread = Thread::current();

    let mut d = min_depth;

    while d <= max_depth {
        let depth = d;

        let iterations = 1 << (max_depth - depth + min_depth);

        let mut check = 0;

        for _ in 1..=iterations {
            
            let tree_node = create_tree(thread, depth as _);
            
            check += tree_node.as_ref().check_tree();

        }

        println!("{}\t trees of depth {}\t check: {}", iterations, depth, check);

        d += 2;
    }

    println!(
        "long lived tree of depth {}\t check: {}",
        max_depth,
        long_lasting_tree.as_ref().check_tree()
    );

    println!(
        "time: {}ms",
        start.elapsed().as_millis()
    );
}

fn main() {
    env_logger::init();
    let args = HeapArguments::from_env();

    let _ = rsgc::thread::main_thread(args, |heap| {
        heap.add_core_root_set();

        bench();

        Ok(())
    });
}