summaryrefslogtreecommitdiffstats
path: root/vendor/parking_lot_core-0.8.5/src/thread_parker/unix.rs
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 12:19:43 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 12:19:43 +0000
commit3e3e70d529d8c7d7c4d7bc4fefc9f109393b9245 (patch)
treedaf049b282ab10e8c3d03e409b3cd84ff3f7690c /vendor/parking_lot_core-0.8.5/src/thread_parker/unix.rs
parentAdding debian version 1.68.2+dfsg1-1. (diff)
downloadrustc-3e3e70d529d8c7d7c4d7bc4fefc9f109393b9245.tar.xz
rustc-3e3e70d529d8c7d7c4d7bc4fefc9f109393b9245.zip
Merging upstream version 1.69.0+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'vendor/parking_lot_core-0.8.5/src/thread_parker/unix.rs')
-rw-r--r--vendor/parking_lot_core-0.8.5/src/thread_parker/unix.rs242
1 files changed, 0 insertions, 242 deletions
diff --git a/vendor/parking_lot_core-0.8.5/src/thread_parker/unix.rs b/vendor/parking_lot_core-0.8.5/src/thread_parker/unix.rs
deleted file mode 100644
index c2381e6df..000000000
--- a/vendor/parking_lot_core-0.8.5/src/thread_parker/unix.rs
+++ /dev/null
@@ -1,242 +0,0 @@
-// Copyright 2016 Amanieu d'Antras
-//
-// Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or
-// http://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or
-// http://opensource.org/licenses/MIT>, at your option. This file may not be
-// copied, modified, or distributed except according to those terms.
-
-#[cfg(any(target_os = "macos", target_os = "ios"))]
-use core::ptr;
-use core::{
- cell::{Cell, UnsafeCell},
- mem::MaybeUninit,
-};
-use instant::Instant;
-use libc;
-use std::{thread, time::Duration};
-
-// x32 Linux uses a non-standard type for tv_nsec in timespec.
-// See https://sourceware.org/bugzilla/show_bug.cgi?id=16437
-#[cfg(all(target_arch = "x86_64", target_pointer_width = "32"))]
-#[allow(non_camel_case_types)]
-type tv_nsec_t = i64;
-#[cfg(not(all(target_arch = "x86_64", target_pointer_width = "32")))]
-#[allow(non_camel_case_types)]
-type tv_nsec_t = libc::c_long;
-
-// Helper type for putting a thread to sleep until some other thread wakes it up
-pub struct ThreadParker {
- should_park: Cell<bool>,
- mutex: UnsafeCell<libc::pthread_mutex_t>,
- condvar: UnsafeCell<libc::pthread_cond_t>,
- initialized: Cell<bool>,
-}
-
-impl super::ThreadParkerT for ThreadParker {
- type UnparkHandle = UnparkHandle;
-
- const IS_CHEAP_TO_CONSTRUCT: bool = false;
-
- #[inline]
- fn new() -> ThreadParker {
- ThreadParker {
- should_park: Cell::new(false),
- mutex: UnsafeCell::new(libc::PTHREAD_MUTEX_INITIALIZER),
- condvar: UnsafeCell::new(libc::PTHREAD_COND_INITIALIZER),
- initialized: Cell::new(false),
- }
- }
-
- #[inline]
- unsafe fn prepare_park(&self) {
- self.should_park.set(true);
- if !self.initialized.get() {
- self.init();
- self.initialized.set(true);
- }
- }
-
- #[inline]
- unsafe fn timed_out(&self) -> bool {
- // We need to grab the mutex here because another thread may be
- // concurrently executing UnparkHandle::unpark, which is done without
- // holding the queue lock.
- let r = libc::pthread_mutex_lock(self.mutex.get());
- debug_assert_eq!(r, 0);
- let should_park = self.should_park.get();
- let r = libc::pthread_mutex_unlock(self.mutex.get());
- debug_assert_eq!(r, 0);
- should_park
- }
-
- #[inline]
- unsafe fn park(&self) {
- let r = libc::pthread_mutex_lock(self.mutex.get());
- debug_assert_eq!(r, 0);
- while self.should_park.get() {
- let r = libc::pthread_cond_wait(self.condvar.get(), self.mutex.get());
- debug_assert_eq!(r, 0);
- }
- let r = libc::pthread_mutex_unlock(self.mutex.get());
- debug_assert_eq!(r, 0);
- }
-
- #[inline]
- unsafe fn park_until(&self, timeout: Instant) -> bool {
- let r = libc::pthread_mutex_lock(self.mutex.get());
- debug_assert_eq!(r, 0);
- while self.should_park.get() {
- let now = Instant::now();
- if timeout <= now {
- let r = libc::pthread_mutex_unlock(self.mutex.get());
- debug_assert_eq!(r, 0);
- return false;
- }
-
- if let Some(ts) = timeout_to_timespec(timeout - now) {
- let r = libc::pthread_cond_timedwait(self.condvar.get(), self.mutex.get(), &ts);
- if ts.tv_sec < 0 {
- // On some systems, negative timeouts will return EINVAL. In
- // that case we won't sleep and will just busy loop instead,
- // which is the best we can do.
- debug_assert!(r == 0 || r == libc::ETIMEDOUT || r == libc::EINVAL);
- } else {
- debug_assert!(r == 0 || r == libc::ETIMEDOUT);
- }
- } else {
- // Timeout calculation overflowed, just sleep indefinitely
- let r = libc::pthread_cond_wait(self.condvar.get(), self.mutex.get());
- debug_assert_eq!(r, 0);
- }
- }
- let r = libc::pthread_mutex_unlock(self.mutex.get());
- debug_assert_eq!(r, 0);
- true
- }
-
- #[inline]
- unsafe fn unpark_lock(&self) -> UnparkHandle {
- let r = libc::pthread_mutex_lock(self.mutex.get());
- debug_assert_eq!(r, 0);
-
- UnparkHandle {
- thread_parker: self,
- }
- }
-}
-
-impl ThreadParker {
- /// Initializes the condvar to use CLOCK_MONOTONIC instead of CLOCK_REALTIME.
- #[cfg(any(target_os = "macos", target_os = "ios", target_os = "android"))]
- #[inline]
- unsafe fn init(&self) {}
-
- /// Initializes the condvar to use CLOCK_MONOTONIC instead of CLOCK_REALTIME.
- #[cfg(not(any(target_os = "macos", target_os = "ios", target_os = "android")))]
- #[inline]
- unsafe fn init(&self) {
- let mut attr = MaybeUninit::<libc::pthread_condattr_t>::uninit();
- let r = libc::pthread_condattr_init(attr.as_mut_ptr());
- debug_assert_eq!(r, 0);
- let r = libc::pthread_condattr_setclock(attr.as_mut_ptr(), libc::CLOCK_MONOTONIC);
- debug_assert_eq!(r, 0);
- let r = libc::pthread_cond_init(self.condvar.get(), attr.as_ptr());
- debug_assert_eq!(r, 0);
- let r = libc::pthread_condattr_destroy(attr.as_mut_ptr());
- debug_assert_eq!(r, 0);
- }
-}
-
-impl Drop for ThreadParker {
- #[inline]
- fn drop(&mut self) {
- // On DragonFly pthread_mutex_destroy() returns EINVAL if called on a
- // mutex that was just initialized with libc::PTHREAD_MUTEX_INITIALIZER.
- // Once it is used (locked/unlocked) or pthread_mutex_init() is called,
- // this behaviour no longer occurs. The same applies to condvars.
- unsafe {
- let r = libc::pthread_mutex_destroy(self.mutex.get());
- debug_assert!(r == 0 || r == libc::EINVAL);
- let r = libc::pthread_cond_destroy(self.condvar.get());
- debug_assert!(r == 0 || r == libc::EINVAL);
- }
- }
-}
-
-pub struct UnparkHandle {
- thread_parker: *const ThreadParker,
-}
-
-impl super::UnparkHandleT for UnparkHandle {
- #[inline]
- unsafe fn unpark(self) {
- (*self.thread_parker).should_park.set(false);
-
- // We notify while holding the lock here to avoid races with the target
- // thread. In particular, the thread could exit after we unlock the
- // mutex, which would make the condvar access invalid memory.
- let r = libc::pthread_cond_signal((*self.thread_parker).condvar.get());
- debug_assert_eq!(r, 0);
- let r = libc::pthread_mutex_unlock((*self.thread_parker).mutex.get());
- debug_assert_eq!(r, 0);
- }
-}
-
-// Returns the current time on the clock used by pthread_cond_t as a timespec.
-#[cfg(any(target_os = "macos", target_os = "ios"))]
-#[inline]
-fn timespec_now() -> libc::timespec {
- let mut now = MaybeUninit::<libc::timeval>::uninit();
- let r = unsafe { libc::gettimeofday(now.as_mut_ptr(), ptr::null_mut()) };
- debug_assert_eq!(r, 0);
- // SAFETY: We know `libc::gettimeofday` has initialized the value.
- let now = unsafe { now.assume_init() };
- libc::timespec {
- tv_sec: now.tv_sec,
- tv_nsec: now.tv_usec as tv_nsec_t * 1000,
- }
-}
-#[cfg(not(any(target_os = "macos", target_os = "ios")))]
-#[inline]
-fn timespec_now() -> libc::timespec {
- let mut now = MaybeUninit::<libc::timespec>::uninit();
- let clock = if cfg!(target_os = "android") {
- // Android doesn't support pthread_condattr_setclock, so we need to
- // specify the timeout in CLOCK_REALTIME.
- libc::CLOCK_REALTIME
- } else {
- libc::CLOCK_MONOTONIC
- };
- let r = unsafe { libc::clock_gettime(clock, now.as_mut_ptr()) };
- debug_assert_eq!(r, 0);
- // SAFETY: We know `libc::clock_gettime` has initialized the value.
- unsafe { now.assume_init() }
-}
-
-// Converts a relative timeout into an absolute timeout in the clock used by
-// pthread_cond_t.
-#[inline]
-fn timeout_to_timespec(timeout: Duration) -> Option<libc::timespec> {
- // Handle overflows early on
- if timeout.as_secs() > libc::time_t::max_value() as u64 {
- return None;
- }
-
- let now = timespec_now();
- let mut nsec = now.tv_nsec + timeout.subsec_nanos() as tv_nsec_t;
- let mut sec = now.tv_sec.checked_add(timeout.as_secs() as libc::time_t);
- if nsec >= 1_000_000_000 {
- nsec -= 1_000_000_000;
- sec = sec.and_then(|sec| sec.checked_add(1));
- }
-
- sec.map(|sec| libc::timespec {
- tv_nsec: nsec,
- tv_sec: sec,
- })
-}
-
-#[inline]
-pub fn thread_yield() {
- thread::yield_now();
-}