pub struct RelaxedAtomic<T: AtomicRepr> { /* private fields */ }Expand description
Provides inner mutability for Copy types via relaxed atomic operations.
On x86_64 and ARM, relaxed loads and stores compile to the same instructions
as regular memory accesses — no LOCK prefix is emitted. This makes
RelaxedAtomic a zero-overhead way to achieve interior mutability without
the bus-lock cost of fetch_* or CAS operations.
Deliberately exposes only load and store. The fetch_* methods are
omitted because they emit LOCK-prefixed instructions with measurable
overhead. Instead, use the load–mutate–store pattern:
let counter = RelaxedAtomic::new(0u32);
let val = counter.load();
counter.store(val + 1);§When to use
Use when a field needs interior mutability and is accessed without
contention (same pattern as the original C code using plain loads/stores).
If you need multi-step atomic operations (CAS, fetch_add), use the
underlying std::sync::atomic types directly.
§When not to use
Do not use when the operation must be atomic relative to other threads. The load–mutate–store pattern is not atomic as a whole — it can race with concurrent stores. Use only where the C code would have used a non-atomic access that happens to be race-free by design.
Implementations§
Source§impl<T: AtomicRepr> RelaxedAtomic<T>
impl<T: AtomicRepr> RelaxedAtomic<T>
Sourcepub fn into_inner(self) -> T
pub fn into_inner(self) -> T
Consume the atomic and return the inner value.
Source§impl RelaxedAtomic<u32>
impl RelaxedAtomic<u32>
Sourcepub fn fetch_add(&self, val: u32) -> u32
pub fn fetch_add(&self, val: u32) -> u32
Atomic add with relaxed ordering.
Returns the previous value. This is an atomic read-modify-write operation
that compiles to a LOCK XADD instruction on x86_64. While it does emit
a LOCK prefix, it avoids the stronger ordering fence overhead of SeqCst.
Use this for atomic increments where the load-mutate-store pattern would cause race conditions.
Trait Implementations§
Source§impl<T: AtomicRepr> Clone for RelaxedAtomic<T>
impl<T: AtomicRepr> Clone for RelaxedAtomic<T>
Source§impl<T: Debug + AtomicRepr> Debug for RelaxedAtomic<T>
impl<T: Debug + AtomicRepr> Debug for RelaxedAtomic<T>
Source§impl<T: AtomicRepr + Default> Default for RelaxedAtomic<T>
impl<T: AtomicRepr + Default> Default for RelaxedAtomic<T>
Source§impl<T: AtomicRepr + Display> Display for RelaxedAtomic<T>
impl<T: AtomicRepr + Display> Display for RelaxedAtomic<T>
impl<T: AtomicRepr + Eq> Eq for RelaxedAtomic<T>
Source§impl<T: AtomicRepr + PartialEq> PartialEq for RelaxedAtomic<T>
WARNING: This performs two separate relaxed loads. Under concurrent writes
the two values may come from different points in time. This is a race condition
(not a data race) — Rust does not prevent it.
impl<T: AtomicRepr + PartialEq> PartialEq for RelaxedAtomic<T>
WARNING: This performs two separate relaxed loads. Under concurrent writes the two values may come from different points in time. This is a race condition (not a data race) — Rust does not prevent it.
Use this ONLY for diagnostic assertions, debug checks, or logging. NEVER use this for correctness-critical decisions like:
- Deciding whether to proceed with an operation
- Checking if a resource is available
- Validating state transitions
For correctness-critical comparisons, load both values atomically first:
let a = atomic_a.load(Ordering::SeqCst);
let b = atomic_b.load(Ordering::SeqCst);
if a == b { /* safe to proceed */ }Auto Trait Implementations§
impl<T> Freeze for RelaxedAtomic<T>
impl<T> RefUnwindSafe for RelaxedAtomic<T>
impl<T> Send for RelaxedAtomic<T>
impl<T> Sync for RelaxedAtomic<T>
impl<T> Unpin for RelaxedAtomic<T>
impl<T> UnsafeUnpin for RelaxedAtomic<T>
impl<T> UnwindSafe for RelaxedAtomic<T>
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
Source§fn equivalent(&self, key: &K) -> bool
fn equivalent(&self, key: &K) -> bool
key and return true if they are equal.Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
Source§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> Pointable for T
impl<T> Pointable for T
Source§impl<T> PolicyExt for Twhere
T: ?Sized,
impl<T> PolicyExt for Twhere
T: ?Sized,
Source§impl<T> ToCompactString for Twhere
T: Display,
impl<T> ToCompactString for Twhere
T: Display,
Source§fn try_to_compact_string(&self) -> Result<CompactString, ToCompactStringError>
fn try_to_compact_string(&self) -> Result<CompactString, ToCompactStringError>
ToCompactString::to_compact_string() Read moreSource§fn to_compact_string(&self) -> CompactString
fn to_compact_string(&self) -> CompactString
CompactString. Read more