Struct rs_lockfree::hazard_epoch::HazardEpoch[][src]

pub struct HazardEpoch { /* fields omitted */ }

HazardEpoch a practical implementation of Hazard Pointers, which use global incremental version to identify shared object to be reclaimed. Because of False sharing, a part of the member variables, might be frequently modified by different threads, are aligned to 64 bytes.

Methods

impl HazardEpoch
[src]

To improve performance, HazardEpoch can be allocated in stack directly, but it can't be moved after calling any method. thread_waiting_threshold means the maximum of the number of shared objects to be reclaimed under one thread. min_version_cache_time_us means the time interval(microsecond) to update minimum version cache.

Examples

use rs_lockfree::hazard_epoch::HazardEpoch;

let h = unsafe { HazardEpoch::new_in_stack(64, 200000) };
let addr_h = &h as *const _ as usize;
assert_eq!(addr_h % 64, 0);

Alloc HazardEpoch in heap. Usage is the same as new_in_stack.

Examples

use rs_lockfree::hazard_epoch::HazardEpoch;

let h = HazardEpoch::new_in_heap(64, 200000);
let _addr_h = &h as *const _ as usize;

Return Self::new_in_stack(64, 200000)

Return Self::new_in_heap(64, 200000)

Reclaim all shared objects waiting to be reclaimed. It will be called when dropping HazardEpoch.

Examples

use rs_lockfree::hazard_epoch::HazardEpoch;
use rs_lockfree::hazard_epoch::BaseHazardNode;

let mut h = HazardEpoch::new_in_heap(64, 200000);
let node = Box::into_raw(Box::new(BaseHazardNode::default()));
unsafe { h.add_node(node); }
unsafe { h.retire(); }

Reclaim all shared objects waiting to be reclaimed. node can be any type as long as it implements Trait HazardNodeT. BaseHazardNode is used to realize vtable.

Examples

use rs_lockfree::hazard_epoch::HazardEpoch;
use rs_lockfree::hazard_epoch::{BaseHazardNode, HazardNodeT};
use std::cell::RefCell;

struct Node<'a, T> {
    base: BaseHazardNode,
    cnt: &'a RefCell<i32>,
    v: T,
}

impl<'a, T> Drop for Node<'a, T> {
    fn drop(&mut self) {
        *self.cnt.borrow_mut() += 10;
    }
}

impl<'a, T> HazardNodeT for Node<'a, T> {
    fn get_base_hazard_node(&self) -> *mut BaseHazardNode {
        &self.base as *const _ as *mut _
    }
}

let cnt = RefCell::new(0);
let mut h = HazardEpoch::default_new_in_heap();
let node = Box::into_raw(Box::new(Node{
    base: Default::default(),
    cnt: &cnt,
    v: 2333,
}));
unsafe { h.add_node(node); }
drop(h);
assert_eq!(*cnt.borrow(), 10);

Before accessing a shared object, call method acquire to get the handle of this operation.

Examples

use rs_lockfree::hazard_epoch::HazardEpoch;
use rs_lockfree::hazard_epoch::BaseHazardNode;
use rs_lockfree::error::Status;

let mut h = HazardEpoch::default_new_in_heap();
let node = Box::into_raw(Box::new(BaseHazardNode::default()));
let mut handle = 0;
assert_eq!(h.acquire(&mut handle), Status::Success);
let _o = unsafe { &(*node) };
unsafe { h.release(handle); }

After accessing a shared object, call method release to trigger reclaiming. Usage is the same as acquire.

Atomic load count of shared objects waiting to be reclaimed.

Trait Implementations

impl Drop for HazardEpoch
[src]

Executes the destructor for this type. Read more

Auto Trait Implementations

impl !Send for HazardEpoch

impl !Sync for HazardEpoch