diff options
| author | Paul Menage <menage@gmail.com> | 2024-10-17 12:21:53 -0700 |
|---|---|---|
| committer | Paul Menage <menage@gmail.com> | 2024-10-17 12:21:53 -0700 |
| commit | cf7ff15a0ddfe0713dd794cd39eb3b3b58ba8d27 (patch) | |
| tree | 4b14a1e05b6fca5c17fc010616fc9547ac143651 /library/std/src/sys/pal | |
| parent | 3a85d3fa785d95a7b7bcf4f160b67bffba7afd4a (diff) | |
| download | rust-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/pal')
| -rw-r--r-- | library/std/src/sys/pal/hermit/futex.rs | 9 | ||||
| -rw-r--r-- | library/std/src/sys/pal/unix/futex.rs | 9 | ||||
| -rw-r--r-- | library/std/src/sys/pal/wasm/atomics/futex.rs | 9 | ||||
| -rw-r--r-- | library/std/src/sys/pal/windows/futex.rs | 35 |
4 files changed, 41 insertions, 21 deletions
diff --git a/library/std/src/sys/pal/hermit/futex.rs b/library/std/src/sys/pal/hermit/futex.rs index 21c5facd52f..670383b45ac 100644 --- a/library/std/src/sys/pal/hermit/futex.rs +++ b/library/std/src/sys/pal/hermit/futex.rs @@ -3,9 +3,14 @@ use crate::ptr::null; use crate::sync::atomic::AtomicU32; use crate::time::Duration; +/// An atomic for use as a futex that is at least 32-bits but may be larger +pub type Futex = AtomicU32; +/// Must be the underlying type of Futex +pub type Primitive = u32; + /// An atomic for use as a futex that is at least 8-bits but may be larger. -pub type SmallAtomic = AtomicU32; -/// Must be the underlying type of SmallAtomic +pub type SmallFutex = AtomicU32; +/// Must be the underlying type of SmallFutex pub type SmallPrimitive = u32; pub fn futex_wait(futex: &AtomicU32, expected: u32, timeout: Option<Duration>) -> bool { diff --git a/library/std/src/sys/pal/unix/futex.rs b/library/std/src/sys/pal/unix/futex.rs index cc725045c48..0fc765dc87a 100644 --- a/library/std/src/sys/pal/unix/futex.rs +++ b/library/std/src/sys/pal/unix/futex.rs @@ -11,9 +11,14 @@ use crate::sync::atomic::AtomicU32; use crate::time::Duration; +/// An atomic for use as a futex that is at least 32-bits but may be larger +pub type Futex = AtomicU32; +/// Must be the underlying type of Futex +pub type Primitive = u32; + /// An atomic for use as a futex that is at least 8-bits but may be larger. -pub type SmallAtomic = AtomicU32; -/// Must be the underlying type of SmallAtomic +pub type SmallFutex = AtomicU32; +/// Must be the underlying type of SmallFutex pub type SmallPrimitive = u32; /// Waits for a `futex_wake` operation to wake us. diff --git a/library/std/src/sys/pal/wasm/atomics/futex.rs b/library/std/src/sys/pal/wasm/atomics/futex.rs index 42913a99ee9..bdad0da73f0 100644 --- a/library/std/src/sys/pal/wasm/atomics/futex.rs +++ b/library/std/src/sys/pal/wasm/atomics/futex.rs @@ -6,9 +6,14 @@ use core::arch::wasm64 as wasm; use crate::sync::atomic::AtomicU32; use crate::time::Duration; +/// An atomic for use as a futex that is at least 32-bits but may be larger +pub type Futex = AtomicU32; +/// Must be the underlying type of Futex +pub type Primitive = u32; + /// An atomic for use as a futex that is at least 8-bits but may be larger. -pub type SmallAtomic = AtomicU32; -/// Must be the underlying type of SmallAtomic +pub type SmallFutex = AtomicU32; +/// Must be the underlying type of SmallFutex pub type SmallPrimitive = u32; /// Wait for a futex_wake operation to wake us. diff --git a/library/std/src/sys/pal/windows/futex.rs b/library/std/src/sys/pal/windows/futex.rs index 4d6c4df9a5a..38afb8c043b 100644 --- a/library/std/src/sys/pal/windows/futex.rs +++ b/library/std/src/sys/pal/windows/futex.rs @@ -9,22 +9,27 @@ use core::{mem, ptr}; use super::api::{self, WinError}; use crate::sys::{c, dur2timeout}; +/// An atomic for use as a futex that is at least 32-bits but may be larger +pub type Futex = AtomicU32; +/// Must be the underlying type of Futex +pub type Primitive = u32; + /// An atomic for use as a futex that is at least 8-bits but may be larger. -pub type SmallAtomic = AtomicU8; -/// Must be the underlying type of SmallAtomic +pub type SmallFutex = AtomicU8; +/// Must be the underlying type of SmallFutex pub type SmallPrimitive = u8; -pub unsafe trait Futex {} +pub unsafe trait Futexable {} pub unsafe trait Waitable { - type Atomic; + type Futex; } macro_rules! unsafe_waitable_int { ($(($int:ty, $atomic:ty)),*$(,)?) => { $( unsafe impl Waitable for $int { - type Atomic = $atomic; + type Futex = $atomic; } - unsafe impl Futex for $atomic {} + unsafe impl Futexable for $atomic {} )* }; } @@ -42,15 +47,15 @@ unsafe_waitable_int! { (usize, AtomicUsize), } unsafe impl<T> Waitable for *const T { - type Atomic = AtomicPtr<T>; + type Futex = AtomicPtr<T>; } unsafe impl<T> Waitable for *mut T { - type Atomic = AtomicPtr<T>; + type Futex = AtomicPtr<T>; } -unsafe impl<T> Futex for AtomicPtr<T> {} +unsafe impl<T> Futexable for AtomicPtr<T> {} pub fn wait_on_address<W: Waitable>( - address: &W::Atomic, + address: &W::Futex, compare: W, timeout: Option<Duration>, ) -> bool { @@ -63,30 +68,30 @@ pub fn wait_on_address<W: Waitable>( } } -pub fn wake_by_address_single<T: Futex>(address: &T) { +pub fn wake_by_address_single<T: Futexable>(address: &T) { unsafe { let addr = ptr::from_ref(address).cast::<c_void>(); c::WakeByAddressSingle(addr); } } -pub fn wake_by_address_all<T: Futex>(address: &T) { +pub fn wake_by_address_all<T: Futexable>(address: &T) { unsafe { let addr = ptr::from_ref(address).cast::<c_void>(); c::WakeByAddressAll(addr); } } -pub fn futex_wait<W: Waitable>(futex: &W::Atomic, expected: W, timeout: Option<Duration>) -> bool { +pub fn futex_wait<W: Waitable>(futex: &W::Futex, expected: W, timeout: Option<Duration>) -> bool { // return false only on timeout wait_on_address(futex, expected, timeout) || api::get_last_error() != WinError::TIMEOUT } -pub fn futex_wake<T: Futex>(futex: &T) -> bool { +pub fn futex_wake<T: Futexable>(futex: &T) -> bool { wake_by_address_single(futex); false } -pub fn futex_wake_all<T: Futex>(futex: &T) { +pub fn futex_wake_all<T: Futexable>(futex: &T) { wake_by_address_all(futex) } |
