summaryrefslogtreecommitdiffstats
path: root/library/std/src/sys/unix/thread_parking
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--library/std/src/sys/unix/thread_parking/darwin.rs (renamed from library/std/src/sys/unix/thread_parker/darwin.rs)2
-rw-r--r--library/std/src/sys/unix/thread_parking/mod.rs32
-rw-r--r--library/std/src/sys/unix/thread_parking/netbsd.rs52
-rw-r--r--library/std/src/sys/unix/thread_parking/pthread.rs (renamed from library/std/src/sys/unix/thread_parker/pthread.rs)12
4 files changed, 91 insertions, 7 deletions
diff --git a/library/std/src/sys/unix/thread_parker/darwin.rs b/library/std/src/sys/unix/thread_parking/darwin.rs
index 2f5356fe2..b709fada3 100644
--- a/library/std/src/sys/unix/thread_parker/darwin.rs
+++ b/library/std/src/sys/unix/thread_parking/darwin.rs
@@ -46,7 +46,7 @@ unsafe impl Sync for Parker {}
unsafe impl Send for Parker {}
impl Parker {
- pub unsafe fn new(parker: *mut Parker) {
+ pub unsafe fn new_in_place(parker: *mut Parker) {
let semaphore = dispatch_semaphore_create(0);
assert!(
!semaphore.is_null(),
diff --git a/library/std/src/sys/unix/thread_parking/mod.rs b/library/std/src/sys/unix/thread_parking/mod.rs
new file mode 100644
index 000000000..185333c07
--- /dev/null
+++ b/library/std/src/sys/unix/thread_parking/mod.rs
@@ -0,0 +1,32 @@
+//! Thread parking on systems without futex support.
+
+#![cfg(not(any(
+ target_os = "linux",
+ target_os = "android",
+ all(target_os = "emscripten", target_feature = "atomics"),
+ target_os = "freebsd",
+ target_os = "openbsd",
+ target_os = "dragonfly",
+ target_os = "fuchsia",
+)))]
+
+cfg_if::cfg_if! {
+ if #[cfg(all(
+ any(
+ target_os = "macos",
+ target_os = "ios",
+ target_os = "watchos",
+ target_os = "tvos",
+ ),
+ not(miri),
+ ))] {
+ mod darwin;
+ pub use darwin::Parker;
+ } else if #[cfg(target_os = "netbsd")] {
+ mod netbsd;
+ pub use netbsd::{current, park, park_timeout, unpark, ThreadId};
+ } else {
+ mod pthread;
+ pub use pthread::Parker;
+ }
+}
diff --git a/library/std/src/sys/unix/thread_parking/netbsd.rs b/library/std/src/sys/unix/thread_parking/netbsd.rs
new file mode 100644
index 000000000..3be081221
--- /dev/null
+++ b/library/std/src/sys/unix/thread_parking/netbsd.rs
@@ -0,0 +1,52 @@
+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::invalid(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::invalid(hint), ptr::null());
+ }
+}
+
+#[inline]
+pub fn unpark(tid: ThreadId, hint: usize) {
+ unsafe {
+ _lwp_unpark(tid, ptr::invalid(hint));
+ }
+}
diff --git a/library/std/src/sys/unix/thread_parker/pthread.rs b/library/std/src/sys/unix/thread_parking/pthread.rs
index 3dfc0026e..082d25e68 100644
--- a/library/std/src/sys/unix/thread_parker/pthread.rs
+++ b/library/std/src/sys/unix/thread_parking/pthread.rs
@@ -6,6 +6,7 @@ use crate::pin::Pin;
use crate::ptr::addr_of_mut;
use crate::sync::atomic::AtomicUsize;
use crate::sync::atomic::Ordering::SeqCst;
+use crate::sys::time::TIMESPEC_MAX;
use crate::time::Duration;
const EMPTY: usize = 0;
@@ -32,9 +33,6 @@ unsafe fn wait(cond: *mut libc::pthread_cond_t, lock: *mut libc::pthread_mutex_t
debug_assert_eq!(r, 0);
}
-const TIMESPEC_MAX: libc::timespec =
- libc::timespec { tv_sec: <libc::time_t>::MAX, tv_nsec: 1_000_000_000 - 1 };
-
unsafe fn wait_timeout(
cond: *mut libc::pthread_cond_t,
lock: *mut libc::pthread_mutex_t,
@@ -46,7 +44,8 @@ unsafe fn wait_timeout(
target_os = "macos",
target_os = "ios",
target_os = "watchos",
- target_os = "espidf"
+ target_os = "espidf",
+ target_os = "horizon",
))]
let (now, dur) = {
use crate::cmp::min;
@@ -72,7 +71,8 @@ unsafe fn wait_timeout(
target_os = "macos",
target_os = "ios",
target_os = "watchos",
- target_os = "espidf"
+ target_os = "espidf",
+ target_os = "horizon",
)))]
let (now, dur) = {
use crate::sys::time::Timespec;
@@ -99,7 +99,7 @@ impl Parker {
///
/// # Safety
/// The constructed parker must never be moved.
- pub unsafe fn new(parker: *mut Parker) {
+ pub unsafe fn new_in_place(parker: *mut Parker) {
// Use the default mutex implementation to allow for simpler initialization.
// This could lead to undefined behaviour when deadlocking. This is avoided
// by not deadlocking. Note in particular the unlocking operation before any