Skip to content

Commit afe1a25

Browse files
committed
Use futex-based locks and thread parker on OpenBSD.
1 parent 87937d3 commit afe1a25

File tree

3 files changed

+53
-1
lines changed

3 files changed

+53
-1
lines changed

library/std/src/sys/unix/futex.rs

Lines changed: 51 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
#![cfg(any(
22
target_os = "linux",
33
target_os = "android",
4-
all(target_os = "emscripten", target_feature = "atomics")
4+
all(target_os = "emscripten", target_feature = "atomics"),
5+
target_os = "openbsd",
56
))]
67

78
use crate::sync::atomic::AtomicU32;
@@ -81,6 +82,55 @@ pub fn futex_wake_all(futex: &AtomicU32) {
8182
}
8283
}
8384

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+
84134
#[cfg(target_os = "emscripten")]
85135
extern "C" {
86136
fn emscripten_futex_wake(addr: *const AtomicU32, count: libc::c_int) -> libc::c_int;

library/std/src/sys/unix/locks/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ cfg_if::cfg_if! {
33
target_os = "linux",
44
target_os = "android",
55
all(target_os = "emscripten", target_feature = "atomics"),
6+
target_os = "openbsd",
67
))] {
78
mod futex;
89
mod futex_rwlock;

library/std/src/sys_common/thread_parker/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ cfg_if::cfg_if! {
33
target_os = "linux",
44
target_os = "android",
55
all(target_arch = "wasm32", target_feature = "atomics"),
6+
target_os = "openbsd",
67
))] {
78
mod futex;
89
pub use futex::Parker;

0 commit comments

Comments
 (0)