From 7dcc6a8d6f2d8be2bd5792f010a53f285152e39b Mon Sep 17 00:00:00 2001 From: oliver-giersch Date: Tue, 21 Jul 2020 12:07:03 +0200 Subject: [PATCH] adds atomic_cxchg[weak]_rel_acq primitive and permits (Release, Acquire) ordering for CAS --- library/core/src/intrinsics.rs | 24 ++++++++++++++++++++++++ library/core/src/sync/atomic.rs | 4 ++++ src/librustc_codegen_llvm/intrinsic.rs | 1 + 3 files changed, 29 insertions(+) diff --git a/library/core/src/intrinsics.rs b/library/core/src/intrinsics.rs index 3a28bc79effaf..ed37cecc7f60d 100644 --- a/library/core/src/intrinsics.rs +++ b/library/core/src/intrinsics.rs @@ -104,6 +104,18 @@ extern "rust-intrinsic" { /// /// The stabilized version of this intrinsic is available on the /// `std::sync::atomic` types via the `compare_exchange` method by passing + /// [`Ordering::Release`](../../std/sync/atomic/enum.Ordering.html) + /// as the `success` and + /// [`Ordering::Acquire`](../../std/sync/atomic/enum.Ordering.html) + /// as the `failure` parameters. For example, + /// [`AtomicBool::compare_exchange`][compare_exchange]. + /// + /// [compare_exchange]: ../../std/sync/atomic/struct.AtomicBool.html#method.compare_exchange + pub fn atomic_cxchg_rel_acq(dst: *mut T, old: T, src: T) -> (T, bool); + /// Stores a value if the current value is the same as the `old` value. + /// + /// The stabilized version of this intrinsic is available on the + /// `std::sync::atomic` types via the `compare_exchange` method by passing /// [`Ordering::AcqRel`](../../std/sync/atomic/enum.Ordering.html) /// as the `success` and /// [`Ordering::Acquire`](../../std/sync/atomic/enum.Ordering.html) @@ -207,6 +219,18 @@ extern "rust-intrinsic" { /// /// The stabilized version of this intrinsic is available on the /// `std::sync::atomic` types via the `compare_exchange_weak` method by passing + /// [`Ordering::Release`](../../std/sync/atomic/enum.Ordering.html) + /// as the `success` and + /// [`Ordering::Acquire`](../../std/sync/atomic/enum.Ordering.html) + /// as the `failure` parameters. For example, + /// [`AtomicBool::compare_exchange_weak`][cew]. + /// + /// [cew]: ../../std/sync/atomic/struct.AtomicBool.html#method.compare_exchange_weak + pub fn atomic_cxchgweak_rel_acq(dst: *mut T, old: T, src: T) -> (T, bool); + /// Stores a value if the current value is the same as the `old` value. + /// + /// The stabilized version of this intrinsic is available on the + /// `std::sync::atomic` types via the `compare_exchange_weak` method by passing /// [`Ordering::AcqRel`](../../std/sync/atomic/enum.Ordering.html) /// as the `success` and /// [`Ordering::Acquire`](../../std/sync/atomic/enum.Ordering.html) diff --git a/library/core/src/sync/atomic.rs b/library/core/src/sync/atomic.rs index f31a4a0b7518d..0167120abbb0c 100644 --- a/library/core/src/sync/atomic.rs +++ b/library/core/src/sync/atomic.rs @@ -2421,6 +2421,8 @@ unsafe fn atomic_compare_exchange( let (val, ok) = unsafe { match (success, failure) { (Acquire, Acquire) => intrinsics::atomic_cxchg_acq(dst, old, new), + #[cfg(not(bootstrap))] + (Release, Acquire) => intrinsics::atomic_cxchg_rel_acq(dst, old, new), (Release, Relaxed) => intrinsics::atomic_cxchg_rel(dst, old, new), (AcqRel, Acquire) => intrinsics::atomic_cxchg_acqrel(dst, old, new), (Relaxed, Relaxed) => intrinsics::atomic_cxchg_relaxed(dst, old, new), @@ -2450,6 +2452,8 @@ unsafe fn atomic_compare_exchange_weak( let (val, ok) = unsafe { match (success, failure) { (Acquire, Acquire) => intrinsics::atomic_cxchgweak_acq(dst, old, new), + #[cfg(not(bootstrap))] + (Release, Acquire) => intrinsics::atomic_cxchgweak_rel_acq(dst, old, new), (Release, Relaxed) => intrinsics::atomic_cxchgweak_rel(dst, old, new), (AcqRel, Acquire) => intrinsics::atomic_cxchgweak_acqrel(dst, old, new), (Relaxed, Relaxed) => intrinsics::atomic_cxchgweak_relaxed(dst, old, new), diff --git a/src/librustc_codegen_llvm/intrinsic.rs b/src/librustc_codegen_llvm/intrinsic.rs index f1977946ee9b1..952e90e67b867 100644 --- a/src/librustc_codegen_llvm/intrinsic.rs +++ b/src/librustc_codegen_llvm/intrinsic.rs @@ -702,6 +702,7 @@ impl IntrinsicCallMethods<'tcx> for Builder<'a, 'll, 'tcx> { _ => self.sess().fatal("unknown ordering in atomic intrinsic"), }, 4 => match (split[2], split[3]) { + ("rel", "acq") if is_cxchg => (Release, Acquire), ("acq", "failrelaxed") if is_cxchg => (Acquire, Monotonic), ("acqrel", "failrelaxed") if is_cxchg => (AcquireRelease, Monotonic), _ => self.sess().fatal("unknown ordering in atomic intrinsic"),