diff options
| author | Mara Bos <m-ou.se@m-ou.se> | 2022-04-28 10:32:11 +0200 | 
|---|---|---|
| committer | Mara Bos <m-ou.se@m-ou.se> | 2022-04-29 16:30:54 +0200 | 
| commit | afe1a256ce6612c8c98b5f8a15f797dced1cf696 (patch) | |
| tree | 358b01537f80d04e3be16067348df5da42bf91e2 /library/std/src/sys/unix/futex.rs | |
| parent | 87937d3b6c302dfedfa5c4b94d0a30985d46298d (diff) | |
| download | rust-afe1a256ce6612c8c98b5f8a15f797dced1cf696.tar.gz rust-afe1a256ce6612c8c98b5f8a15f797dced1cf696.zip | |
Use futex-based locks and thread parker on OpenBSD.
Diffstat (limited to 'library/std/src/sys/unix/futex.rs')
| -rw-r--r-- | library/std/src/sys/unix/futex.rs | 52 | 
1 files changed, 51 insertions, 1 deletions
| diff --git a/library/std/src/sys/unix/futex.rs b/library/std/src/sys/unix/futex.rs index c12ee169e79..f86dd560d63 100644 --- a/library/std/src/sys/unix/futex.rs +++ b/library/std/src/sys/unix/futex.rs @@ -1,7 +1,8 @@ #![cfg(any( target_os = "linux", target_os = "android", - all(target_os = "emscripten", target_feature = "atomics") + all(target_os = "emscripten", target_feature = "atomics"), + target_os = "openbsd", ))] use crate::sync::atomic::AtomicU32; @@ -81,6 +82,55 @@ pub fn futex_wake_all(futex: &AtomicU32) { } } +#[cfg(target_os = "openbsd")] +pub fn futex_wait(futex: &AtomicU32, expected: u32, timeout: Option<Duration>) -> bool { + use crate::convert::TryInto; + use crate::ptr::{null, null_mut}; + let timespec = timeout.and_then(|d| { + Some(libc::timespec { + // Sleep forever if the timeout is longer than fits in a timespec. + tv_sec: d.as_secs().try_into().ok()?, + // This conversion never truncates, as subsec_nanos is always <1e9. + tv_nsec: d.subsec_nanos() as _, + }) + }); + + let r = unsafe { + libc::futex( + futex as *const AtomicU32 as *mut u32, + libc::FUTEX_WAIT, + expected as i32, + timespec.as_ref().map_or(null(), |t| t as *const libc::timespec), + null_mut(), + ) + }; + + r == 0 || super::os::errno() != libc::ETIMEDOUT +} + +#[cfg(target_os = "openbsd")] +pub fn futex_wake(futex: &AtomicU32) -> bool { + use crate::ptr::{null, null_mut}; + unsafe { + libc::futex(futex as *const AtomicU32 as *mut u32, libc::FUTEX_WAKE, 1, null(), null_mut()) + > 0 + } +} + +#[cfg(target_os = "openbsd")] +pub fn futex_wake_all(futex: &AtomicU32) { + use crate::ptr::{null, null_mut}; + unsafe { + libc::futex( + futex as *const AtomicU32 as *mut u32, + libc::FUTEX_WAKE, + i32::MAX, + null(), + null_mut(), + ); + } +} + #[cfg(target_os = "emscripten")] extern "C" { fn emscripten_futex_wake(addr: *const AtomicU32, count: libc::c_int) -> libc::c_int; | 
