Skip to content

Commit 4415af5

Browse files
authoredJun 22, 2022
Rollup merge of rust-lang#96768 - m-ou-se:futex-fuchsia, r=tmandry
Use futex based thread parker on Fuchsia.
2 parents ecda292 + ac38258 commit 4415af5

File tree

3 files changed

+52
-0
lines changed

3 files changed

+52
-0
lines changed
 

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

+50
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
target_os = "freebsd",
66
target_os = "openbsd",
77
target_os = "dragonfly",
8+
target_os = "fuchsia",
89
))]
910

1011
use crate::sync::atomic::AtomicU32;
@@ -237,3 +238,52 @@ pub fn futex_wake(futex: &AtomicU32) -> bool {
237238
pub fn futex_wake_all(futex: &AtomicU32) {
238239
unsafe { emscripten_futex_wake(futex, i32::MAX) };
239240
}
241+
242+
#[cfg(target_os = "fuchsia")]
243+
mod zircon {
244+
type zx_time_t = i64;
245+
type zx_futex_t = crate::sync::atomic::AtomicU32;
246+
type zx_handle_t = u32;
247+
type zx_status_t = i32;
248+
249+
pub const ZX_HANDLE_INVALID: zx_handle_t = 0;
250+
pub const ZX_ERR_TIMED_OUT: zx_status_t = -21;
251+
pub const ZX_TIME_INFINITE: zx_time_t = zx_time_t::MAX;
252+
253+
extern "C" {
254+
pub fn zx_futex_wait(
255+
value_ptr: *const zx_futex_t,
256+
current_value: zx_futex_t,
257+
new_futex_owner: zx_handle_t,
258+
deadline: zx_time_t,
259+
) -> zx_status_t;
260+
pub fn zx_futex_wake(value_ptr: *const zx_futex_t, wake_count: u32) -> zx_status_t;
261+
pub fn zx_clock_get_monotonic() -> zx_time_t;
262+
}
263+
}
264+
265+
#[cfg(target_os = "fuchsia")]
266+
pub fn futex_wait(futex: &AtomicU32, expected: u32, timeout: Option<Duration>) -> bool {
267+
use crate::convert::TryFrom;
268+
269+
// Sleep forever if the timeout is longer than fits in a i64.
270+
let deadline = timeout
271+
.and_then(|d| {
272+
i64::try_from(d.as_nanos())
273+
.ok()?
274+
.checked_add(unsafe { zircon::zx_clock_get_monotonic() })
275+
})
276+
.unwrap_or(zircon::ZX_TIME_INFINITE);
277+
278+
unsafe {
279+
zircon::zx_futex_wait(futex, AtomicU32::new(expected), zircon::ZX_HANDLE_INVALID, deadline)
280+
!= zircon::ZX_ERR_TIMED_OUT
281+
}
282+
}
283+
284+
// Fuchsia doesn't tell us how many threads are woken up, so this always returns false.
285+
#[cfg(target_os = "fuchsia")]
286+
pub fn futex_wake(futex: &AtomicU32) -> bool {
287+
unsafe { zircon::zx_futex_wake(futex, 1) };
288+
false
289+
}

‎library/std/src/sys/unix/thread_parker.rs

+1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
target_os = "freebsd",
88
target_os = "openbsd",
99
target_os = "dragonfly",
10+
target_os = "fuchsia",
1011
)))]
1112

1213
use crate::cell::UnsafeCell;

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

+1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ cfg_if::cfg_if! {
66
target_os = "freebsd",
77
target_os = "openbsd",
88
target_os = "dragonfly",
9+
target_os = "fuchsia",
910
))] {
1011
mod futex;
1112
pub use futex::Parker;

0 commit comments

Comments
 (0)
Please sign in to comment.