pub fn fence(order: Ordering)
An atomic fence.
Depending on the specified order, a fence prevents the compiler and CPU from reordering certain types of memory operations around it. That creates synchronizes-with relationships between it and atomic operations or fences in other threads.
A fence 'A' which has (at least) Release
ordering semantics, synchronizes with a fence 'B' with (at least) Acquire
semantics, if and only if there exist operations X and Y, both operating on some atomic object 'M' such that A is sequenced before X, Y is synchronized before B and Y observes the change to M. This provides a happens-before dependence between A and B.
Thread 1 Thread 2 fence(Release); A -------------- x.store(3, Relaxed); X --------- | | | | | -------------> Y if x.load(Relaxed) == 3 { |-------> B fence(Acquire); ... }
Atomic operations with Release
or Acquire
semantics can also synchronize with a fence.
A fence which has SeqCst
ordering, in addition to having both Acquire
and Release
semantics, participates in the global program order of the other SeqCst
operations and/or fences.
Accepts Acquire
, Release
, AcqRel
and SeqCst
orderings.
Panics if order
is Relaxed
.
use std::sync::atomic::AtomicBool; use std::sync::atomic::fence; use std::sync::atomic::Ordering; // A mutual exclusion primitive based on spinlock. pub struct Mutex { flag: AtomicBool, } impl Mutex { pub fn new() -> Mutex { Mutex { flag: AtomicBool::new(false), } } pub fn lock(&self) { while !self.flag.compare_and_swap(false, true, Ordering::Relaxed) {} // This fence synchronizes-with store in `unlock`. fence(Ordering::Acquire); } pub fn unlock(&self) { self.flag.store(false, Ordering::Release); } }
© 2010 The Rust Project Developers
Licensed under the Apache License, Version 2.0 or the MIT license, at your option.
https://doc.rust-lang.org/std/sync/atomic/fn.fence.html