diff options
| author | Yuki Okushi <jtitor@2k36.org> | 2022-07-18 08:39:57 +0900 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2022-07-18 08:39:57 +0900 |
| commit | 796bc7cae364b39ff7e5139842b51dd9b764060d (patch) | |
| tree | ce79b2e9250d96491caa4a01bf0b217d60a234a4 | |
| parent | 263edd43c5255084292329423c61a9d69715ebfa (diff) | |
| parent | a898f413795d923d1a025517458fa0fd2d7291ac (diff) | |
| download | rust-796bc7cae364b39ff7e5139842b51dd9b764060d.tar.gz rust-796bc7cae364b39ff7e5139842b51dd9b764060d.zip | |
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 | :heavy_check_mark: | :heavy_check_mark: | | Relaxed | Acquire | :x: | :heavy_check_mark: | | Relaxed | SeqCst | :x: | :heavy_check_mark: | | Acquire | Relaxed | :heavy_check_mark: | :heavy_check_mark: | | Acquire | Acquire | :heavy_check_mark: | :heavy_check_mark: | | Acquire | SeqCst | :x: | :heavy_check_mark: | | Release | Relaxed | :heavy_check_mark: | :heavy_check_mark: | | Release | Acquire | :x: | :heavy_check_mark: | | Release | SeqCst | :x: | :heavy_check_mark: | | AcqRel | Relaxed | :heavy_check_mark: | :heavy_check_mark: | | AcqRel | Acquire | :heavy_check_mark: | :heavy_check_mark: | | AcqRel | SeqCst | :x: | :heavy_check_mark: | | SeqCst | Relaxed | :heavy_check_mark: | :heavy_check_mark: | | SeqCst | Acquire | :heavy_check_mark: | :heavy_check_mark: | | SeqCst | SeqCst | :heavy_check_mark: | :heavy_check_mark: | | \* | Release | :x: | :x: | | \* | AcqRel | :x: | :x: | Fixes https://github.com/rust-lang/rust/issues/68464
| -rw-r--r-- | library/core/src/sync/atomic.rs | 65 |
1 files changed, 35 insertions, 30 deletions
diff --git a/library/core/src/sync/atomic.rs b/library/core/src/sync/atomic.rs index ebc769ac7ca..b636dc491a4 100644 --- a/library/core/src/sync/atomic.rs +++ b/library/core/src/sync/atomic.rs @@ -581,8 +581,7 @@ impl AtomicBool { /// `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 @@ impl AtomicBool { /// `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 @@ impl AtomicBool { /// 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 @@ impl<T> AtomicPtr<T> { /// `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 @@ impl<T> AtomicPtr<T> { /// `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 @@ impl<T> AtomicPtr<T> { /// 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 @@ macro_rules! atomic_int { /// `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 @@ macro_rules! atomic_int { /// `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 @@ macro_rules! atomic_int { /// /// 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"), } }; |
