Struct concurrent::Atomic
[−]
[src]
pub struct Atomic<T> { /* fields omitted */ }
A concurrently accessible and updatable optional pointer.
This acts as a kind of concurrent Option<T>
. It can be compared to std::cell::RefCell
in
some ways: It allows accessing, referencing, updating, etc., however contrary to RefCell
,
this is concurrent and has no aliasing restrictions. It is further distinguished from
std::sync::AtomicPtr
in that it allows references to the inner data without the ABA problem
or any variant thereof.
It conveniently wraps this crates API in a seemless manner.
Methods
impl<T> Atomic<T>
[src]
fn new(init: Option<Box<T>>) -> Atomic<T>
Create a new concurrent option.
unsafe fn get_inner(&self) -> &AtomicPtr<T>
Get a mutable reference to the underlying std::sync::AtomicPtr
.
There is no overhead in this.
None
corresponds to the null pointer. Some(ptr)
corresponds to ptr
's address.
Safety
This is unsafe as you can easily invalidate the invariants. When using, you must ensure
that, if you drop, there are no existing readers/hazards of the Atomic
and that, if you
mutate, the value, you change to is valid.
unsafe fn get_inner_mut(&mut self) -> &mut AtomicPtr<T>
Get an immutable reference to the underlying std::sync::AtomicPtr
There is no overhead in this.
None
corresponds to the null pointer. Some(ptr)
corresponds to ptr
's address.
Safety
This is unsafe as you can easily invalidate the invariants. When using, you must ensure
that, if you drop, there are no existing readers/hazards of the Atomic
and that, if you
mutate, the value, you change to is valid.
fn load_raw(&self, ordering: Ordering) -> *mut T
Load the container's current pointer.
This gets the current pointer stored in self
. If self
is None
, the null pointer is
returned.
The ordering
defines what constraints the atomic operation has. Refer to the LLVM
documentation for more information.
Safety
As this returns a raw pointer, which does not have to abide by any rules, this is completely safe, however you got to be careful.
You may not dereference the returned pointer, as it can have been deallocated in the meantime. You must thus be very careful with what you do.
You cannot assume any validity of the address. The only assumptions, you can safely make,
is that this has been the pointer in self
at some point.
fn load(&self, ordering: Ordering) -> Option<Guard<T>>
Get a reference to the current content of the option.
This returns a Guard<T>
, which "protects" the inner value such that it is not dropped
before the guard is no longer active. This is all handled automatically through RAII.
The ordering
defines what constraints the atomic operation has. Refer to the LLVM
documentation for more information.
fn store(&self, new: Option<Box<T>>, ordering: Ordering)
Store a new value in the option.
The old value of self
will eventually be dropped, at some point after all the guarding
references are gone.
The ordering
defines what constraints the atomic operation has. Refer to the LLVM
documentation for more information.
fn swap(&self, new: Option<Box<T>>, ordering: Ordering) -> Option<Guard<T>>
Swap the old value with a new.
This returns a Guard<T>
as readers of the old values might exist. The old value will be
queued for destruction.
The ordering
defines what constraints the atomic operation has. Refer to the LLVM
documentation for more information.
Performance
This is slower than store
as it requires initializing a new guard, which requires at
least two atomic operations. Thus, when possible, you should use store
.
unsafe fn compare_and_store_raw(
&self,
old: *const T,
new: *mut T,
ordering: Ordering
) -> Result<(), ()>
&self,
old: *const T,
new: *mut T,
ordering: Ordering
) -> Result<(), ()>
Store a (raw) pointer if the current matches the specified pointer.
This compares self
to old
. If they match, the value is set to new
and Ok(())
is
returned. Otherwise, Err(())
is returned.
The ordering
defines what constraints the atomic operation has. Refer to the LLVM
documentation for more information.
Safety
As this accepts a raw pointer, it is necessary to mark it as unsafe
. To uphold the
invariants, ensure that new
isn't used (hereunder dropped) after this function has been
called, if it succeeds (returns Ok
).
Memory leak
If it fails (returns Err
), this function won't drop new
at any point. The handling of
its destructor lies solely on the caller of the function.
fn compare_and_store(
&self,
old: Option<*const T>,
new: Option<Box<T>>,
ordering: Ordering
) -> Result<(), Option<Box<T>>>
&self,
old: Option<*const T>,
new: Option<Box<T>>,
ordering: Ordering
) -> Result<(), Option<Box<T>>>
Store a pointer if the current matches the specified pointer.
This compares self
to old
. If they match, the value is set to new
and Ok(())
is
returned. Otherwise, Err(new)
is returned.
The ordering
defines what constraints the atomic operation has. Refer to the LLVM
documentation for more information.
unsafe fn compare_and_swap_raw(
&self,
old: *const T,
new: *mut T,
ordering: Ordering
) -> Result<Option<Guard<T>>, Option<Guard<T>>>
&self,
old: *const T,
new: *mut T,
ordering: Ordering
) -> Result<Option<Guard<T>>, Option<Guard<T>>>
Swap a (raw) pointer if it matches the specified pointer.
This compares self
to old
. If they match, it is swapped with new
and a guard to the
old value is returned wrapped in Ok
. If not, a tuple containing the guard to the actual
(non-matching) value, wrapped in Err()
is returned.
The ordering
defines what constraints the atomic operation has. Refer to the LLVM
documentation for more information.
Safety
As this accepts a raw pointer, it is necessary to mark it as unsafe
. To uphold the
invariants, ensure that new
isn't used (hereunder dropped) after this function has been
called, if it succeeds (returns Ok
).
Memory leak
If it fails (returns Err
), this function won't drop new
at any point. The handling of
its destructor lies solely on the caller of the function.
fn compare_and_swap(
&self,
old: Option<*const T>,
new: Option<Box<T>>,
ordering: Ordering
) -> Result<Option<Guard<T>>, (Option<Guard<T>>, Option<Box<T>>)>
&self,
old: Option<*const T>,
new: Option<Box<T>>,
ordering: Ordering
) -> Result<Option<Guard<T>>, (Option<Guard<T>>, Option<Box<T>>)>
Swap a pointer if it matches the specified pointer.
This compares self
to old
. If they match, it is swapped with new
and a guard to the
old value is returned wrapped in Ok
. If not, a tuple containing the guard to the actual
(non-matching) value and the box of new
— wrapped in Err
— is returned.
The ordering
defines what constraints the atomic operation has. Refer to the LLVM
documentation for more information.
Performance
This is slower than compare_and_store
as it requires initializing a new guard, which
requires at least two atomic operations. Thus, when possible, you should use
compare_and_store
.