[−][src]Trait reclaim::Reclaim
A trait, which constitutes the foundation for the GlobalReclaim
trait.
This trait is specifically intended to be fully compatible with #[no_std]
environments.
This is expressed by the requirement to explicitly pass references to thread
local state or storage when calling functions that retire records.
If a reclamation scheme does not require or deliberately chooses to avoid
using thread local storage for the sake of simplicity or portability
(usually at the cost of performance), it is valid to implement Self::Local
as ()
and pass all retired records directly through to some global state.
Note, that this will generally require more and also more frequent
synchronization.
For cases in which Local
is defined to be ()
, there exists a blanket
implementation of `GlobalReclaim.
Associated Types
type Local: Sized
The type used for storing all relevant thread local state.
type RecordHeader: Default + Sync + Sized
Every record allocates this type alongside itself to store additional
reclamation scheme specific data.
When no such data is required, ()
is the recommended choice.
Required methods
unsafe fn retire_local<T: 'static, N: Unsigned>(
local: &Self::Local,
unlinked: Unlinked<T, Self, N>
)
local: &Self::Local,
unlinked: Unlinked<T, Self, N>
)
Retires a record and caches it at least until it is safe to deallocate it.
How to determine that no other thread can possibly have any (protected) reference to a record depends on the respective reclamation scheme.
Safety
The caller has to guarantee that the record is fully unlinked from
any data structure it was previously inserted in:
There must be no way for another thread to acquire a new reference to
the given unlinked
record.
While an Unlinked
value can only safely be obtained by atomic
operations that do in fact remove a value from its place in memory (i.e.
swap or compare-and-swap), this is only the necessary condition
for safe reclamation, but not always sufficient.
When a unique address to heap allocated memory is inserted in more than
one element of a shared data structure, it is still possible for other
threads to access this address even if its unlinked from one spot.
This invariant also mandates, that correct synchronization of atomic operations around calls to functions that retire records is ensured. Consider the following (incorrect) example:
let g = Atomic::from(Owned::new(1)); // thread 1 let expected = g.load_unprotected(Relaxed); // reads &1 let unlinked = g .compare_exchange(expected, Owned::null(), Relaxed, Relaxed) .unwrap(); unsafe { unlinked.retire() }; // thread 2 if let Some(shared) = g.load(Relaxed, &mut guard) { assert_eq!(*shared, &1); // !!! may read freed memory }
In this example, the invariant can not be guaranteed to be maintained,
due to the incorrect (relaxed) memory orderings.
Thread 1 can potentially unlink the shared value, retire and reclaim it,
without the compare_exchange
operation ever becoming visible to
thread 2.
The thread could then proceed to load and read the previous
value instead of the inserted null
, accessing freed memory.
unsafe fn retire_local_unchecked<T, N: Unsigned>(
local: &Self::Local,
unlinked: Unlinked<T, Self, N>
)
local: &Self::Local,
unlinked: Unlinked<T, Self, N>
)
Retires a record and caches it at least until it is safe to deallocate it.
How to determine that no other thread can possibly have any (protected) reference to a record depends on the respective reclamation scheme.
Safety
The same restrictions as with the retire_local
function apply here as well.
In addition to these invariants, this method additionally requires the
caller to ensure any Drop
implementation for T
or any contained type
does not access any non-static references.
The reclaim
interface makes no guarantees about the precise time a
retired record is actually reclaimed.
Hence, it is not possible to ensure any references stored within the
record have not become invalid at that point.
Provided methods
unsafe fn retire_local_raw<T, N: Unsigned>(
local: &Self::Local,
ptr: MarkedPtr<T, N>
)
local: &Self::Local,
ptr: MarkedPtr<T, N>
)
Retires a raw marked pointer to a record.
Safety
The same restrictions as with retire_local_unchecked
apply.
Since this function accepts a raw pointer, no type level checks on the validity are possible
and are hence the responsibility of the caller.
Panics
In debug mode, this function panics if ptr
is null
.
Implementors
impl Reclaim for Leaking
[src]
type Local = ()
type RecordHeader = ()
unsafe fn retire_local<T: 'static, N: Unsigned>(_: &(), _: Unlinked<T, N>)
[src]
Leaks the given value.
Safety
Contrary to the specifications of the trait's method, this particular implementation is always safe to call.
unsafe fn retire_local_unchecked<T, N: Unsigned>(_: &(), _: Unlinked<T, N>)
[src]
Leaks the given value.
Safety
Contrary to the specifications of the trait's method, this particular implementation is always safe to call.