about summary refs log tree commit diff
path: root/library/std/src/sys/sync/once
diff options
context:
space:
mode:
authorPaul Menage <menage@gmail.com>2024-10-17 12:21:53 -0700
committerPaul Menage <menage@gmail.com>2024-10-17 12:21:53 -0700
commitcf7ff15a0ddfe0713dd794cd39eb3b3b58ba8d27 (patch)
tree4b14a1e05b6fca5c17fc010616fc9547ac143651 /library/std/src/sys/sync/once
parent3a85d3fa785d95a7b7bcf4f160b67bffba7afd4a (diff)
downloadrust-cf7ff15a0ddfe0713dd794cd39eb3b3b58ba8d27.tar.gz
rust-cf7ff15a0ddfe0713dd794cd39eb3b3b58ba8d27.zip
Abstract the state type for futexes
In the same way that we expose SmallAtomic and SmallPrimitive to allow
Windows to use a value other than an AtomicU32 for its futex state, this
patch switches the primary futex state type from AtomicU32 to
futex::Atomic.  The futex::Atomic type should be usable as an atomic
value with underlying primitive type equal to futex::Primitive.

This allows supporting the futex API on systems where the underlying
kernel futex implementation requires more state than simply an
AtomicU32.

All in-tree futex implementations simply define {Atomic,Primitive}
directly as {AtomicU32,u32}.
Diffstat (limited to 'library/std/src/sys/sync/once')
-rw-r--r--library/std/src/sys/sync/once/futex.rs25
-rw-r--r--library/std/src/sys/sync/once/queue.rs2
2 files changed, 13 insertions, 14 deletions
diff --git a/library/std/src/sys/sync/once/futex.rs b/library/std/src/sys/sync/once/futex.rs
index 25588a4217b..10bfa81a6d7 100644
--- a/library/std/src/sys/sync/once/futex.rs
+++ b/library/std/src/sys/sync/once/futex.rs
@@ -1,39 +1,38 @@
 use crate::cell::Cell;
 use crate::sync as public;
-use crate::sync::atomic::AtomicU32;
 use crate::sync::atomic::Ordering::{Acquire, Relaxed, Release};
 use crate::sync::once::ExclusiveState;
-use crate::sys::futex::{futex_wait, futex_wake_all};
+use crate::sys::futex::{Futex, Primitive, futex_wait, futex_wake_all};
 
 // On some platforms, the OS is very nice and handles the waiter queue for us.
 // This means we only need one atomic value with 4 states:
 
 /// No initialization has run yet, and no thread is currently using the Once.
-const INCOMPLETE: u32 = 0;
+const INCOMPLETE: Primitive = 0;
 /// Some thread has previously attempted to initialize the Once, but it panicked,
 /// so the Once is now poisoned. There are no other threads currently accessing
 /// this Once.
-const POISONED: u32 = 1;
+const POISONED: Primitive = 1;
 /// Some thread is currently attempting to run initialization. It may succeed,
 /// so all future threads need to wait for it to finish.
-const RUNNING: u32 = 2;
+const RUNNING: Primitive = 2;
 /// Initialization has completed and all future calls should finish immediately.
-const COMPLETE: u32 = 3;
+const COMPLETE: Primitive = 3;
 
 // An additional bit indicates whether there are waiting threads:
 
 /// May only be set if the state is not COMPLETE.
-const QUEUED: u32 = 4;
+const QUEUED: Primitive = 4;
 
 // Threads wait by setting the QUEUED bit and calling `futex_wait` on the state
 // variable. When the running thread finishes, it will wake all waiting threads using
 // `futex_wake_all`.
 
-const STATE_MASK: u32 = 0b11;
+const STATE_MASK: Primitive = 0b11;
 
 pub struct OnceState {
     poisoned: bool,
-    set_state_to: Cell<u32>,
+    set_state_to: Cell<Primitive>,
 }
 
 impl OnceState {
@@ -49,8 +48,8 @@ impl OnceState {
 }
 
 struct CompletionGuard<'a> {
-    state_and_queued: &'a AtomicU32,
-    set_state_on_drop_to: u32,
+    state_and_queued: &'a Futex,
+    set_state_on_drop_to: Primitive,
 }
 
 impl<'a> Drop for CompletionGuard<'a> {
@@ -65,13 +64,13 @@ impl<'a> Drop for CompletionGuard<'a> {
 }
 
 pub struct Once {
-    state_and_queued: AtomicU32,
+    state_and_queued: Futex,
 }
 
 impl Once {
     #[inline]
     pub const fn new() -> Once {
-        Once { state_and_queued: AtomicU32::new(INCOMPLETE) }
+        Once { state_and_queued: Futex::new(INCOMPLETE) }
     }
 
     #[inline]
diff --git a/library/std/src/sys/sync/once/queue.rs b/library/std/src/sys/sync/once/queue.rs
index 17abaf0bf26..3e83a4a088f 100644
--- a/library/std/src/sys/sync/once/queue.rs
+++ b/library/std/src/sys/sync/once/queue.rs
@@ -23,7 +23,7 @@
 // You'll find a few more details in the implementation, but that's the gist of
 // it!
 //
-// Atomic orderings:
+// Futex orderings:
 // When running `Once` we deal with multiple atomics:
 // `Once.state_and_queue` and an unknown number of `Waiter.signaled`.
 // * `state_and_queue` is used (1) as a state flag, (2) for synchronizing the