use crate::sync::atomic::AtomicU32;
#[cfg(all(target_os = "linux", not(feature = "shuttle")))]
mod platform {
use core::sync::atomic::AtomicU32;
#[inline]
pub fn wait(a: &AtomicU32, expected: u32) {
unsafe {
libc::syscall(
libc::SYS_futex,
a,
libc::FUTEX_WAIT | libc::FUTEX_PRIVATE_FLAG,
expected,
core::ptr::null::<libc::timespec>(),
);
};
}
#[inline]
pub fn wake_one(ptr: *const AtomicU32) {
unsafe {
libc::syscall(
libc::SYS_futex,
ptr,
libc::FUTEX_WAKE | libc::FUTEX_PRIVATE_FLAG,
1i32,
);
};
}
#[inline]
pub fn wake_all(ptr: *const AtomicU32) {
unsafe {
libc::syscall(
libc::SYS_futex,
ptr,
libc::FUTEX_WAKE | libc::FUTEX_PRIVATE_FLAG,
i32::MAX,
);
};
}
}
#[cfg(all(feature = "shuttle", test))]
mod platform {
use shuttle::sync::atomic::AtomicU32;
#[inline]
pub fn wait(_a: &AtomicU32, _expected: u32) {
shuttle::thread::yield_now();
}
#[inline]
pub fn wake_one(_ptr: *const AtomicU32) {
shuttle::thread::yield_now();
}
#[inline]
pub fn wake_all(_ptr: *const AtomicU32) {
shuttle::thread::yield_now();
}
}
#[cfg(all(target_os = "macos", not(feature = "shuttle")))]
mod platform {
#[inline]
pub fn wait(_a: &std::sync::atomic::AtomicU32, _expected: u32) {}
#[inline]
pub fn wake_one(_ptr: *const std::sync::atomic::AtomicU32) {}
#[inline]
pub fn wake_all(_ptr: *const std::sync::atomic::AtomicU32) {}
}
#[cfg(all(target_os = "windows", not(feature = "shuttle")))]
mod platform {
use core::sync::atomic::AtomicU32;
use windows_sys::Win32::System::Threading::{
WaitOnAddress, WakeByAddressAll, WakeByAddressSingle, INFINITE,
};
#[inline]
pub fn wait(a: &AtomicU32, expected: u32) {
let ptr: *const AtomicU32 = a;
let expected_ptr: *const u32 = &expected;
unsafe { WaitOnAddress(ptr.cast(), expected_ptr.cast(), 4, INFINITE) };
}
#[inline]
pub fn wake_one(ptr: *const AtomicU32) {
unsafe { WakeByAddressSingle(ptr.cast()) };
}
#[inline]
pub fn wake_all(ptr: *const AtomicU32) {
unsafe { WakeByAddressAll(ptr.cast()) };
}
}
#[inline]
pub fn wait(atomic: &AtomicU32, value: u32) {
platform::wait(atomic, value)
}
#[inline]
pub fn wake_one(atomic: *const AtomicU32) {
platform::wake_one(atomic);
}
#[inline]
pub fn wake_all(atomic: *const AtomicU32) {
platform::wake_all(atomic);
}