about summary refs log tree commit diff
path: root/library/std/src/sys
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2022-06-22 08:07:46 +0000
committerbors <bors@rust-lang.org>2022-06-22 08:07:46 +0000
commit89a0783f1c8fef46b1c8de57dc611a1d753bf0d5 (patch)
treeb5bc0da449b017293c90ec93cd34fcf7cd5470b0 /library/std/src/sys
parent3d829a0922d865d7a77fb284424fd8ba6afaea3b (diff)
parentdb64923b800686132139168124891d58b66a2a98 (diff)
downloadrust-89a0783f1c8fef46b1c8de57dc611a1d753bf0d5.tar.gz
rust-89a0783f1c8fef46b1c8de57dc611a1d753bf0d5.zip
Auto merge of #98375 - JohnTitor:rollup-e5c6rgo, r=JohnTitor
Rollup of 10 pull requests

Successful merges:

 - #95446 (update CPU usage script)
 - #96768 (Use futex based thread parker on Fuchsia.)
 - #97454 (Add release notes for 1.62)
 - #97516 (clarify how Rust atomics correspond to C++ atomics)
 - #97818 (Point at return expression for RPIT-related error)
 - #97895 (Simplify `likely!` and `unlikely!` macro)
 - #98005 (Add some tests for impossible bounds)
 - #98226 (Document unstable `--extern` options)
 - #98356 (Add missing period)
 - #98363 (remove use of &Alloc in btree tests)

Failed merges:

r? `@ghost`
`@rustbot` modify labels: rollup
Diffstat (limited to 'library/std/src/sys')
-rw-r--r--library/std/src/sys/unix/futex.rs50
-rw-r--r--library/std/src/sys/unix/thread_parker.rs1
2 files changed, 51 insertions, 0 deletions
diff --git a/library/std/src/sys/unix/futex.rs b/library/std/src/sys/unix/futex.rs
index 8d05cb44b94..ab516a7f76d 100644
--- a/library/std/src/sys/unix/futex.rs
+++ b/library/std/src/sys/unix/futex.rs
@@ -5,6 +5,7 @@
     target_os = "freebsd",
     target_os = "openbsd",
     target_os = "dragonfly",
+    target_os = "fuchsia",
 ))]
 
 use crate::sync::atomic::AtomicU32;
@@ -237,3 +238,52 @@ pub fn futex_wake(futex: &AtomicU32) -> bool {
 pub fn futex_wake_all(futex: &AtomicU32) {
     unsafe { emscripten_futex_wake(futex, i32::MAX) };
 }
+
+#[cfg(target_os = "fuchsia")]
+mod zircon {
+    type zx_time_t = i64;
+    type zx_futex_t = crate::sync::atomic::AtomicU32;
+    type zx_handle_t = u32;
+    type zx_status_t = i32;
+
+    pub const ZX_HANDLE_INVALID: zx_handle_t = 0;
+    pub const ZX_ERR_TIMED_OUT: zx_status_t = -21;
+    pub const ZX_TIME_INFINITE: zx_time_t = zx_time_t::MAX;
+
+    extern "C" {
+        pub fn zx_futex_wait(
+            value_ptr: *const zx_futex_t,
+            current_value: zx_futex_t,
+            new_futex_owner: zx_handle_t,
+            deadline: zx_time_t,
+        ) -> zx_status_t;
+        pub fn zx_futex_wake(value_ptr: *const zx_futex_t, wake_count: u32) -> zx_status_t;
+        pub fn zx_clock_get_monotonic() -> zx_time_t;
+    }
+}
+
+#[cfg(target_os = "fuchsia")]
+pub fn futex_wait(futex: &AtomicU32, expected: u32, timeout: Option<Duration>) -> bool {
+    use crate::convert::TryFrom;
+
+    // Sleep forever if the timeout is longer than fits in a i64.
+    let deadline = timeout
+        .and_then(|d| {
+            i64::try_from(d.as_nanos())
+                .ok()?
+                .checked_add(unsafe { zircon::zx_clock_get_monotonic() })
+        })
+        .unwrap_or(zircon::ZX_TIME_INFINITE);
+
+    unsafe {
+        zircon::zx_futex_wait(futex, AtomicU32::new(expected), zircon::ZX_HANDLE_INVALID, deadline)
+            != zircon::ZX_ERR_TIMED_OUT
+    }
+}
+
+// Fuchsia doesn't tell us how many threads are woken up, so this always returns false.
+#[cfg(target_os = "fuchsia")]
+pub fn futex_wake(futex: &AtomicU32) -> bool {
+    unsafe { zircon::zx_futex_wake(futex, 1) };
+    false
+}
diff --git a/library/std/src/sys/unix/thread_parker.rs b/library/std/src/sys/unix/thread_parker.rs
index 76278ae30f1..9f4d4f7e736 100644
--- a/library/std/src/sys/unix/thread_parker.rs
+++ b/library/std/src/sys/unix/thread_parker.rs
@@ -7,6 +7,7 @@
     target_os = "freebsd",
     target_os = "openbsd",
     target_os = "dragonfly",
+    target_os = "fuchsia",
 )))]
 
 use crate::cell::UnsafeCell;