Rollup merge of #98383 - m-ou-se:remove-memory-order-restrictions, r=joshtriplett
Remove restrictions on compare-exchange memory ordering. We currently don't allow the failure memory ordering of compare-exchange operations to be stronger than the success ordering, as was the case in C++11 when its memory model was copied to Rust. However, this restriction was lifted in C++17 as part of [p0418r2](https://wg21.link/p0418r2). It's time we lift the restriction too. | Success | Failure | Before | After | |---------|---------|--------|-------| | Relaxed | Relaxed | ✔️ | ✔️ | | Relaxed | Acquire | ❌ | ✔️ | | Relaxed | SeqCst | ❌ | ✔️ | | Acquire | Relaxed | ✔️ | ✔️ | | Acquire | Acquire | ✔️ | ✔️ | | Acquire | SeqCst | ❌ | ✔️ | | Release | Relaxed | ✔️ | ✔️ | | Release | Acquire | ❌ | ✔️ | | Release | SeqCst | ❌ | ✔️ | | AcqRel | Relaxed | ✔️ | ✔️ | | AcqRel | Acquire | ✔️ | ✔️ | | AcqRel | SeqCst | ❌ | ✔️ | | SeqCst | Relaxed | ✔️ | ✔️ | | SeqCst | Acquire | ✔️ | ✔️ | | SeqCst | SeqCst | ✔️ | ✔️ | | \* | Release | ❌ | ❌ | | \* | AcqRel | ❌ | ❌ | Fixes https://github.com/rust-lang/rust/issues/68464
This commit is contained in:
commit
796bc7cae3
@ -581,8 +581,7 @@ pub fn compare_and_swap(&self, current: bool, new: bool, order: Ordering) -> boo
|
||||
/// `failure` describes the required ordering for the load operation that takes place when
|
||||
/// the comparison fails. Using [`Acquire`] as success ordering makes the store part
|
||||
/// of this operation [`Relaxed`], and using [`Release`] makes the successful load
|
||||
/// [`Relaxed`]. The failure ordering can only be [`SeqCst`], [`Acquire`] or [`Relaxed`]
|
||||
/// and must be equivalent to or weaker than the success ordering.
|
||||
/// [`Relaxed`]. The failure ordering can only be [`SeqCst`], [`Acquire`] or [`Relaxed`].
|
||||
///
|
||||
/// **Note:** This method is only available on platforms that support atomic
|
||||
/// operations on `u8`.
|
||||
@ -640,8 +639,7 @@ pub fn compare_exchange(
|
||||
/// `failure` describes the required ordering for the load operation that takes place when
|
||||
/// the comparison fails. Using [`Acquire`] as success ordering makes the store part
|
||||
/// of this operation [`Relaxed`], and using [`Release`] makes the successful load
|
||||
/// [`Relaxed`]. The failure ordering can only be [`SeqCst`], [`Acquire`] or [`Relaxed`]
|
||||
/// and must be equivalent to or weaker than the success ordering.
|
||||
/// [`Relaxed`]. The failure ordering can only be [`SeqCst`], [`Acquire`] or [`Relaxed`].
|
||||
///
|
||||
/// **Note:** This method is only available on platforms that support atomic
|
||||
/// operations on `u8`.
|
||||
@ -941,8 +939,7 @@ pub fn as_mut_ptr(&self) -> *mut bool {
|
||||
/// Using [`Acquire`] as success ordering makes the store part of this
|
||||
/// operation [`Relaxed`], and using [`Release`] makes the final successful
|
||||
/// load [`Relaxed`]. The (failed) load ordering can only be [`SeqCst`],
|
||||
/// [`Acquire`] or [`Relaxed`] and must be equivalent to or weaker than the
|
||||
/// success ordering.
|
||||
/// [`Acquire`] or [`Relaxed`].
|
||||
///
|
||||
/// **Note:** This method is only available on platforms that support atomic
|
||||
/// operations on `u8`.
|
||||
@ -1301,8 +1298,7 @@ pub fn compare_and_swap(&self, current: *mut T, new: *mut T, order: Ordering) ->
|
||||
/// `failure` describes the required ordering for the load operation that takes place when
|
||||
/// the comparison fails. Using [`Acquire`] as success ordering makes the store part
|
||||
/// of this operation [`Relaxed`], and using [`Release`] makes the successful load
|
||||
/// [`Relaxed`]. The failure ordering can only be [`SeqCst`], [`Acquire`] or [`Relaxed`]
|
||||
/// and must be equivalent to or weaker than the success ordering.
|
||||
/// [`Relaxed`]. The failure ordering can only be [`SeqCst`], [`Acquire`] or [`Relaxed`].
|
||||
///
|
||||
/// **Note:** This method is only available on platforms that support atomic
|
||||
/// operations on pointers.
|
||||
@ -1347,8 +1343,7 @@ pub fn compare_exchange(
|
||||
/// `failure` describes the required ordering for the load operation that takes place when
|
||||
/// the comparison fails. Using [`Acquire`] as success ordering makes the store part
|
||||
/// of this operation [`Relaxed`], and using [`Release`] makes the successful load
|
||||
/// [`Relaxed`]. The failure ordering can only be [`SeqCst`], [`Acquire`] or [`Relaxed`]
|
||||
/// and must be equivalent to or weaker than the success ordering.
|
||||
/// [`Relaxed`]. The failure ordering can only be [`SeqCst`], [`Acquire`] or [`Relaxed`].
|
||||
///
|
||||
/// **Note:** This method is only available on platforms that support atomic
|
||||
/// operations on pointers.
|
||||
@ -1404,8 +1399,7 @@ pub fn compare_exchange_weak(
|
||||
/// Using [`Acquire`] as success ordering makes the store part of this
|
||||
/// operation [`Relaxed`], and using [`Release`] makes the final successful
|
||||
/// load [`Relaxed`]. The (failed) load ordering can only be [`SeqCst`],
|
||||
/// [`Acquire`] or [`Relaxed`] and must be equivalent to or weaker than the
|
||||
/// success ordering.
|
||||
/// [`Acquire`] or [`Relaxed`].
|
||||
///
|
||||
/// **Note:** This method is only available on platforms that support atomic
|
||||
/// operations on pointers.
|
||||
@ -2227,8 +2221,7 @@ pub fn compare_and_swap(&self,
|
||||
/// `failure` describes the required ordering for the load operation that takes place when
|
||||
/// the comparison fails. Using [`Acquire`] as success ordering makes the store part
|
||||
/// of this operation [`Relaxed`], and using [`Release`] makes the successful load
|
||||
/// [`Relaxed`]. The failure ordering can only be [`SeqCst`], [`Acquire`] or [`Relaxed`]
|
||||
/// and must be equivalent to or weaker than the success ordering.
|
||||
/// [`Relaxed`]. The failure ordering can only be [`SeqCst`], [`Acquire`] or [`Relaxed`].
|
||||
///
|
||||
/// **Note**: This method is only available on platforms that support atomic operations on
|
||||
#[doc = concat!("[`", $s_int_type, "`].")]
|
||||
@ -2279,8 +2272,7 @@ pub fn compare_exchange(&self,
|
||||
/// `failure` describes the required ordering for the load operation that takes place when
|
||||
/// the comparison fails. Using [`Acquire`] as success ordering makes the store part
|
||||
/// of this operation [`Relaxed`], and using [`Release`] makes the successful load
|
||||
/// [`Relaxed`]. The failure ordering can only be [`SeqCst`], [`Acquire`] or [`Relaxed`]
|
||||
/// and must be equivalent to or weaker than the success ordering.
|
||||
/// [`Relaxed`]. The failure ordering can only be [`SeqCst`], [`Acquire`] or [`Relaxed`].
|
||||
///
|
||||
/// **Note**: This method is only available on platforms that support atomic operations on
|
||||
#[doc = concat!("[`", $s_int_type, "`].")]
|
||||
@ -2517,8 +2509,7 @@ pub fn fetch_xor(&self, val: $int_type, order: Ordering) -> $int_type {
|
||||
///
|
||||
/// Using [`Acquire`] as success ordering makes the store part
|
||||
/// of this operation [`Relaxed`], and using [`Release`] makes the final successful load
|
||||
/// [`Relaxed`]. The (failed) load ordering can only be [`SeqCst`], [`Acquire`] or [`Relaxed`]
|
||||
/// and must be equivalent to or weaker than the success ordering.
|
||||
/// [`Relaxed`]. The (failed) load ordering can only be [`SeqCst`], [`Acquire`] or [`Relaxed`].
|
||||
///
|
||||
/// **Note**: This method is only available on platforms that support atomic operations on
|
||||
#[doc = concat!("[`", $s_int_type, "`].")]
|
||||
@ -3035,22 +3026,29 @@ unsafe fn atomic_compare_exchange<T: Copy>(
|
||||
let (val, ok) = unsafe {
|
||||
match (success, failure) {
|
||||
(Relaxed, Relaxed) => intrinsics::atomic_cxchg_relaxed_relaxed(dst, old, new),
|
||||
//(Relaxed, Acquire) => intrinsics::atomic_cxchg_relaxed_acquire(dst, old, new),
|
||||
//(Relaxed, SeqCst) => intrinsics::atomic_cxchg_relaxed_seqcst(dst, old, new),
|
||||
#[cfg(not(bootstrap))]
|
||||
(Relaxed, Acquire) => intrinsics::atomic_cxchg_relaxed_acquire(dst, old, new),
|
||||
#[cfg(not(bootstrap))]
|
||||
(Relaxed, SeqCst) => intrinsics::atomic_cxchg_relaxed_seqcst(dst, old, new),
|
||||
(Acquire, Relaxed) => intrinsics::atomic_cxchg_acquire_relaxed(dst, old, new),
|
||||
(Acquire, Acquire) => intrinsics::atomic_cxchg_acquire_acquire(dst, old, new),
|
||||
//(Acquire, SeqCst) => intrinsics::atomic_cxchg_acquire_seqcst(dst, old, new),
|
||||
#[cfg(not(bootstrap))]
|
||||
(Acquire, SeqCst) => intrinsics::atomic_cxchg_acquire_seqcst(dst, old, new),
|
||||
(Release, Relaxed) => intrinsics::atomic_cxchg_release_relaxed(dst, old, new),
|
||||
//(Release, Acquire) => intrinsics::atomic_cxchg_release_acquire(dst, old, new),
|
||||
//(Release, SeqCst) => intrinsics::atomic_cxchg_release_seqcst(dst, old, new),
|
||||
#[cfg(not(bootstrap))]
|
||||
(Release, Acquire) => intrinsics::atomic_cxchg_release_acquire(dst, old, new),
|
||||
#[cfg(not(bootstrap))]
|
||||
(Release, SeqCst) => intrinsics::atomic_cxchg_release_seqcst(dst, old, new),
|
||||
(AcqRel, Relaxed) => intrinsics::atomic_cxchg_acqrel_relaxed(dst, old, new),
|
||||
(AcqRel, Acquire) => intrinsics::atomic_cxchg_acqrel_acquire(dst, old, new),
|
||||
//(AcqRel, SeqCst) => intrinsics::atomic_cxchg_acqrel_seqcst(dst, old, new),
|
||||
#[cfg(not(bootstrap))]
|
||||
(AcqRel, SeqCst) => intrinsics::atomic_cxchg_acqrel_seqcst(dst, old, new),
|
||||
(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"),
|
||||
#[cfg(bootstrap)]
|
||||
_ => panic!("a failure ordering can't be stronger than a success ordering"),
|
||||
}
|
||||
};
|
||||
@ -3070,22 +3068,29 @@ unsafe fn atomic_compare_exchange_weak<T: Copy>(
|
||||
let (val, ok) = unsafe {
|
||||
match (success, failure) {
|
||||
(Relaxed, Relaxed) => intrinsics::atomic_cxchgweak_relaxed_relaxed(dst, old, new),
|
||||
//(Relaxed, Acquire) => intrinsics::atomic_cxchgweak_relaxed_acquire(dst, old, new),
|
||||
//(Relaxed, SeqCst) => intrinsics::atomic_cxchgweak_relaxed_seqcst(dst, old, new),
|
||||
#[cfg(not(bootstrap))]
|
||||
(Relaxed, Acquire) => intrinsics::atomic_cxchgweak_relaxed_acquire(dst, old, new),
|
||||
#[cfg(not(bootstrap))]
|
||||
(Relaxed, SeqCst) => intrinsics::atomic_cxchgweak_relaxed_seqcst(dst, old, new),
|
||||
(Acquire, Relaxed) => intrinsics::atomic_cxchgweak_acquire_relaxed(dst, old, new),
|
||||
(Acquire, Acquire) => intrinsics::atomic_cxchgweak_acquire_acquire(dst, old, new),
|
||||
//(Acquire, SeqCst) => intrinsics::atomic_cxchgweak_acquire_seqcst(dst, old, new),
|
||||
#[cfg(not(bootstrap))]
|
||||
(Acquire, SeqCst) => intrinsics::atomic_cxchgweak_acquire_seqcst(dst, old, new),
|
||||
(Release, Relaxed) => intrinsics::atomic_cxchgweak_release_relaxed(dst, old, new),
|
||||
//(Release, Acquire) => intrinsics::atomic_cxchgweak_release_acquire(dst, old, new),
|
||||
//(Release, SeqCst) => intrinsics::atomic_cxchgweak_release_seqcst(dst, old, new),
|
||||
#[cfg(not(bootstrap))]
|
||||
(Release, Acquire) => intrinsics::atomic_cxchgweak_release_acquire(dst, old, new),
|
||||
#[cfg(not(bootstrap))]
|
||||
(Release, SeqCst) => intrinsics::atomic_cxchgweak_release_seqcst(dst, old, new),
|
||||
(AcqRel, Relaxed) => intrinsics::atomic_cxchgweak_acqrel_relaxed(dst, old, new),
|
||||
(AcqRel, Acquire) => intrinsics::atomic_cxchgweak_acqrel_acquire(dst, old, new),
|
||||
//(AcqRel, SeqCst) => intrinsics::atomic_cxchgweak_acqrel_seqcst(dst, old, new),
|
||||
#[cfg(not(bootstrap))]
|
||||
(AcqRel, SeqCst) => intrinsics::atomic_cxchgweak_acqrel_seqcst(dst, old, new),
|
||||
(SeqCst, Relaxed) => intrinsics::atomic_cxchgweak_seqcst_relaxed(dst, old, new),
|
||||
(SeqCst, Acquire) => intrinsics::atomic_cxchgweak_seqcst_acquire(dst, old, new),
|
||||
(SeqCst, SeqCst) => intrinsics::atomic_cxchgweak_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"),
|
||||
#[cfg(bootstrap)]
|
||||
_ => panic!("a failure ordering can't be stronger than a success ordering"),
|
||||
}
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user