Struct crossbeam_epoch::Atomic [−][src]
An atomic pointer that can be safely shared between threads.
The pointer must be properly aligned. Since it is aligned, a tag can be stored into the unused
least significant bits of the address. For example, the tag for a pointer to a sized type T
should be less than (1 << mem::align_of::<T>().trailing_zeros())
.
Any method that loads the pointer must be passed a reference to a Guard
.
Crossbeam supports dynamically sized types. See Pointable
for details.
Implementations
impl<T> Atomic<T>
[src]
pub fn new(init: T) -> Atomic<T>
[src]
Allocates value
on the heap and returns a new atomic pointer pointing to it.
Examples
use crossbeam_epoch::Atomic; let a = Atomic::new(1234);
impl<T: ?Sized + Pointable> Atomic<T>
[src]
pub fn init(init: T::Init) -> Atomic<T>
[src]
Allocates value
on the heap and returns a new atomic pointer pointing to it.
Examples
use crossbeam_epoch::Atomic; let a = Atomic::<i32>::init(1234);
pub fn null() -> Atomic<T>
[src]
Returns a new null atomic pointer.
Examples
use crossbeam_epoch::Atomic; let a = Atomic::<i32>::null();
pub fn load<'g>(&self, ord: Ordering, _: &'g Guard) -> Shared<'g, T>
[src]
Loads a Shared
from the atomic pointer.
This method takes an Ordering
argument which describes the memory ordering of this
operation.
Examples
use crossbeam_epoch::{self as epoch, Atomic}; use std::sync::atomic::Ordering::SeqCst; let a = Atomic::new(1234); let guard = &epoch::pin(); let p = a.load(SeqCst, guard);
pub fn load_consume<'g>(&self, _: &'g Guard) -> Shared<'g, T>
[src]
Loads a Shared
from the atomic pointer using a “consume” memory ordering.
This is similar to the “acquire” ordering, except that an ordering is only guaranteed with operations that “depend on” the result of the load. However consume loads are usually much faster than acquire loads on architectures with a weak memory model since they don’t require memory fence instructions.
The exact definition of “depend on” is a bit vague, but it works as you would expect in practice since a lot of software, especially the Linux kernel, rely on this behavior.
Examples
use crossbeam_epoch::{self as epoch, Atomic}; let a = Atomic::new(1234); let guard = &epoch::pin(); let p = a.load_consume(guard);
pub fn store<P: Pointer<T>>(&self, new: P, ord: Ordering)
[src]
Stores a Shared
or Owned
pointer into the atomic pointer.
This method takes an Ordering
argument which describes the memory ordering of this
operation.
Examples
use crossbeam_epoch::{Atomic, Owned, Shared}; use std::sync::atomic::Ordering::SeqCst; let a = Atomic::new(1234); a.store(Shared::null(), SeqCst); a.store(Owned::new(1234), SeqCst);
pub fn swap<'g, P: Pointer<T>>(
&self,
new: P,
ord: Ordering,
_: &'g Guard
) -> Shared<'g, T>
[src]
&self,
new: P,
ord: Ordering,
_: &'g Guard
) -> Shared<'g, T>
Stores a Shared
or Owned
pointer into the atomic pointer, returning the previous
Shared
.
This method takes an Ordering
argument which describes the memory ordering of this
operation.
Examples
use crossbeam_epoch::{self as epoch, Atomic, Shared}; use std::sync::atomic::Ordering::SeqCst; let a = Atomic::new(1234); let guard = &epoch::pin(); let p = a.swap(Shared::null(), SeqCst, guard);
pub fn compare_exchange<'g, P>(
&self,
current: Shared<'_, T>,
new: P,
success: Ordering,
failure: Ordering,
_: &'g Guard
) -> Result<Shared<'g, T>, CompareExchangeError<'g, T, P>> where
P: Pointer<T>,
[src]
&self,
current: Shared<'_, T>,
new: P,
success: Ordering,
failure: Ordering,
_: &'g Guard
) -> Result<Shared<'g, T>, CompareExchangeError<'g, T, P>> where
P: Pointer<T>,
Stores the pointer new
(either Shared
or Owned
) into the atomic pointer if the current
value is the same as current
. The tag is also taken into account, so two pointers to the
same object, but with different tags, will not be considered equal.
The return value is a result indicating whether the new pointer was written. On success the
pointer that was written is returned. On failure the actual current value and new
are
returned.
This method takes two Ordering
arguments to describe the memory
ordering of this operation. success
describes the required ordering for the
read-modify-write operation that takes place if the comparison with current
succeeds.
failure
describes the required ordering for the load operation that takes place when
the comparison fails. Using Acquire
as success ordering makes the store part
of this operation Relaxed
, and using Release
makes the successful load
Relaxed
. The failure ordering can only be SeqCst
, Acquire
or Relaxed
and must be equivalent to or weaker than the success ordering.
Examples
use crossbeam_epoch::{self as epoch, Atomic, Owned, Shared}; use std::sync::atomic::Ordering::SeqCst; let a = Atomic::new(1234); let guard = &epoch::pin(); let curr = a.load(SeqCst, guard); let res1 = a.compare_exchange(curr, Shared::null(), SeqCst, SeqCst, guard); let res2 = a.compare_exchange(curr, Owned::new(5678), SeqCst, SeqCst, guard);
pub fn compare_exchange_weak<'g, P>(
&self,
current: Shared<'_, T>,
new: P,
success: Ordering,
failure: Ordering,
_: &'g Guard
) -> Result<Shared<'g, T>, CompareExchangeError<'g, T, P>> where
P: Pointer<T>,
[src]
&self,
current: Shared<'_, T>,
new: P,
success: Ordering,
failure: Ordering,
_: &'g Guard
) -> Result<Shared<'g, T>, CompareExchangeError<'g, T, P>> where
P: Pointer<T>,
Stores the pointer new
(either Shared
or Owned
) into the atomic pointer if the current
value is the same as current
. The tag is also taken into account, so two pointers to the
same object, but with different tags, will not be considered equal.
Unlike compare_exchange
, this method is allowed to spuriously fail even when comparison
succeeds, which can result in more efficient code on some platforms. The return value is a
result indicating whether the new pointer was written. On success the pointer that was
written is returned. On failure the actual current value and new
are returned.
This method takes two Ordering
arguments to describe the memory
ordering of this operation. success
describes the required ordering for the
read-modify-write operation that takes place if the comparison with current
succeeds.
failure
describes the required ordering for the load operation that takes place when
the comparison fails. Using Acquire
as success ordering makes the store part
of this operation Relaxed
, and using Release
makes the successful load
Relaxed
. The failure ordering can only be SeqCst
, Acquire
or Relaxed
and must be equivalent to or weaker than the success ordering.
Examples
use crossbeam_epoch::{self as epoch, Atomic, Owned, Shared}; use std::sync::atomic::Ordering::SeqCst; let a = Atomic::new(1234); let guard = &epoch::pin(); let mut new = Owned::new(5678); let mut ptr = a.load(SeqCst, guard); loop { match a.compare_exchange_weak(ptr, new, SeqCst, SeqCst, guard) { Ok(p) => { ptr = p; break; } Err(err) => { ptr = err.current; new = err.new; } } } let mut curr = a.load(SeqCst, guard); loop { match a.compare_exchange_weak(curr, Shared::null(), SeqCst, SeqCst, guard) { Ok(_) => break, Err(err) => curr = err.current, } }
pub fn compare_and_set<'g, O, P>(
&self,
current: Shared<'_, T>,
new: P,
ord: O,
guard: &'g Guard
) -> Result<Shared<'g, T>, CompareAndSetError<'g, T, P>> where
O: CompareAndSetOrdering,
P: Pointer<T>,
[src]
&self,
current: Shared<'_, T>,
new: P,
ord: O,
guard: &'g Guard
) -> Result<Shared<'g, T>, CompareAndSetError<'g, T, P>> where
O: CompareAndSetOrdering,
P: Pointer<T>,
Use compare_exchange
instead
Stores the pointer new
(either Shared
or Owned
) into the atomic pointer if the current
value is the same as current
. The tag is also taken into account, so two pointers to the
same object, but with different tags, will not be considered equal.
The return value is a result indicating whether the new pointer was written. On success the
pointer that was written is returned. On failure the actual current value and new
are
returned.
This method takes a CompareAndSetOrdering
argument which describes the memory
ordering of this operation.
Migrating to compare_exchange
compare_and_set
is equivalent to compare_exchange
with the following mapping for
memory orderings:
Original | Success | Failure |
---|---|---|
Relaxed | Relaxed | Relaxed |
Acquire | Acquire | Acquire |
Release | Release | Relaxed |
AcqRel | AcqRel | Acquire |
SeqCst | SeqCst | SeqCst |
Examples
use crossbeam_epoch::{self as epoch, Atomic, Owned, Shared}; use std::sync::atomic::Ordering::SeqCst; let a = Atomic::new(1234); let guard = &epoch::pin(); let curr = a.load(SeqCst, guard); let res1 = a.compare_and_set(curr, Shared::null(), SeqCst, guard); let res2 = a.compare_and_set(curr, Owned::new(5678), SeqCst, guard);
pub fn compare_and_set_weak<'g, O, P>(
&self,
current: Shared<'_, T>,
new: P,
ord: O,
guard: &'g Guard
) -> Result<Shared<'g, T>, CompareAndSetError<'g, T, P>> where
O: CompareAndSetOrdering,
P: Pointer<T>,
[src]
&self,
current: Shared<'_, T>,
new: P,
ord: O,
guard: &'g Guard
) -> Result<Shared<'g, T>, CompareAndSetError<'g, T, P>> where
O: CompareAndSetOrdering,
P: Pointer<T>,
Use compare_exchange_weak
instead
Stores the pointer new
(either Shared
or Owned
) into the atomic pointer if the current
value is the same as current
. The tag is also taken into account, so two pointers to the
same object, but with different tags, will not be considered equal.
Unlike compare_and_set
, this method is allowed to spuriously fail even when comparison
succeeds, which can result in more efficient code on some platforms. The return value is a
result indicating whether the new pointer was written. On success the pointer that was
written is returned. On failure the actual current value and new
are returned.
This method takes a CompareAndSetOrdering
argument which describes the memory
ordering of this operation.
Migrating to compare_exchange_weak
compare_and_set_weak
is equivalent to compare_exchange_weak
with the following mapping for
memory orderings:
Original | Success | Failure |
---|---|---|
Relaxed | Relaxed | Relaxed |
Acquire | Acquire | Acquire |
Release | Release | Relaxed |
AcqRel | AcqRel | Acquire |
SeqCst | SeqCst | SeqCst |
Examples
use crossbeam_epoch::{self as epoch, Atomic, Owned, Shared}; use std::sync::atomic::Ordering::SeqCst; let a = Atomic::new(1234); let guard = &epoch::pin(); let mut new = Owned::new(5678); let mut ptr = a.load(SeqCst, guard); loop { match a.compare_and_set_weak(ptr, new, SeqCst, guard) { Ok(p) => { ptr = p; break; } Err(err) => { ptr = err.current; new = err.new; } } } let mut curr = a.load(SeqCst, guard); loop { match a.compare_and_set_weak(curr, Shared::null(), SeqCst, guard) { Ok(_) => break, Err(err) => curr = err.current, } }
pub fn fetch_and<'g>(
&self,
val: usize,
ord: Ordering,
_: &'g Guard
) -> Shared<'g, T>
[src]
&self,
val: usize,
ord: Ordering,
_: &'g Guard
) -> Shared<'g, T>
Bitwise “and” with the current tag.
Performs a bitwise “and” operation on the current tag and the argument val
, and sets the
new tag to the result. Returns the previous pointer.
This method takes an Ordering
argument which describes the memory ordering of this
operation.
Examples
use crossbeam_epoch::{self as epoch, Atomic, Shared}; use std::sync::atomic::Ordering::SeqCst; let a = Atomic::<i32>::from(Shared::null().with_tag(3)); let guard = &epoch::pin(); assert_eq!(a.fetch_and(2, SeqCst, guard).tag(), 3); assert_eq!(a.load(SeqCst, guard).tag(), 2);
pub fn fetch_or<'g>(
&self,
val: usize,
ord: Ordering,
_: &'g Guard
) -> Shared<'g, T>
[src]
&self,
val: usize,
ord: Ordering,
_: &'g Guard
) -> Shared<'g, T>
Bitwise “or” with the current tag.
Performs a bitwise “or” operation on the current tag and the argument val
, and sets the
new tag to the result. Returns the previous pointer.
This method takes an Ordering
argument which describes the memory ordering of this
operation.
Examples
use crossbeam_epoch::{self as epoch, Atomic, Shared}; use std::sync::atomic::Ordering::SeqCst; let a = Atomic::<i32>::from(Shared::null().with_tag(1)); let guard = &epoch::pin(); assert_eq!(a.fetch_or(2, SeqCst, guard).tag(), 1); assert_eq!(a.load(SeqCst, guard).tag(), 3);
pub fn fetch_xor<'g>(
&self,
val: usize,
ord: Ordering,
_: &'g Guard
) -> Shared<'g, T>
[src]
&self,
val: usize,
ord: Ordering,
_: &'g Guard
) -> Shared<'g, T>
Bitwise “xor” with the current tag.
Performs a bitwise “xor” operation on the current tag and the argument val
, and sets the
new tag to the result. Returns the previous pointer.
This method takes an Ordering
argument which describes the memory ordering of this
operation.
Examples
use crossbeam_epoch::{self as epoch, Atomic, Shared}; use std::sync::atomic::Ordering::SeqCst; let a = Atomic::<i32>::from(Shared::null().with_tag(1)); let guard = &epoch::pin(); assert_eq!(a.fetch_xor(3, SeqCst, guard).tag(), 1); assert_eq!(a.load(SeqCst, guard).tag(), 2);
pub unsafe fn into_owned(self) -> Owned<T>
[src]
Takes ownership of the pointee.
This consumes the atomic and converts it into Owned
. As Atomic
doesn’t have a
destructor and doesn’t drop the pointee while Owned
does, this is suitable for
destructors of data structures.
Panics
Panics if this pointer is null, but only in debug mode.
Safety
This method may be called only if the pointer is valid and nobody else is holding a reference to the same object.
Examples
struct DataStructure { ptr: Atomic<usize>, } impl Drop for DataStructure { fn drop(&mut self) { // By now the DataStructure lives only in our thread and we are sure we don't hold // any Shared or & to it ourselves. unsafe { drop(mem::replace(&mut self.ptr, Atomic::null()).into_owned()); } } }
Trait Implementations
impl<T: ?Sized + Pointable> Clone for Atomic<T>
[src]
fn clone(&self) -> Self
[src]
Returns a copy of the atomic value.
Note that a Relaxed
load is used here. If you need synchronization, use it with other
atomics or fences.
pub fn clone_from(&mut self, source: &Self)
1.0.0[src]
impl<T: ?Sized + Pointable> Debug for Atomic<T>
[src]
impl<T: ?Sized + Pointable> Default for Atomic<T>
[src]
impl<T> From<*const T> for Atomic<T>
[src]
fn from(raw: *const T) -> Self
[src]
Returns a new atomic pointer pointing to raw
.
Examples
use std::ptr; use crossbeam_epoch::Atomic; let a = Atomic::<i32>::from(ptr::null::<i32>());
impl<T> From<Box<T, Global>> for Atomic<T>
[src]
impl<T: ?Sized + Pointable> From<Owned<T>> for Atomic<T>
[src]
fn from(owned: Owned<T>) -> Self
[src]
Returns a new atomic pointer pointing to owned
.
Examples
use crossbeam_epoch::{Atomic, Owned}; let a = Atomic::<i32>::from(Owned::new(1234));
impl<'g, T: ?Sized + Pointable> From<Shared<'g, T>> for Atomic<T>
[src]
fn from(ptr: Shared<'g, T>) -> Self
[src]
Returns a new atomic pointer pointing to ptr
.
Examples
use crossbeam_epoch::{Atomic, Shared}; let a = Atomic::<i32>::from(Shared::<i32>::null());
impl<T> From<T> for Atomic<T>
[src]
impl<T: ?Sized + Pointable> Pointer for Atomic<T>
[src]
impl<T: ?Sized + Pointable + Send + Sync> Send for Atomic<T>
[src]
impl<T: ?Sized + Pointable + Send + Sync> Sync for Atomic<T>
[src]
Auto Trait Implementations
impl<T: ?Sized> RefUnwindSafe for Atomic<T> where
T: RefUnwindSafe,
T: RefUnwindSafe,
impl<T: ?Sized> Unpin for Atomic<T>
impl<T: ?Sized> UnwindSafe for Atomic<T> where
T: RefUnwindSafe,
T: RefUnwindSafe,
Blanket Implementations
impl<T> Any for T where
T: 'static + ?Sized,
[src]
T: 'static + ?Sized,
impl<T> Borrow<T> for T where
T: ?Sized,
[src]
T: ?Sized,
impl<T> BorrowMut<T> for T where
T: ?Sized,
[src]
T: ?Sized,
pub fn borrow_mut(&mut self) -> &mut T
[src]
impl<T> From<!> for T
[src]
impl<T> From<T> for T
[src]
impl<T, U> Into<U> for T where
U: From<T>,
[src]
U: From<T>,
impl<T> ToOwned for T where
T: Clone,
[src]
T: Clone,
type Owned = T
The resulting type after obtaining ownership.
pub fn to_owned(&self) -> T
[src]
pub fn clone_into(&self, target: &mut T)
[src]
impl<T, U> TryFrom<U> for T where
U: Into<T>,
[src]
U: Into<T>,
type Error = Infallible
The type returned in the event of a conversion error.
pub fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>
[src]
impl<T, U> TryInto<U> for T where
U: TryFrom<T>,
[src]
U: TryFrom<T>,