From 3e1254d956d944a2909f61f733427350cd96f410 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Tue, 17 Jul 2018 20:51:31 +0200 Subject: [PATCH] sync::Once: Use Acquire on the hot path, and explain why we don't use it elsewhere --- src/libstd/sync/once.rs | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/libstd/sync/once.rs b/src/libstd/sync/once.rs index 51c42995d5e71..443e2a6980d9e 100644 --- a/src/libstd/sync/once.rs +++ b/src/libstd/sync/once.rs @@ -220,7 +220,11 @@ impl Once { #[stable(feature = "rust1", since = "1.0.0")] pub fn call_once(&self, f: F) where F: FnOnce() { // Fast path, just see if we've completed initialization. - if self.state.load(Ordering::SeqCst) == COMPLETE { + // An `Acquire` load is enough because that makes all the initialization + // operations visible to us. The cold path uses SeqCst consistently + // because the performance difference really does not matter there, + // and SeqCst minimizes the chances of something going wrong. + if self.state.load(Ordering::Acquire) == COMPLETE { return } @@ -277,7 +281,11 @@ impl Once { #[unstable(feature = "once_poison", issue = "33577")] pub fn call_once_force(&self, f: F) where F: FnOnce(&OnceState) { // same as above, just with a different parameter to `call_inner`. - if self.state.load(Ordering::SeqCst) == COMPLETE { + // An `Acquire` load is enough because that makes all the initialization + // operations visible to us. The cold path uses SeqCst consistently + // because the performance difference really does not matter there, + // and SeqCst minimizes the chances of something going wrong. + if self.state.load(Ordering::Acquire) == COMPLETE { return }