about summary refs log tree commit diff
path: root/library/std/src/sys/pal/unix/thread_parking.rs
diff options
context:
space:
mode:
authorjoboet <jonasboettiger@icloud.com>2024-04-23 11:49:37 +0200
committerjoboet <jonasboettiger@icloud.com>2024-05-02 12:38:26 +0200
commita56fd370fc3e6b5cfbd9eb0b96f533d0bcca0b1f (patch)
treea1fc69d5c82808c6018e0500d1f77bafdf002b85 /library/std/src/sys/pal/unix/thread_parking.rs
parentfcc06c894b17f4d0c80b8934ea5f27faa894c960 (diff)
downloadrust-a56fd370fc3e6b5cfbd9eb0b96f533d0bcca0b1f.tar.gz
rust-a56fd370fc3e6b5cfbd9eb0b96f533d0bcca0b1f.zip
std: move thread parking to `sys::sync`
Diffstat (limited to 'library/std/src/sys/pal/unix/thread_parking.rs')
-rw-r--r--library/std/src/sys/pal/unix/thread_parking.rs63
1 files changed, 63 insertions, 0 deletions
diff --git a/library/std/src/sys/pal/unix/thread_parking.rs b/library/std/src/sys/pal/unix/thread_parking.rs
new file mode 100644
index 00000000000..66ffc006057
--- /dev/null
+++ b/library/std/src/sys/pal/unix/thread_parking.rs
@@ -0,0 +1,63 @@
+// Only used on NetBSD. If other platforms start using id-based parking, use
+// separate modules for each platform.
+#![cfg(target_os = "netbsd")]
+
+use crate::ffi::{c_int, c_void};
+use crate::ptr;
+use crate::time::Duration;
+use libc::{_lwp_self, clockid_t, lwpid_t, time_t, timespec, CLOCK_MONOTONIC};
+
+extern "C" {
+    fn ___lwp_park60(
+        clock_id: clockid_t,
+        flags: c_int,
+        ts: *mut timespec,
+        unpark: lwpid_t,
+        hint: *const c_void,
+        unparkhint: *const c_void,
+    ) -> c_int;
+    fn _lwp_unpark(lwp: lwpid_t, hint: *const c_void) -> c_int;
+}
+
+pub type ThreadId = lwpid_t;
+
+#[inline]
+pub fn current() -> ThreadId {
+    unsafe { _lwp_self() }
+}
+
+#[inline]
+pub fn park(hint: usize) {
+    unsafe {
+        ___lwp_park60(0, 0, ptr::null_mut(), 0, ptr::without_provenance(hint), ptr::null());
+    }
+}
+
+pub fn park_timeout(dur: Duration, hint: usize) {
+    let mut timeout = timespec {
+        // Saturate so that the operation will definitely time out
+        // (even if it is after the heat death of the universe).
+        tv_sec: dur.as_secs().try_into().ok().unwrap_or(time_t::MAX),
+        tv_nsec: dur.subsec_nanos().into(),
+    };
+
+    // Timeout needs to be mutable since it is modified on NetBSD 9.0 and
+    // above.
+    unsafe {
+        ___lwp_park60(
+            CLOCK_MONOTONIC,
+            0,
+            &mut timeout,
+            0,
+            ptr::without_provenance(hint),
+            ptr::null(),
+        );
+    }
+}
+
+#[inline]
+pub fn unpark(tid: ThreadId, hint: usize) {
+    unsafe {
+        _lwp_unpark(tid, ptr::without_provenance(hint));
+    }
+}