summaryrefslogtreecommitdiffstats
path: root/library/stdarch/crates/core_arch/src/x86_64/cmpxchg16b.rs
diff options
context:
space:
mode:
Diffstat (limited to 'library/stdarch/crates/core_arch/src/x86_64/cmpxchg16b.rs')
-rw-r--r--library/stdarch/crates/core_arch/src/x86_64/cmpxchg16b.rs24
1 files changed, 13 insertions, 11 deletions
diff --git a/library/stdarch/crates/core_arch/src/x86_64/cmpxchg16b.rs b/library/stdarch/crates/core_arch/src/x86_64/cmpxchg16b.rs
index a262932af..a4fc0e732 100644
--- a/library/stdarch/crates/core_arch/src/x86_64/cmpxchg16b.rs
+++ b/library/stdarch/crates/core_arch/src/x86_64/cmpxchg16b.rs
@@ -16,10 +16,13 @@ use stdarch_test::assert_instr;
///
/// # Memory Orderings
///
-/// This atomic operations has the same semantics of memory orderings as
+/// This atomic operation has the same semantics of memory orderings as
/// `AtomicUsize::compare_exchange` does, only operating on 16 bytes of memory
/// instead of just a pointer.
///
+/// The failure ordering must be [`Ordering::SeqCst`], [`Ordering::Acquire`] or
+/// [`Ordering::Relaxed`].
+///
/// For more information on memory orderings here see the `compare_exchange`
/// documentation for other `Atomic*` types in the standard library.
///
@@ -33,15 +36,11 @@ use stdarch_test::assert_instr;
/// runtime to work correctly. If the CPU running the binary does not actually
/// support `cmpxchg16b` and the program enters an execution path that
/// eventually would reach this function the behavior is undefined.
-///
-/// The failure ordering must be [`Ordering::SeqCst`], [`Ordering::Acquire`] or
-/// [`Ordering::Relaxed`], or this function call is undefined. See the `Atomic*`
-/// documentation's `compare_exchange` function for more information. When
-/// `compare_exchange` panics, this is undefined behavior. Currently this
-/// function aborts the process with an undefined instruction.
#[inline]
+#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
#[cfg_attr(test, assert_instr(cmpxchg16b, success = Ordering::SeqCst, failure = Ordering::SeqCst))]
#[target_feature(enable = "cmpxchg16b")]
+#[stable(feature = "cmpxchg16b_intrinsic", since = "1.67.0")]
pub unsafe fn cmpxchg16b(
dst: *mut u128,
old: u128,
@@ -53,6 +52,8 @@ pub unsafe fn cmpxchg16b(
debug_assert!(dst as usize % 16 == 0);
+ // Copied from `atomic_compare_exchange` in `core`.
+ // https://github.com/rust-lang/rust/blob/f8a2e49/library/core/src/sync/atomic.rs#L3046-L3079
let (val, _ok) = match (success, failure) {
(Relaxed, Relaxed) => intrinsics::atomic_cxchg_relaxed_relaxed(dst, old, new),
(Relaxed, Acquire) => intrinsics::atomic_cxchg_relaxed_acquire(dst, old, new),
@@ -69,11 +70,12 @@ pub unsafe fn cmpxchg16b(
(SeqCst, Relaxed) => intrinsics::atomic_cxchg_seqcst_relaxed(dst, old, new),
(SeqCst, Acquire) => intrinsics::atomic_cxchg_seqcst_acquire(dst, old, new),
(SeqCst, SeqCst) => intrinsics::atomic_cxchg_seqcst_seqcst(dst, old, new),
+ (_, AcqRel) => panic!("there is no such thing as an acquire-release failure ordering"),
+ (_, Release) => panic!("there is no such thing as a release failure ordering"),
- // The above block is all copied from libcore, and this statement is
- // also copied from libcore except that it's a panic in libcore and we
- // have a little bit more of a lightweight panic here.
- _ => crate::core_arch::x86::ud2(),
+ // `atomic::Ordering` is non_exhaustive. It warns when `core_arch` is built as a part of `core`.
+ #[allow(unreachable_patterns)]
+ (_, _) => unreachable!(),
};
val
}