From 70216b40042cf58f14225cc2b687a9f5d6bb0d09 Mon Sep 17 00:00:00 2001 From: Imbris Date: Tue, 14 Feb 2023 09:31:04 -0500 Subject: [PATCH 1/2] AcqRel -> Release for compare_exchange success ordering in `race` module Since the load during success for compare exchange is `0`/`null` and no `Release` store of this value exists, using an `Aquire` load for this case adds no additional synchronization. Fixes https://github.com/matklad/once_cell/issues/220 --- src/race.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/race.rs b/src/race.rs index ee3d51a..e239159 100644 --- a/src/race.rs +++ b/src/race.rs @@ -57,7 +57,7 @@ impl OnceNonZeroUsize { #[inline] pub fn set(&self, value: NonZeroUsize) -> Result<(), ()> { let exchange = - self.inner.compare_exchange(0, value.get(), Ordering::AcqRel, Ordering::Acquire); + self.inner.compare_exchange(0, value.get(), Ordering::Release, Ordering::Acquire); match exchange { Ok(_) => Ok(()), Err(_) => Err(()), @@ -98,7 +98,7 @@ impl OnceNonZeroUsize { None => { let mut val = f()?.get(); let exchange = - self.inner.compare_exchange(0, val, Ordering::AcqRel, Ordering::Acquire); + self.inner.compare_exchange(0, val, Ordering::Release, Ordering::Acquire); if let Err(old) = exchange { val = old; } @@ -215,7 +215,7 @@ impl<'a, T> OnceRef<'a, T> { pub fn set(&self, value: &'a T) -> Result<(), ()> { let ptr = value as *const T as *mut T; let exchange = - self.inner.compare_exchange(ptr::null_mut(), ptr, Ordering::AcqRel, Ordering::Acquire); + self.inner.compare_exchange(ptr::null_mut(), ptr, Ordering::Release, Ordering::Acquire); match exchange { Ok(_) => Ok(()), Err(_) => Err(()), @@ -258,7 +258,7 @@ impl<'a, T> OnceRef<'a, T> { let exchange = self.inner.compare_exchange( ptr::null_mut(), ptr, - Ordering::AcqRel, + Ordering::Release, Ordering::Acquire, ); if let Err(old) = exchange { @@ -348,7 +348,7 @@ mod once_box { let exchange = self.inner.compare_exchange( ptr::null_mut(), ptr, - Ordering::AcqRel, + Ordering::Release, Ordering::Acquire, ); if let Err(_) = exchange { @@ -394,7 +394,7 @@ mod once_box { let exchange = self.inner.compare_exchange( ptr::null_mut(), ptr, - Ordering::AcqRel, + Ordering::Release, Ordering::Acquire, ); if let Err(old) = exchange { From bf0a819516c092060980f6e01c991c3ab756642e Mon Sep 17 00:00:00 2001 From: Imbris Date: Tue, 14 Feb 2023 09:52:06 -0500 Subject: [PATCH 2/2] Bump version to 1.17.1 and update the changelog. --- CHANGELOG.md | 6 ++++++ Cargo.toml | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3f3a862..b537f68 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,12 @@ - +## 1.17.1 + +- Make `OnceRef` implementation compliant with [strict provenance](https://github.com/rust-lang/rust/issues/95228). +- Weaken `compare_exchange` success case ordering in `race::*` implementations + from `AcqRel` to `Release`, [#xxx](https://github.com/matklad/once_cell/pull/xxx) + ## 1.17.0 - Add `race::OnceRef` for storing a `&'a T`. diff --git a/Cargo.toml b/Cargo.toml index 5ceec5e..ad02c34 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "once_cell" -version = "1.17.0" +version = "1.17.1" authors = ["Aleksey Kladov "] license = "MIT OR Apache-2.0" edition = "2021"