summaryrefslogtreecommitdiffstats
path: root/library/std/src/sys/unix/thread_parker
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--library/std/src/sys/unix/thread_parker/mod.rs32
-rw-r--r--library/std/src/sys/unix/thread_parker/netbsd.rs113
-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/pthread.rs (renamed from library/std/src/sys/unix/thread_parker/pthread.rs)12
4 files changed, 7 insertions, 152 deletions
diff --git a/library/std/src/sys/unix/thread_parker/mod.rs b/library/std/src/sys/unix/thread_parker/mod.rs
deleted file mode 100644
index 35f1e68a8..000000000
--- a/library/std/src/sys/unix/thread_parker/mod.rs
+++ /dev/null
@@ -1,32 +0,0 @@
-//! 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::Parker;
- } else {
- mod pthread;
- pub use pthread::Parker;
- }
-}
diff --git a/library/std/src/sys/unix/thread_parker/netbsd.rs b/library/std/src/sys/unix/thread_parker/netbsd.rs
deleted file mode 100644
index 7657605b5..000000000
--- a/library/std/src/sys/unix/thread_parker/netbsd.rs
+++ /dev/null
@@ -1,113 +0,0 @@
-use crate::ffi::{c_int, c_void};
-use crate::pin::Pin;
-use crate::ptr::{null, null_mut};
-use crate::sync::atomic::{
- AtomicU64,
- Ordering::{Acquire, Relaxed, Release},
-};
-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;
-}
-
-/// The thread is not parked and the token is not available.
-///
-/// Zero cannot be a valid LWP id, since it is used as empty value for the unpark
-/// argument in _lwp_park.
-const EMPTY: u64 = 0;
-/// The token is available. Do not park anymore.
-const NOTIFIED: u64 = u64::MAX;
-
-pub struct Parker {
- /// The parker state. Contains either one of the two state values above or the LWP
- /// id of the parked thread.
- state: AtomicU64,
-}
-
-impl Parker {
- pub unsafe fn new(parker: *mut Parker) {
- parker.write(Parker { state: AtomicU64::new(EMPTY) })
- }
-
- // Does not actually need `unsafe` or `Pin`, but the pthread implementation does.
- pub unsafe fn park(self: Pin<&Self>) {
- // If the token has already been made available, we can skip
- // a bit of work, so check for it here.
- if self.state.load(Acquire) != NOTIFIED {
- let parked = _lwp_self() as u64;
- let hint = self.state.as_mut_ptr().cast();
- if self.state.compare_exchange(EMPTY, parked, Relaxed, Acquire).is_ok() {
- // Loop to guard against spurious wakeups.
- loop {
- ___lwp_park60(0, 0, null_mut(), 0, hint, null());
- if self.state.load(Acquire) == NOTIFIED {
- break;
- }
- }
- }
- }
-
- // At this point, the change to NOTIFIED has always been observed with acquire
- // ordering, so we can just use a relaxed store here (instead of a swap).
- self.state.store(EMPTY, Relaxed);
- }
-
- // Does not actually need `unsafe` or `Pin`, but the pthread implementation does.
- pub unsafe fn park_timeout(self: Pin<&Self>, dur: Duration) {
- if self.state.load(Acquire) != NOTIFIED {
- let parked = _lwp_self() as u64;
- let hint = self.state.as_mut_ptr().cast();
- 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(),
- };
-
- if self.state.compare_exchange(EMPTY, parked, Relaxed, Acquire).is_ok() {
- // Timeout needs to be mutable since it is modified on NetBSD 9.0 and
- // above.
- ___lwp_park60(CLOCK_MONOTONIC, 0, &mut timeout, 0, hint, null());
- // Use a swap to get acquire ordering even if the token was set after
- // the timeout occurred.
- self.state.swap(EMPTY, Acquire);
- return;
- }
- }
-
- self.state.store(EMPTY, Relaxed);
- }
-
- // Does not actually need `Pin`, but the pthread implementation does.
- pub fn unpark(self: Pin<&Self>) {
- let state = self.state.swap(NOTIFIED, Release);
- if !matches!(state, EMPTY | NOTIFIED) {
- let lwp = state as lwpid_t;
- let hint = self.state.as_mut_ptr().cast();
-
- // If the parking thread terminated and did not actually park, this will
- // probably return an error, which is OK. In the worst case, another
- // thread has received the same LWP id. It will then receive a spurious
- // wakeup, but those are allowable per the API contract. The same reasoning
- // applies if a timeout occurred before this call, but the state was not
- // yet reset.
-
- // SAFETY:
- // The syscall has no invariants to hold. Only unsafe because it is an
- // extern function.
- unsafe {
- _lwp_unpark(lwp, hint);
- }
- }
- }
-}
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_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