39 lines
1,013 B
Rust
39 lines
1,013 B
Rust
use super::abi;
|
|
use crate::ptr::null;
|
|
use crate::sync::atomic::AtomicU32;
|
|
use crate::time::Duration;
|
|
|
|
pub fn futex_wait(futex: &AtomicU32, expected: u32, timeout: Option<Duration>) -> bool {
|
|
// Calculate the timeout as a relative timespec.
|
|
//
|
|
// Overflows are rounded up to an infinite timeout (None).
|
|
let timespec = timeout.and_then(|dur| {
|
|
Some(abi::timespec {
|
|
tv_sec: dur.as_secs().try_into().ok()?,
|
|
tv_nsec: dur.subsec_nanos().into(),
|
|
})
|
|
});
|
|
|
|
let r = unsafe {
|
|
abi::futex_wait(
|
|
futex.as_ptr(),
|
|
expected,
|
|
timespec.as_ref().map_or(null(), |t| t as *const abi::timespec),
|
|
abi::FUTEX_RELATIVE_TIMEOUT,
|
|
)
|
|
};
|
|
|
|
r != -abi::errno::ETIMEDOUT
|
|
}
|
|
|
|
#[inline]
|
|
pub fn futex_wake(futex: &AtomicU32) -> bool {
|
|
unsafe { abi::futex_wake(futex.as_ptr(), 1) > 0 }
|
|
}
|
|
|
|
#[inline]
|
|
pub fn futex_wake_all(futex: &AtomicU32) {
|
|
unsafe {
|
|
abi::futex_wake(futex.as_ptr(), i32::MAX);
|
|
}
|
|
}
|