|
1 | 1 | #![cfg(any(
|
2 | 2 | target_os = "linux",
|
3 | 3 | target_os = "android",
|
4 |
| - all(target_os = "emscripten", target_feature = "atomics") |
| 4 | + all(target_os = "emscripten", target_feature = "atomics"), |
| 5 | + target_os = "openbsd", |
5 | 6 | ))]
|
6 | 7 |
|
7 | 8 | use crate::sync::atomic::AtomicU32;
|
@@ -81,6 +82,55 @@ pub fn futex_wake_all(futex: &AtomicU32) {
|
81 | 82 | }
|
82 | 83 | }
|
83 | 84 |
|
| 85 | +#[cfg(target_os = "openbsd")] |
| 86 | +pub fn futex_wait(futex: &AtomicU32, expected: u32, timeout: Option<Duration>) -> bool { |
| 87 | + use crate::convert::TryInto; |
| 88 | + use crate::ptr::{null, null_mut}; |
| 89 | + let timespec = timeout.and_then(|d| { |
| 90 | + Some(libc::timespec { |
| 91 | + // Sleep forever if the timeout is longer than fits in a timespec. |
| 92 | + tv_sec: d.as_secs().try_into().ok()?, |
| 93 | + // This conversion never truncates, as subsec_nanos is always <1e9. |
| 94 | + tv_nsec: d.subsec_nanos() as _, |
| 95 | + }) |
| 96 | + }); |
| 97 | + |
| 98 | + let r = unsafe { |
| 99 | + libc::futex( |
| 100 | + futex as *const AtomicU32 as *mut u32, |
| 101 | + libc::FUTEX_WAIT, |
| 102 | + expected as i32, |
| 103 | + timespec.as_ref().map_or(null(), |t| t as *const libc::timespec), |
| 104 | + null_mut(), |
| 105 | + ) |
| 106 | + }; |
| 107 | + |
| 108 | + r == 0 || super::os::errno() != libc::ETIMEDOUT |
| 109 | +} |
| 110 | + |
| 111 | +#[cfg(target_os = "openbsd")] |
| 112 | +pub fn futex_wake(futex: &AtomicU32) -> bool { |
| 113 | + use crate::ptr::{null, null_mut}; |
| 114 | + unsafe { |
| 115 | + libc::futex(futex as *const AtomicU32 as *mut u32, libc::FUTEX_WAKE, 1, null(), null_mut()) |
| 116 | + > 0 |
| 117 | + } |
| 118 | +} |
| 119 | + |
| 120 | +#[cfg(target_os = "openbsd")] |
| 121 | +pub fn futex_wake_all(futex: &AtomicU32) { |
| 122 | + use crate::ptr::{null, null_mut}; |
| 123 | + unsafe { |
| 124 | + libc::futex( |
| 125 | + futex as *const AtomicU32 as *mut u32, |
| 126 | + libc::FUTEX_WAKE, |
| 127 | + i32::MAX, |
| 128 | + null(), |
| 129 | + null_mut(), |
| 130 | + ); |
| 131 | + } |
| 132 | +} |
| 133 | + |
84 | 134 | #[cfg(target_os = "emscripten")]
|
85 | 135 | extern "C" {
|
86 | 136 | fn emscripten_futex_wake(addr: *const AtomicU32, count: libc::c_int) -> libc::c_int;
|
|
0 commit comments