diff options
Diffstat (limited to 'library/std/src/sys/pal/windows/futex.rs')
| -rw-r--r-- | library/std/src/sys/pal/windows/futex.rs | 53 |
1 files changed, 43 insertions, 10 deletions
diff --git a/library/std/src/sys/pal/windows/futex.rs b/library/std/src/sys/pal/windows/futex.rs index 88f20ed270b..bc19c402d9c 100644 --- a/library/std/src/sys/pal/windows/futex.rs +++ b/library/std/src/sys/pal/windows/futex.rs @@ -4,21 +4,58 @@ use crate::sys::dur2timeout; use core::ffi::c_void; use core::mem; use core::ptr; +use core::sync::atomic::{ + AtomicBool, AtomicI16, AtomicI32, AtomicI64, AtomicI8, AtomicIsize, AtomicPtr, AtomicU16, + AtomicU32, AtomicU64, AtomicU8, AtomicUsize, +}; use core::time::Duration; -#[inline(always)] -pub fn wait_on_address<T, U>(address: &T, compare: U, timeout: Option<Duration>) -> bool { - assert_eq!(mem::size_of::<T>(), mem::size_of::<U>()); +pub unsafe trait Waitable { + type Atomic; +} +macro_rules! unsafe_waitable_int { + ($(($int:ty, $atomic:ty)),*$(,)?) => { + $( + unsafe impl Waitable for $int { + type Atomic = $atomic; + } + )* + }; +} +unsafe_waitable_int! { + (bool, AtomicBool), + (i8, AtomicI8), + (i16, AtomicI16), + (i32, AtomicI32), + (i64, AtomicI64), + (isize, AtomicIsize), + (u8, AtomicU8), + (u16, AtomicU16), + (u32, AtomicU32), + (u64, AtomicU64), + (usize, AtomicUsize), +} +unsafe impl<T> Waitable for *const T { + type Atomic = AtomicPtr<T>; +} +unsafe impl<T> Waitable for *mut T { + type Atomic = AtomicPtr<T>; +} + +pub fn wait_on_address<W: Waitable>( + address: &W::Atomic, + compare: W, + timeout: Option<Duration>, +) -> bool { unsafe { let addr = ptr::from_ref(address).cast::<c_void>(); - let size = mem::size_of::<T>(); + let size = mem::size_of::<W>(); let compare_addr = ptr::addr_of!(compare).cast::<c_void>(); let timeout = timeout.map(dur2timeout).unwrap_or(c::INFINITE); c::WaitOnAddress(addr, compare_addr, size, timeout) == c::TRUE } } -#[inline(always)] pub fn wake_by_address_single<T>(address: &T) { unsafe { let addr = ptr::from_ref(address).cast::<c_void>(); @@ -26,7 +63,6 @@ pub fn wake_by_address_single<T>(address: &T) { } } -#[inline(always)] pub fn wake_by_address_all<T>(address: &T) { unsafe { let addr = ptr::from_ref(address).cast::<c_void>(); @@ -34,19 +70,16 @@ pub fn wake_by_address_all<T>(address: &T) { } } -#[inline(always)] -pub fn futex_wait<T, U>(futex: &T, expected: U, timeout: Option<Duration>) -> bool { +pub fn futex_wait<W: Waitable>(futex: &W::Atomic, expected: W, timeout: Option<Duration>) -> bool { // return false only on timeout wait_on_address(futex, expected, timeout) || api::get_last_error().code != c::ERROR_TIMEOUT } -#[inline(always)] pub fn futex_wake<T>(futex: &T) -> bool { wake_by_address_single(futex); false } -#[inline(always)] pub fn futex_wake_all<T>(futex: &T) { wake_by_address_all(futex) } |
