pub struct Domain { /* private fields */ }
Expand description

A Hazard-Pointer-Domain that can be used either globally as a shared Domain or as a per Object Domain to seperate the Domains of different Instances of Objects.

What is a Hazard-Pointer-Domain

A Hazard-Pointer-Domain is a collection of Hazard-Pointers and allows you to seperate different Parts of a System, where you know that they dont need access to the Hazard-Pointers of other Parts. This could lead to performance improvements as all the Parts only check the Hazard-Pointers that are actually relevant for them.

Where to use a different Hazard-Pointer-Domain

Like previously mentioned different Domains are useful to seperate an entire System into smaller Parts, however there are also other cases where having a custom Domain can be useful.

Seperating Datastructure Instances

Having seperate Domains for individual Datastructures can help with Performance, because for example if you have two Lists and they were to share a single Domain, List 1 has to check the Hazard-Pointers for List 2 everytime it needs to work with Hazard-Pointers although they are not relevant in that Case.

Implementations

Creates a new Hazard-Pointer-Domain

Params

reclaim_threshold: The Threshold for waiting Items before attempting to reclaim Memory

Reads the Data from the given AtomicPtr and protects it using a Hazard- Ptr. Returns you a Guard through which you can interact with the Data loaded from the AtomicPtr and as long as the Guard lives, the Data is safe to access and use

Example
let domain = hazard_ptr::Domain::new(10);

// Create an AtomicPtr with some Value
let ptr = Box::into_raw(Box::new(13));
let atom_ptr = atomic::AtomicPtr::new(ptr);

// Get protected Access to the Value pointed to
let guarded = domain.protect(&atom_ptr, atomic::Ordering::SeqCst);
// Access the inner Value
assert_eq!(13, *guarded);

unsafe {
    // Retire/"Free" the Data
    domain.retire(ptr, |p| { unsafe { Box::from_raw(p) }; });
}

// As long as we still have the Guard, the Data will not actually be
// reclaimed and can still be used safely
assert_eq!(13, *guarded);

Creates a new empty Guard, that can then be used to protect any sort of Data behind an AtomicPtr.

Marks the given Ptr as retired and once no more Hazard-Ptrs protect the same Ptr, the given retire_fn function will be called to properly clean up the Data.

Note

There is no garantue as to when the given Ptr will actually be retired using the given function, because the Hazard-Pointer that protects the Data may be stored somewhere or the Thread that was responsible for it crashed/wont respond/is not running again and therefore can not mark it as unused anymore.

Safety

The given Pointer must not be reachable anymore, meaning that it can not be loaded anymore or any new Guards pointing to it can be created. However it is okay to have outstanding Guards pointing to it that may still be used and those are still valid.

This garantue is already held up by most algorithms as they first swap out the Pointer from any shared references and then perform a call to retire, which is valid in this case as the pointer can not be loaded anymore from the shared reference.

Forces a reclaimation cycle, however this does not garantue that any Nodes/Ptrs will actually be reclaimed, as they might all still be protected/in use

Use Cases

This might be useful in a very performance sensitive application, where you want to avoid running the Reclaimation while in a Hot-Path. In these Cases, you can set the reclaimation threshold to a very large Value when creating the Domain, as to avoid triggering it by accident, and then call this function manually outside of the Hot-Path.

Trait Implementations

Returns a copy of the value. Read more

Performs copy-assignment from source. Read more

Formats the value using the given formatter. Read more

Auto Trait Implementations

Blanket Implementations

Gets the TypeId of self. Read more

Immutably borrows from an owned value. Read more

Mutably borrows from an owned value. Read more

Returns the argument unchanged.

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

The resulting type after obtaining ownership.

Creates owned data from borrowed data, usually by cloning. Read more

Uses borrowed data to replace owned data, usually by cloning. Read more

The type returned in the event of a conversion error.

Performs the conversion.

The type returned in the event of a conversion error.

Performs the conversion.