pub struct AtomicArc<T> { /* private fields */ }
Expand description
AtomicArc
owns the underlying instance, and allows users to perform atomic operations
on the pointer to it.
Implementations§
source§impl<T: 'static> AtomicArc<T>
impl<T: 'static> AtomicArc<T>
sourcepub fn new(t: T) -> Self
pub fn new(t: T) -> Self
Creates a new AtomicArc
from an instance of T
.
The type of the instance must be determined at compile-time, must not contain non-static
references, and must not be a non-static reference since the instance can, theoretically,
live as long as the process. For instance, struct Disallowed<'l, T>(&'l T)
is not
allowed, because an instance of the type cannot outlive 'l
whereas the garbage collector
does not guarantee that the instance is dropped within 'l
.
Examples
use scc::ebr::AtomicArc;
let atomic_arc: AtomicArc<usize> = AtomicArc::new(10);
source§impl<T> AtomicArc<T>
impl<T> AtomicArc<T>
sourcepub fn swap(
&self,
new: (Option<Arc<T>>, Tag),
order: Ordering
) -> (Option<Arc<T>>, Tag)
pub fn swap( &self, new: (Option<Arc<T>>, Tag), order: Ordering ) -> (Option<Arc<T>>, Tag)
Stores the given value into the AtomicArc
and returns the original value.
Examples
use scc::ebr::{Arc, AtomicArc, Barrier, Tag};
use std::sync::atomic::Ordering::Relaxed;
let atomic_arc: AtomicArc<usize> = AtomicArc::new(14);
let barrier = Barrier::new();
let (old, tag) = atomic_arc.swap((Some(Arc::new(15)), Tag::Second), Relaxed);
assert_eq!(tag, Tag::None);
assert_eq!(*old.unwrap(), 14);
let (old, tag) = atomic_arc.swap((None, Tag::First), Relaxed);
assert_eq!(tag, Tag::Second);
assert_eq!(*old.unwrap(), 15);
let (old, tag) = atomic_arc.swap((None, Tag::None), Relaxed);
assert_eq!(tag, Tag::First);
assert!(old.is_none());
sourcepub fn update_tag_if<F: FnMut(Ptr<'_, T>) -> bool>(
&self,
tag: Tag,
condition: F,
set_order: Ordering,
fetch_order: Ordering
) -> bool
pub fn update_tag_if<F: FnMut(Ptr<'_, T>) -> bool>( &self, tag: Tag, condition: F, set_order: Ordering, fetch_order: Ordering ) -> bool
Sets a new Tag
if the given condition is met.
Returns true
if the new Tag
has been successfully set.
Examples
use scc::ebr::{AtomicArc, Tag};
use std::sync::atomic::Ordering::Relaxed;
let atomic_arc: AtomicArc<usize> = AtomicArc::null();
assert!(atomic_arc.update_tag_if(Tag::Both, |p| p.tag() == Tag::None, Relaxed, Relaxed));
assert_eq!(atomic_arc.tag(Relaxed), Tag::Both);
sourcepub fn compare_exchange<'b>(
&self,
current: Ptr<'b, T>,
new: (Option<Arc<T>>, Tag),
success: Ordering,
failure: Ordering,
_barrier: &'b Barrier
) -> Result<(Option<Arc<T>>, Ptr<'b, T>), (Option<Arc<T>>, Ptr<'b, T>)>
pub fn compare_exchange<'b>( &self, current: Ptr<'b, T>, new: (Option<Arc<T>>, Tag), success: Ordering, failure: Ordering, _barrier: &'b Barrier ) -> Result<(Option<Arc<T>>, Ptr<'b, T>), (Option<Arc<T>>, Ptr<'b, T>)>
Stores new
into the AtomicArc
if the current value is the same as current
.
Returns the previously held value and the updated Ptr
.
Errors
Returns Err
with the supplied Arc
and the current Ptr
.
Examples
use scc::ebr::{Arc, AtomicArc, Barrier, Tag};
use std::sync::atomic::Ordering::Relaxed;
let atomic_arc: AtomicArc<usize> = AtomicArc::new(17);
let barrier = Barrier::new();
let mut ptr = atomic_arc.load(Relaxed, &barrier);
assert_eq!(*ptr.as_ref().unwrap(), 17);
atomic_arc.update_tag_if(Tag::Both, |_| true, Relaxed, Relaxed);
assert!(atomic_arc.compare_exchange(
ptr, (Some(Arc::new(18)), Tag::First), Relaxed, Relaxed, &barrier).is_err());
ptr.set_tag(Tag::Both);
let old: Arc<usize> = atomic_arc.compare_exchange(
ptr, (Some(Arc::new(18)), Tag::First), Relaxed, Relaxed, &barrier).unwrap().0.unwrap();
assert_eq!(*old, 17);
drop(old);
assert!(atomic_arc.compare_exchange(
ptr, (Some(Arc::new(19)), Tag::None), Relaxed, Relaxed, &barrier).is_err());
assert_eq!(*ptr.as_ref().unwrap(), 17);
sourcepub fn compare_exchange_weak<'b>(
&self,
current: Ptr<'b, T>,
new: (Option<Arc<T>>, Tag),
success: Ordering,
failure: Ordering,
_barrier: &'b Barrier
) -> Result<(Option<Arc<T>>, Ptr<'b, T>), (Option<Arc<T>>, Ptr<'b, T>)>
pub fn compare_exchange_weak<'b>( &self, current: Ptr<'b, T>, new: (Option<Arc<T>>, Tag), success: Ordering, failure: Ordering, _barrier: &'b Barrier ) -> Result<(Option<Arc<T>>, Ptr<'b, T>), (Option<Arc<T>>, Ptr<'b, T>)>
Stores new
into the AtomicArc
if the current value is the same as current
.
This method is allowed to spuriously fail even when the comparison succeeds.
Returns the previously held value and the updated Ptr
.
Errors
Returns Err
with the supplied Arc
and the current Ptr
.
Examples
use scc::ebr::{Arc, AtomicArc, Barrier, Tag};
use std::sync::atomic::Ordering::Relaxed;
let atomic_arc: AtomicArc<usize> = AtomicArc::new(17);
let barrier = Barrier::new();
let mut ptr = atomic_arc.load(Relaxed, &barrier);
assert_eq!(*ptr.as_ref().unwrap(), 17);
while let Err((_, actual)) = atomic_arc.compare_exchange_weak(
ptr,
(Some(Arc::new(18)), Tag::First),
Relaxed,
Relaxed,
&barrier) {
ptr = actual;
}
let mut ptr = atomic_arc.load(Relaxed, &barrier);
assert_eq!(*ptr.as_ref().unwrap(), 18);
sourcepub fn clone(&self, order: Ordering, _barrier: &Barrier) -> AtomicArc<T>
pub fn clone(&self, order: Ordering, _barrier: &Barrier) -> AtomicArc<T>
Clones self
including tags.
If self
is not supposed to be an AtomicArc::null
, this will never return an
AtomicArc::null
.
Examples
use scc::ebr::{Arc, AtomicArc, Barrier};
use std::sync::atomic::Ordering::Relaxed;
let atomic_arc: AtomicArc<usize> = AtomicArc::new(59);
let barrier = Barrier::new();
let atomic_arc_clone = atomic_arc.clone(Relaxed, &barrier);
let ptr = atomic_arc_clone.load(Relaxed, &barrier);
assert_eq!(*ptr.as_ref().unwrap(), 59);
sourcepub fn get_arc(&self, order: Ordering, _barrier: &Barrier) -> Option<Arc<T>>
pub fn get_arc(&self, order: Ordering, _barrier: &Barrier) -> Option<Arc<T>>
Tries to create an Arc
out of self
.
If self
is not supposed to be an AtomicArc::null
, this will never return None
.
Examples
use scc::ebr::{Arc, AtomicArc, Barrier};
use std::sync::atomic::Ordering::Relaxed;
let atomic_arc: AtomicArc<usize> = AtomicArc::new(47);
let barrier = Barrier::new();
let arc: Arc<usize> = atomic_arc.get_arc(Relaxed, &barrier).unwrap();
assert_eq!(*arc, 47);