From 10fb0c73bc2269b514a65197dff0f6e42f031624 Mon Sep 17 00:00:00 2001 From: dvdsk Date: Sun, 26 Nov 2023 17:39:22 +0100 Subject: [PATCH 01/19] adds specialized impl of sleep_until for unix and wasi --- library/backtrace | 2 +- library/std/src/sys/pal/hermit/thread.rs | 8 +++ library/std/src/sys/pal/itron/thread.rs | 8 +++ library/std/src/sys/pal/sgx/thread.rs | 8 +++ library/std/src/sys/pal/unix/thread.rs | 48 ++++++++++++++ library/std/src/sys/pal/unix/time.rs | 4 ++ library/std/src/sys/pal/wasi/thread.rs | 77 +++++++++++++---------- library/std/src/sys/pal/wasi/time.rs | 4 ++ library/std/src/sys/pal/windows/thread.rs | 8 +++ library/std/src/sys/pal/xous/thread.rs | 8 +++ library/std/src/thread/mod.rs | 6 +- library/std/src/time.rs | 4 ++ library/stdarch | 2 +- 13 files changed, 147 insertions(+), 40 deletions(-) diff --git a/library/backtrace b/library/backtrace index 230570f2dac80..72265bea21089 160000 --- a/library/backtrace +++ b/library/backtrace @@ -1 +1 @@ -Subproject commit 230570f2dac80a601f5c0b30da00cc9480bd35eb +Subproject commit 72265bea210891ae47bbe6d4f17b493ef0606619 diff --git a/library/std/src/sys/pal/hermit/thread.rs b/library/std/src/sys/pal/hermit/thread.rs index 41f2c3e212355..fb0c9bcee3371 100644 --- a/library/std/src/sys/pal/hermit/thread.rs +++ b/library/std/src/sys/pal/hermit/thread.rs @@ -86,6 +86,14 @@ impl Thread { } } + pub fn sleep_until(deadline: Instant) { + let now = Instant::now(); + + if let Some(delay) = deadline.checked_duration_since(now) { + sleep(delay); + } + } + pub fn join(self) { unsafe { let _ = hermit_abi::join(self.tid); diff --git a/library/std/src/sys/pal/itron/thread.rs b/library/std/src/sys/pal/itron/thread.rs index 04095e1a7cf99..5437188e9e046 100644 --- a/library/std/src/sys/pal/itron/thread.rs +++ b/library/std/src/sys/pal/itron/thread.rs @@ -205,6 +205,14 @@ impl Thread { } } + pub fn sleep_until(deadline: Instant) { + let now = Instant::now(); + + if let Some(delay) = deadline.checked_duration_since(now) { + sleep(delay); + } + } + pub fn join(self) { // Safety: `ThreadInner` is alive at this point let inner = unsafe { self.p_inner.as_ref() }; diff --git a/library/std/src/sys/pal/sgx/thread.rs b/library/std/src/sys/pal/sgx/thread.rs index cecd53c352c5a..0e68899b0b33f 100644 --- a/library/std/src/sys/pal/sgx/thread.rs +++ b/library/std/src/sys/pal/sgx/thread.rs @@ -131,6 +131,14 @@ impl Thread { usercalls::wait_timeout(0, dur, || true); } + pub fn sleep_until(deadline: Instant) { + let now = Instant::now(); + + if let Some(delay) = deadline.checked_duration_since(now) { + sleep(delay); + } + } + pub fn join(self) { self.0.wait(); } diff --git a/library/std/src/sys/pal/unix/thread.rs b/library/std/src/sys/pal/unix/thread.rs index 040246618360f..8ff5bb15a282e 100644 --- a/library/std/src/sys/pal/unix/thread.rs +++ b/library/std/src/sys/pal/unix/thread.rs @@ -303,6 +303,54 @@ impl Thread { } } + #[cfg(not(any( + target_os = "freebsd", + target_os = "netbsd", + target_os = "linux", + target_os = "android", + target_os = "solaris", + target_os = "illumos", + )))] + pub fn sleep_until(deadline: Instant) { + let now = Instant::now(); + + if let Some(delay) = deadline.checked_duration_since(now) { + sleep(delay); + } + } + + // Note depends on clock_nanosleep (not supported on macos/ios/watchos/tvos) + #[cfg(any( + target_os = "freebsd", + target_os = "netbsd", + target_os = "linux", + target_os = "android", + target_os = "solaris", + target_os = "illumos", + ))] + pub fn sleep_until(deadline: crate::time::Instant) { + let mut ts = deadline + .into_inner() + .into_timespec() + .to_timespec() + .expect("Timespec is narrower then libc::timespec thus conversion can't fail"); + let ts_ptr = &mut ts as *mut _; + + // If we're awoken with a signal and the return value is -1 + // clock_nanosleep needs to be called again. + unsafe { + while libc::clock_nanosleep(libc::CLOCK_MONOTONIC, libc::TIMER_ABSTIME, ts_ptr, ts_ptr) + == -1 + { + assert_eq!( + os::errno(), + libc::EINTR, + "clock nanosleep should only return an error if interrupted" + ); + } + } + } + pub fn join(self) { let id = self.into_id(); let ret = unsafe { libc::pthread_join(id, ptr::null_mut()) }; diff --git a/library/std/src/sys/pal/unix/time.rs b/library/std/src/sys/pal/unix/time.rs index 535fe6b27d91e..5f26fd8242879 100644 --- a/library/std/src/sys/pal/unix/time.rs +++ b/library/std/src/sys/pal/unix/time.rs @@ -287,6 +287,10 @@ impl Instant { pub fn checked_sub_duration(&self, other: &Duration) -> Option { Some(Instant { t: self.t.checked_sub_duration(other)? }) } + + pub(in crate::sys::unix) fn into_timespec(self) -> Timespec { + self.t + } } impl fmt::Debug for Instant { diff --git a/library/std/src/sys/pal/wasi/thread.rs b/library/std/src/sys/pal/wasi/thread.rs index 4b83870fdea6c..20e5b6ec2a2a5 100644 --- a/library/std/src/sys/pal/wasi/thread.rs +++ b/library/std/src/sys/pal/wasi/thread.rs @@ -3,7 +3,7 @@ use crate::ffi::CStr; use crate::num::NonZero; use crate::sys::unsupported; -use crate::time::Duration; +use crate::time::{Duration, Instant}; use crate::{io, mem}; cfg_if::cfg_if! { @@ -136,41 +136,25 @@ impl Thread { } pub fn sleep(dur: Duration) { - let mut nanos = dur.as_nanos(); + let mut nanos_all = dur.as_nanos(); while nanos > 0 { - const USERDATA: wasi::Userdata = 0x0123_45678; - - let clock = wasi::SubscriptionClock { - id: wasi::CLOCKID_MONOTONIC, - timeout: u64::try_from(nanos).unwrap_or(u64::MAX), - precision: 0, - flags: 0, - }; - nanos -= u128::from(clock.timeout); - - let in_ = wasi::Subscription { - userdata: USERDATA, - u: wasi::SubscriptionU { tag: 0, u: wasi::SubscriptionUU { clock } }, - }; - unsafe { - let mut event: wasi::Event = mem::zeroed(); - let res = wasi::poll_oneoff(&in_, &mut event, 1); - match (res, event) { - ( - Ok(1), - wasi::Event { - userdata: USERDATA, - error: wasi::ERRNO_SUCCESS, - type_: wasi::EVENTTYPE_CLOCK, - .. - }, - ) => {} - _ => panic!("thread::sleep(): unexpected result of poll_oneoff"), - } - } + let nanos_sleepable = u64::try_from(full_nanos).unwrap_or(u64::MAX); + nanos_all -= u128::from(nanos_sleepable); + sleep_with(nanos_sleepable, wasi::CLOCKID_MONOTONIC, 0); } } + pub fn sleep_until(deadline: Instant) { + let nanos = deadline.into_inner().into_inner().as_nanos(); + assert!(nanos <= u64::MAX as u128); + + sleep_with( + nanos as u64, + wasi::CLOCKID_MONOTONIC, + wasi::SUBCLOCKFLAGS_SUBSCRIPTION_CLOCK_ABSTIME, + ); + } + pub fn join(self) { cfg_if::cfg_if! { if #[cfg(target_feature = "atomics")] { @@ -186,6 +170,33 @@ impl Thread { } } -pub fn available_parallelism() -> io::Result> { +fn sleep_with(nanos: u64, clock_id: wasi::Clockid, flags: u16) { + const USERDATA: wasi::Userdata = 0x0123_45678; + + let clock = wasi::SubscriptionClock { id: clock_id, timeout: nanos, precision: 0, flags }; + + let in_ = wasi::Subscription { + userdata: USERDATA, + u: wasi::SubscriptionU { tag: 0, u: wasi::SubscriptionUU { clock } }, + }; + unsafe { + let mut event: wasi::Event = mem::zeroed(); + let res = wasi::poll_oneoff(&in_, &mut event, 1); + match (res, event) { + ( + Ok(1), + wasi::Event { + userdata: USERDATA, + error: wasi::ERRNO_SUCCESS, + type_: wasi::EVENTTYPE_CLOCK, + .. + }, + ) => {} + _ => panic!("thread::sleep(): unexpected result of poll_oneoff"), + } + } +} + +pub fn available_parallelism() -> io::Result { unsupported() } diff --git a/library/std/src/sys/pal/wasi/time.rs b/library/std/src/sys/pal/wasi/time.rs index 0d8d0b59ac14a..70dddfe4c2868 100644 --- a/library/std/src/sys/pal/wasi/time.rs +++ b/library/std/src/sys/pal/wasi/time.rs @@ -36,6 +36,10 @@ impl Instant { pub fn checked_sub_duration(&self, other: &Duration) -> Option { Some(Instant(self.0.checked_sub(*other)?)) } + + pub(crate) fn into_inner(self) -> Duration { + self.0 + } } impl SystemTime { diff --git a/library/std/src/sys/pal/windows/thread.rs b/library/std/src/sys/pal/windows/thread.rs index 2c8ce42f4148b..4b2c00f12ec60 100644 --- a/library/std/src/sys/pal/windows/thread.rs +++ b/library/std/src/sys/pal/windows/thread.rs @@ -105,6 +105,14 @@ impl Thread { } } + pub fn sleep_until(deadline: Instant) { + let now = Instant::now(); + + if let Some(delay) = deadline.checked_duration_since(now) { + sleep(delay); + } + } + pub fn handle(&self) -> &Handle { &self.handle } diff --git a/library/std/src/sys/pal/xous/thread.rs b/library/std/src/sys/pal/xous/thread.rs index 0ebb46dc19faa..edc64f5e4d4a9 100644 --- a/library/std/src/sys/pal/xous/thread.rs +++ b/library/std/src/sys/pal/xous/thread.rs @@ -128,6 +128,14 @@ impl Thread { } } + pub fn sleep_until(deadline: Instant) { + let now = Instant::now(); + + if let Some(delay) = deadline.checked_duration_since(now) { + sleep(delay); + } + } + pub fn join(self) { join_thread(self.tid).unwrap(); } diff --git a/library/std/src/thread/mod.rs b/library/std/src/thread/mod.rs index 227ee9d64f375..6f452e92b2a4b 100644 --- a/library/std/src/thread/mod.rs +++ b/library/std/src/thread/mod.rs @@ -941,11 +941,7 @@ pub fn sleep(dur: Duration) { /// ``` #[unstable(feature = "thread_sleep_until", issue = "113752")] pub fn sleep_until(deadline: Instant) { - let now = Instant::now(); - - if let Some(delay) = deadline.checked_duration_since(now) { - sleep(delay); - } + imp::Thread::sleep_until(deadline) } /// Used to ensure that `park` and `park_timeout` do not unwind, as that can diff --git a/library/std/src/time.rs b/library/std/src/time.rs index 9f4f8a0d0880c..0aed66be19b45 100644 --- a/library/std/src/time.rs +++ b/library/std/src/time.rs @@ -403,6 +403,10 @@ impl Instant { pub fn checked_sub(&self, duration: Duration) -> Option { self.0.checked_sub_duration(&duration).map(Instant) } + + pub(crate) fn into_inner(self) -> time::Instant { + self.0 + } } #[stable(feature = "time2", since = "1.8.0")] diff --git a/library/stdarch b/library/stdarch index c881fe3231b39..df3618d9f3516 160000 --- a/library/stdarch +++ b/library/stdarch @@ -1 +1 @@ -Subproject commit c881fe3231b3947a4766aa15a26a93022fbb8723 +Subproject commit df3618d9f35165f4bc548114e511c49c29e1fd9b From eac212a08086b0652a13a1bcc121fedf497632a2 Mon Sep 17 00:00:00 2001 From: dvdsk Date: Tue, 28 Nov 2023 13:50:49 +0100 Subject: [PATCH 02/19] adds specialized impl for sleep_until for macos/ios/watchos/tvos --- library/std/src/sys/pal/unix/thread.rs | 46 ++++++++++++++++++++++++++ library/std/src/sys/pal/unix/time.rs | 2 +- 2 files changed, 47 insertions(+), 1 deletion(-) diff --git a/library/std/src/sys/pal/unix/thread.rs b/library/std/src/sys/pal/unix/thread.rs index 8ff5bb15a282e..4d6b95df8e822 100644 --- a/library/std/src/sys/pal/unix/thread.rs +++ b/library/std/src/sys/pal/unix/thread.rs @@ -310,6 +310,10 @@ impl Thread { target_os = "android", target_os = "solaris", target_os = "illumos", + target_os = "macos", + target_os = "ios", + target_os = "tvos", + target_os = "watchos" )))] pub fn sleep_until(deadline: Instant) { let now = Instant::now(); @@ -351,6 +355,31 @@ impl Thread { } } + #[cfg(any(target_os = "macos", target_os = "ios", target_os = "tvos", target_os = "watchos"))] + pub fn sleep_until(deadline: crate::time::Instant) { + // does not count during sleep/suspend same as clock monotonic + // does instant use mach_absolute_time? + // https://developer.apple.com/library/archive/technotes/tn2169/_index.html + + use super::time::Timespec; + use core::mem::MaybeUninit; + + let Timespec { tv_sec, tv_nsec } = deadline.into_inner().into_timespec(); + let nanos = (tv_sec as u64).saturating_mul(1_000_000_000).saturating_add(tv_nsec.0 as u64); + + let mut info = MaybeUninit::uninit(); + unsafe { + let ret = mach_timebase_info(info.as_mut_ptr()); + assert_eq!(ret, KERN_SUCCESS); + + let info = info.assume_init(); + let ticks = nanos * (info.denom as u64) / (info.numer as u64); + + mach_wait_until(ticks); + assert_eq!(ret, KERN_SUCCESS); + } + } + pub fn join(self) { let id = self.into_id(); let ret = unsafe { libc::pthread_join(id, ptr::null_mut()) }; @@ -366,6 +395,23 @@ impl Thread { } } +#[cfg(any(target_os = "macos", target_os = "ios", target_os = "tvos", target_os = "watchos"))] +const KERN_SUCCESS: libc::c_int = 0; + +#[cfg(any(target_os = "macos", target_os = "ios", target_os = "tvos", target_os = "watchos"))] +#[repr(C)] +struct mach_timebase_info_type { + numer: u32, + denom: u32, +} + +#[cfg(any(target_os = "macos", target_os = "ios", target_os = "tvos", target_os = "watchos"))] +extern "C" { + fn mach_wait_until(deadline: u64) -> libc::c_int; + fn mach_timebase_info(info: *mut mach_timebase_info_type) -> libc::c_int; + +} + impl Drop for Thread { fn drop(&mut self) { let ret = unsafe { libc::pthread_detach(self.id) }; diff --git a/library/std/src/sys/pal/unix/time.rs b/library/std/src/sys/pal/unix/time.rs index 5f26fd8242879..150496dd45995 100644 --- a/library/std/src/sys/pal/unix/time.rs +++ b/library/std/src/sys/pal/unix/time.rs @@ -19,7 +19,7 @@ pub(in crate::sys) const TIMESPEC_MAX_CAPPED: libc::timespec = libc::timespec { #[repr(transparent)] #[rustc_layout_scalar_valid_range_start(0)] #[rustc_layout_scalar_valid_range_end(999_999_999)] -struct Nanoseconds(u32); +pub(in crate::sys::unix) struct Nanoseconds(pub(in crate::sys::unix) u32); #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] pub struct SystemTime { From 70e0d2160c05b03734c91b5bda8a28a13673ec5c Mon Sep 17 00:00:00 2001 From: dvdsk Date: Wed, 29 Nov 2023 16:15:47 +0100 Subject: [PATCH 03/19] adds specialized impl for sleep_until for windows --- library/std/src/sys/pal/windows/thread.rs | 30 ++++++++++++++++++++--- library/std/src/sys/pal/windows/time.rs | 6 +++++ 2 files changed, 32 insertions(+), 4 deletions(-) diff --git a/library/std/src/sys/pal/windows/thread.rs b/library/std/src/sys/pal/windows/thread.rs index 4b2c00f12ec60..cbc635301fbbd 100644 --- a/library/std/src/sys/pal/windows/thread.rs +++ b/library/std/src/sys/pal/windows/thread.rs @@ -1,3 +1,14 @@ +use crate::io; +use crate::num::NonZeroUsize; +use crate::os::windows::io::AsRawHandle; +use crate::os::windows::io::HandleOrNull; +use crate::ptr; +use crate::sys::c; +use crate::sys::handle::Handle; +use crate::sys::stack_overflow; +use crate::sys_common::FromInner; +use crate::time::{Duration, Instant}; + use core::ffi::c_void; use super::time::WaitableTimer; @@ -106,11 +117,22 @@ impl Thread { } pub fn sleep_until(deadline: Instant) { - let now = Instant::now(); - - if let Some(delay) = deadline.checked_duration_since(now) { - sleep(delay); + fn high_precision_sleep(deadline: Instant) -> Result<(), ()> { + let timer = WaitableTimer::high_resolution()?; + timer.set_deadline(deadline.into_inner())?; + timer.wait() } + // Attempt to use high-precision sleep (Windows 10, version 1803+). + // On error fallback to the standard `Sleep` function. + // Also preserves the zero duration behaviour of `Sleep`. + if high_precision_sleep(deadline).is_ok() { + return; + } + + let now = Instant::now(); + if let Some(dur) = deadline.checked_duration_since(now) { + unsafe { c::Sleep(super::dur2timeout(dur)) } + }; } pub fn handle(&self) -> &Handle { diff --git a/library/std/src/sys/pal/windows/time.rs b/library/std/src/sys/pal/windows/time.rs index d9010e3996109..a8d3ef8258748 100644 --- a/library/std/src/sys/pal/windows/time.rs +++ b/library/std/src/sys/pal/windows/time.rs @@ -248,6 +248,12 @@ impl WaitableTimer { let result = unsafe { c::SetWaitableTimer(self.handle, &time, 0, None, null(), c::FALSE) }; if result != 0 { Ok(()) } else { Err(()) } } + pub fn set_deadline(&self, deadline: Instant) -> Result<(), ()> { + // Convert the Instant to a format similar to FILETIME. + let time = checked_dur2intervals(&deadline.t).ok_or(())?; + let result = unsafe { c::SetWaitableTimer(self.handle, &time, 0, None, null(), c::FALSE) }; + if result != 0 { Ok(()) } else { Err(()) } + } pub fn wait(&self) -> Result<(), ()> { let result = unsafe { c::WaitForSingleObject(self.handle, c::INFINITE) }; if result != c::WAIT_FAILED { Ok(()) } else { Err(()) } From 947899e55032bb6bc1a5d78ceeb8db6c83cff7f3 Mon Sep 17 00:00:00 2001 From: dvdsk Date: Sat, 26 Oct 2024 14:17:36 +0200 Subject: [PATCH 04/19] (lib/sleep_until) adds test & update docs & fix mac support --- library/std/src/sys/pal/unix/thread.rs | 4 ---- library/std/src/sys/pal/unix/time.rs | 8 +++---- library/std/src/thread/mod.rs | 32 +++++++++++++++++++++++--- library/std/tests/thread.rs | 13 +++++++++++ 4 files changed, 46 insertions(+), 11 deletions(-) diff --git a/library/std/src/sys/pal/unix/thread.rs b/library/std/src/sys/pal/unix/thread.rs index 4d6b95df8e822..5055fa475987b 100644 --- a/library/std/src/sys/pal/unix/thread.rs +++ b/library/std/src/sys/pal/unix/thread.rs @@ -357,10 +357,6 @@ impl Thread { #[cfg(any(target_os = "macos", target_os = "ios", target_os = "tvos", target_os = "watchos"))] pub fn sleep_until(deadline: crate::time::Instant) { - // does not count during sleep/suspend same as clock monotonic - // does instant use mach_absolute_time? - // https://developer.apple.com/library/archive/technotes/tn2169/_index.html - use super::time::Timespec; use core::mem::MaybeUninit; diff --git a/library/std/src/sys/pal/unix/time.rs b/library/std/src/sys/pal/unix/time.rs index 150496dd45995..83c6b21975070 100644 --- a/library/std/src/sys/pal/unix/time.rs +++ b/library/std/src/sys/pal/unix/time.rs @@ -19,7 +19,7 @@ pub(in crate::sys) const TIMESPEC_MAX_CAPPED: libc::timespec = libc::timespec { #[repr(transparent)] #[rustc_layout_scalar_valid_range_start(0)] #[rustc_layout_scalar_valid_range_end(999_999_999)] -pub(in crate::sys::unix) struct Nanoseconds(pub(in crate::sys::unix) u32); +pub(crate) struct Nanoseconds(pub(crate) u32); #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] pub struct SystemTime { @@ -28,8 +28,8 @@ pub struct SystemTime { #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] pub(crate) struct Timespec { - tv_sec: i64, - tv_nsec: Nanoseconds, + pub(crate) tv_sec: i64, + pub(crate) tv_nsec: Nanoseconds, } impl SystemTime { @@ -288,7 +288,7 @@ impl Instant { Some(Instant { t: self.t.checked_sub_duration(other)? }) } - pub(in crate::sys::unix) fn into_timespec(self) -> Timespec { + pub(crate) fn into_timespec(self) -> Timespec { self.t } } diff --git a/library/std/src/thread/mod.rs b/library/std/src/thread/mod.rs index 6f452e92b2a4b..ef3617caf2bfa 100644 --- a/library/std/src/thread/mod.rs +++ b/library/std/src/thread/mod.rs @@ -878,8 +878,34 @@ pub fn sleep(dur: Duration) { /// /// # Platform-specific behavior /// -/// This function uses [`sleep`] internally, see its platform-specific behavior. +/// In most cases this function will call an OS specific function. Where that +/// is not supported [`sleep`] is used. Those platforms are referred to as other +/// in the table below. /// +/// # Underlying System calls +/// +/// The following system calls are [currently] being used: +/// +/// +/// | Platform | System call | +/// |-----------|----------------------------------------------------------------------| +/// | Linux | [clock_nanosleep] (Monotonic clock) | +/// | BSD except OpenBSD | [clock_nanosleep] (Monotonic Clock)] | +/// | Android | [clock_nanosleep] (Monotonic Clock)] | +/// | Solaris | [clock_nanosleep] (Monotonic Clock)] | +/// | Illumos | [clock_nanosleep] (Monotonic Clock)] | +/// | Darwin | [mach_wait_until] | +/// | WASI | [subscription_clock] | +/// | Windows | [SetWaitableTimer] | +/// | Other | `sleep_until` uses [`sleep`] and does not issue a syscall itself | +/// +/// [currently]: crate::io#platform-specific-behavior +/// [clock_nanosleep]: https://linux.die.net/man/3/clock_nanosleep +/// [subscription_clock]: https://github.com/WebAssembly/WASI/blob/main/legacy/preview1/docs.md#-subscription_clock-record +/// [mach_wait_until]: https://developer.apple.com/library/archive/technotes/tn2169/_index.html +/// [SetWaitableTimer]: https://learn.microsoft.com/en-us/windows/win32/api/synchapi/nf-synchapi-setwaitabletimer +/// +/// **Disclaimer:** These system calls might change over time. /// /// # Examples /// @@ -904,9 +930,9 @@ pub fn sleep(dur: Duration) { /// } /// ``` /// -/// A slow api we must not call too fast and which takes a few +/// A slow API we must not call too fast and which takes a few /// tries before succeeding. By using `sleep_until` the time the -/// api call takes does not influence when we retry or when we give up +/// API call takes does not influence when we retry or when we give up /// /// ```no_run /// #![feature(thread_sleep_until)] diff --git a/library/std/tests/thread.rs b/library/std/tests/thread.rs index 1bb17d149fa10..ab83e1ef34ba9 100644 --- a/library/std/tests/thread.rs +++ b/library/std/tests/thread.rs @@ -2,6 +2,8 @@ use std::cell::{Cell, RefCell}; use std::sync::{Arc, Mutex}; use std::thread; use std::time::Duration; +#[feature(thread_sleep_until)] +use std::time::Instant; #[test] #[cfg_attr(any(target_os = "emscripten", target_os = "wasi"), ignore)] // no threads @@ -78,3 +80,14 @@ fn available_parallelism() { // check that std::thread::available_parallelism() returns a valid value assert!(thread::available_parallelism().is_ok()); } + +#[test] +fn sleep_until() { + let now = Instant::now(); + let period = Duration::from_millis(100); + let deadline = now + period; + thread::sleep_until(deadline); + + let elapsed = now.elapsed(); + assert!(elapsed >= period); +} From 05f1cad481289a6bcc1a6eede04d08afa4de077e Mon Sep 17 00:00:00 2001 From: dvdsk Date: Fri, 2 Aug 2024 11:22:01 +0200 Subject: [PATCH 05/19] removes the specialization for windows OS It is not working and I can not figure out why. Since I am not familiar with developing on windows I might not be the best person to work on this. The work removed in this commit might be a useful jumping off point for anyone else however. --- library/std/src/sys/pal/unix/thread.rs | 3 ++- library/std/src/sys/pal/windows/thread.rs | 19 ------------------- library/std/src/sys/pal/windows/time.rs | 6 ------ library/std/src/thread/mod.rs | 2 -- 4 files changed, 2 insertions(+), 28 deletions(-) diff --git a/library/std/src/sys/pal/unix/thread.rs b/library/std/src/sys/pal/unix/thread.rs index 5055fa475987b..804e056b98fbb 100644 --- a/library/std/src/sys/pal/unix/thread.rs +++ b/library/std/src/sys/pal/unix/thread.rs @@ -357,9 +357,10 @@ impl Thread { #[cfg(any(target_os = "macos", target_os = "ios", target_os = "tvos", target_os = "watchos"))] pub fn sleep_until(deadline: crate::time::Instant) { - use super::time::Timespec; use core::mem::MaybeUninit; + use super::time::Timespec; + let Timespec { tv_sec, tv_nsec } = deadline.into_inner().into_timespec(); let nanos = (tv_sec as u64).saturating_mul(1_000_000_000).saturating_add(tv_nsec.0 as u64); diff --git a/library/std/src/sys/pal/windows/thread.rs b/library/std/src/sys/pal/windows/thread.rs index cbc635301fbbd..d3113986fc054 100644 --- a/library/std/src/sys/pal/windows/thread.rs +++ b/library/std/src/sys/pal/windows/thread.rs @@ -116,25 +116,6 @@ impl Thread { } } - pub fn sleep_until(deadline: Instant) { - fn high_precision_sleep(deadline: Instant) -> Result<(), ()> { - let timer = WaitableTimer::high_resolution()?; - timer.set_deadline(deadline.into_inner())?; - timer.wait() - } - // Attempt to use high-precision sleep (Windows 10, version 1803+). - // On error fallback to the standard `Sleep` function. - // Also preserves the zero duration behaviour of `Sleep`. - if high_precision_sleep(deadline).is_ok() { - return; - } - - let now = Instant::now(); - if let Some(dur) = deadline.checked_duration_since(now) { - unsafe { c::Sleep(super::dur2timeout(dur)) } - }; - } - pub fn handle(&self) -> &Handle { &self.handle } diff --git a/library/std/src/sys/pal/windows/time.rs b/library/std/src/sys/pal/windows/time.rs index a8d3ef8258748..d9010e3996109 100644 --- a/library/std/src/sys/pal/windows/time.rs +++ b/library/std/src/sys/pal/windows/time.rs @@ -248,12 +248,6 @@ impl WaitableTimer { let result = unsafe { c::SetWaitableTimer(self.handle, &time, 0, None, null(), c::FALSE) }; if result != 0 { Ok(()) } else { Err(()) } } - pub fn set_deadline(&self, deadline: Instant) -> Result<(), ()> { - // Convert the Instant to a format similar to FILETIME. - let time = checked_dur2intervals(&deadline.t).ok_or(())?; - let result = unsafe { c::SetWaitableTimer(self.handle, &time, 0, None, null(), c::FALSE) }; - if result != 0 { Ok(()) } else { Err(()) } - } pub fn wait(&self) -> Result<(), ()> { let result = unsafe { c::WaitForSingleObject(self.handle, c::INFINITE) }; if result != c::WAIT_FAILED { Ok(()) } else { Err(()) } diff --git a/library/std/src/thread/mod.rs b/library/std/src/thread/mod.rs index ef3617caf2bfa..b8ab2e7ced1f4 100644 --- a/library/std/src/thread/mod.rs +++ b/library/std/src/thread/mod.rs @@ -896,14 +896,12 @@ pub fn sleep(dur: Duration) { /// | Illumos | [clock_nanosleep] (Monotonic Clock)] | /// | Darwin | [mach_wait_until] | /// | WASI | [subscription_clock] | -/// | Windows | [SetWaitableTimer] | /// | Other | `sleep_until` uses [`sleep`] and does not issue a syscall itself | /// /// [currently]: crate::io#platform-specific-behavior /// [clock_nanosleep]: https://linux.die.net/man/3/clock_nanosleep /// [subscription_clock]: https://github.com/WebAssembly/WASI/blob/main/legacy/preview1/docs.md#-subscription_clock-record /// [mach_wait_until]: https://developer.apple.com/library/archive/technotes/tn2169/_index.html -/// [SetWaitableTimer]: https://learn.microsoft.com/en-us/windows/win32/api/synchapi/nf-synchapi-setwaitabletimer /// /// **Disclaimer:** These system calls might change over time. /// From f8850e1b5d1a3febcf9aa57d4fec7cd45b7ab0fd Mon Sep 17 00:00:00 2001 From: dvdsk Date: Fri, 2 Aug 2024 12:14:25 +0200 Subject: [PATCH 06/19] add visionos to sleep_until + check mach_wait_until result --- library/std/src/sys/pal/unix/thread.rs | 34 ++++++++++++++++++++++---- 1 file changed, 29 insertions(+), 5 deletions(-) diff --git a/library/std/src/sys/pal/unix/thread.rs b/library/std/src/sys/pal/unix/thread.rs index 804e056b98fbb..5a61f5595ab7d 100644 --- a/library/std/src/sys/pal/unix/thread.rs +++ b/library/std/src/sys/pal/unix/thread.rs @@ -355,7 +355,13 @@ impl Thread { } } - #[cfg(any(target_os = "macos", target_os = "ios", target_os = "tvos", target_os = "watchos"))] + #[cfg(any( + target_os = "macos", + target_os = "ios", + target_os = "tvos", + target_os = "watchos", + target_os = "visionos" + ))] pub fn sleep_until(deadline: crate::time::Instant) { use core::mem::MaybeUninit; @@ -372,7 +378,7 @@ impl Thread { let info = info.assume_init(); let ticks = nanos * (info.denom as u64) / (info.numer as u64); - mach_wait_until(ticks); + let ret = mach_wait_until(ticks); assert_eq!(ret, KERN_SUCCESS); } } @@ -392,17 +398,35 @@ impl Thread { } } -#[cfg(any(target_os = "macos", target_os = "ios", target_os = "tvos", target_os = "watchos"))] +#[cfg(any( + target_os = "macos", + target_os = "ios", + target_os = "tvos", + target_os = "watchos", + target_os = "visionos" +))] const KERN_SUCCESS: libc::c_int = 0; -#[cfg(any(target_os = "macos", target_os = "ios", target_os = "tvos", target_os = "watchos"))] +#[cfg(any( + target_os = "macos", + target_os = "ios", + target_os = "tvos", + target_os = "watchos", + target_os = "visionos" +))] #[repr(C)] struct mach_timebase_info_type { numer: u32, denom: u32, } -#[cfg(any(target_os = "macos", target_os = "ios", target_os = "tvos", target_os = "watchos"))] +#[cfg(any( + target_os = "macos", + target_os = "ios", + target_os = "tvos", + target_os = "watchos", + target_os = "visionos" +))] extern "C" { fn mach_wait_until(deadline: u64) -> libc::c_int; fn mach_timebase_info(info: *mut mach_timebase_info_type) -> libc::c_int; From 1f32d20dbbeff5d54cbef2e575c03ee3f8b2baf1 Mon Sep 17 00:00:00 2001 From: dvdsk Date: Fri, 2 Aug 2024 12:30:05 +0200 Subject: [PATCH 07/19] fix missing non specialized windows sleep fn --- library/std/src/sys/pal/windows/thread.rs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/library/std/src/sys/pal/windows/thread.rs b/library/std/src/sys/pal/windows/thread.rs index d3113986fc054..48b048bea8905 100644 --- a/library/std/src/sys/pal/windows/thread.rs +++ b/library/std/src/sys/pal/windows/thread.rs @@ -116,6 +116,14 @@ impl Thread { } } + pub fn sleep_until(deadline: Instant) { + let now = Instant::now(); + + if let Some(delay) = deadline.checked_duration_since(now) { + sleep(delay); + } + } + pub fn handle(&self) -> &Handle { &self.handle } From d1ae96a433e228dbd25eac44d84f41c091d35450 Mon Sep 17 00:00:00 2001 From: David Kleingeld Date: Fri, 2 Aug 2024 12:31:29 +0200 Subject: [PATCH 08/19] (lib/sleep_until) use target_vendor apple + fix windows removeal + add more unix platforms MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit target_vendor's done by: Co-authored-by: Jonas Böttiger --- library/std/src/sys/pal/unix/thread.rs | 45 ++++++----------------- library/std/src/sys/pal/windows/thread.rs | 4 +- library/std/src/thread/mod.rs | 3 ++ 3 files changed, 17 insertions(+), 35 deletions(-) diff --git a/library/std/src/sys/pal/unix/thread.rs b/library/std/src/sys/pal/unix/thread.rs index 5a61f5595ab7d..bd58c10e2a312 100644 --- a/library/std/src/sys/pal/unix/thread.rs +++ b/library/std/src/sys/pal/unix/thread.rs @@ -310,10 +310,10 @@ impl Thread { target_os = "android", target_os = "solaris", target_os = "illumos", - target_os = "macos", - target_os = "ios", - target_os = "tvos", - target_os = "watchos" + target_os = "dragonfly", + target_os = "hurd", + target_os = "fuchsia", + target_vendor = "apple" )))] pub fn sleep_until(deadline: Instant) { let now = Instant::now(); @@ -323,7 +323,7 @@ impl Thread { } } - // Note depends on clock_nanosleep (not supported on macos/ios/watchos/tvos) + // Note depends on clock_nanosleep (not supported on os's by apple) #[cfg(any( target_os = "freebsd", target_os = "netbsd", @@ -331,6 +331,9 @@ impl Thread { target_os = "android", target_os = "solaris", target_os = "illumos", + target_os = "dragonfly", + target_os = "hurd", + target_os = "fuchsia", ))] pub fn sleep_until(deadline: crate::time::Instant) { let mut ts = deadline @@ -355,13 +358,7 @@ impl Thread { } } - #[cfg(any( - target_os = "macos", - target_os = "ios", - target_os = "tvos", - target_os = "watchos", - target_os = "visionos" - ))] + #[cfg(target_vendor = "apple")] pub fn sleep_until(deadline: crate::time::Instant) { use core::mem::MaybeUninit; @@ -398,35 +395,17 @@ impl Thread { } } -#[cfg(any( - target_os = "macos", - target_os = "ios", - target_os = "tvos", - target_os = "watchos", - target_os = "visionos" -))] +#[cfg(target_vendor = "apple")] const KERN_SUCCESS: libc::c_int = 0; -#[cfg(any( - target_os = "macos", - target_os = "ios", - target_os = "tvos", - target_os = "watchos", - target_os = "visionos" -))] +#[cfg(target_vendor = "apple")] #[repr(C)] struct mach_timebase_info_type { numer: u32, denom: u32, } -#[cfg(any( - target_os = "macos", - target_os = "ios", - target_os = "tvos", - target_os = "watchos", - target_os = "visionos" -))] +#[cfg(target_vendor = "apple")] extern "C" { fn mach_wait_until(deadline: u64) -> libc::c_int; fn mach_timebase_info(info: *mut mach_timebase_info_type) -> libc::c_int; diff --git a/library/std/src/sys/pal/windows/thread.rs b/library/std/src/sys/pal/windows/thread.rs index 48b048bea8905..4a9db22c9bb7d 100644 --- a/library/std/src/sys/pal/windows/thread.rs +++ b/library/std/src/sys/pal/windows/thread.rs @@ -19,7 +19,7 @@ use crate::os::windows::io::{AsRawHandle, HandleOrNull}; use crate::sys::handle::Handle; use crate::sys::{c, stack_overflow}; use crate::sys_common::FromInner; -use crate::time::Duration; +use crate::time::{Duration, Instant}; use crate::{io, ptr}; pub const DEFAULT_MIN_STACK_SIZE: usize = 2 * 1024 * 1024; @@ -120,7 +120,7 @@ impl Thread { let now = Instant::now(); if let Some(delay) = deadline.checked_duration_since(now) { - sleep(delay); + Self::sleep(delay); } } diff --git a/library/std/src/thread/mod.rs b/library/std/src/thread/mod.rs index b8ab2e7ced1f4..6fe5e525cbb06 100644 --- a/library/std/src/thread/mod.rs +++ b/library/std/src/thread/mod.rs @@ -894,6 +894,9 @@ pub fn sleep(dur: Duration) { /// | Android | [clock_nanosleep] (Monotonic Clock)] | /// | Solaris | [clock_nanosleep] (Monotonic Clock)] | /// | Illumos | [clock_nanosleep] (Monotonic Clock)] | +/// | Dragonfly | [clock_nanosleep] (Monotonic Clock)] | +/// | Hurd | [clock_nanosleep] (Monotonic Clock)] | +/// | Fuchsia | [clock_nanosleep] (Monotonic Clock)] | /// | Darwin | [mach_wait_until] | /// | WASI | [subscription_clock] | /// | Other | `sleep_until` uses [`sleep`] and does not issue a syscall itself | From 5ddda70fd1be395cc014e83975652b3599f1b0b1 Mon Sep 17 00:00:00 2001 From: dvdsk Date: Fri, 2 Aug 2024 15:10:39 +0200 Subject: [PATCH 09/19] (lib/sleep_until) allow unused code for Instant::into_inner --- library/std/src/time.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/library/std/src/time.rs b/library/std/src/time.rs index 0aed66be19b45..6befff240534c 100644 --- a/library/std/src/time.rs +++ b/library/std/src/time.rs @@ -404,6 +404,8 @@ impl Instant { self.0.checked_sub_duration(&duration).map(Instant) } + // used by platform specific sleep_until implementations, no every platform has one + #[allow(unused)] pub(crate) fn into_inner(self) -> time::Instant { self.0 } From e95b65334a93dcf4a9c27eac4b85b0c2f7e45dda Mon Sep 17 00:00:00 2001 From: dvdsk Date: Sat, 3 Aug 2024 13:31:15 +0200 Subject: [PATCH 10/19] (lib/sleep_until) fmt + fix tiny rebase mistake --- library/std/src/sys/pal/wasi/thread.rs | 2 +- library/std/src/sys/pal/windows/thread.rs | 13 +------------ 2 files changed, 2 insertions(+), 13 deletions(-) diff --git a/library/std/src/sys/pal/wasi/thread.rs b/library/std/src/sys/pal/wasi/thread.rs index 20e5b6ec2a2a5..54f5f45310ad1 100644 --- a/library/std/src/sys/pal/wasi/thread.rs +++ b/library/std/src/sys/pal/wasi/thread.rs @@ -197,6 +197,6 @@ fn sleep_with(nanos: u64, clock_id: wasi::Clockid, flags: u16) { } } -pub fn available_parallelism() -> io::Result { +pub fn available_parallelism() -> io::Result> { unsupported() } diff --git a/library/std/src/sys/pal/windows/thread.rs b/library/std/src/sys/pal/windows/thread.rs index 4a9db22c9bb7d..0a3ff28fe17f0 100644 --- a/library/std/src/sys/pal/windows/thread.rs +++ b/library/std/src/sys/pal/windows/thread.rs @@ -1,14 +1,3 @@ -use crate::io; -use crate::num::NonZeroUsize; -use crate::os::windows::io::AsRawHandle; -use crate::os::windows::io::HandleOrNull; -use crate::ptr; -use crate::sys::c; -use crate::sys::handle::Handle; -use crate::sys::stack_overflow; -use crate::sys_common::FromInner; -use crate::time::{Duration, Instant}; - use core::ffi::c_void; use super::time::WaitableTimer; @@ -19,7 +8,7 @@ use crate::os::windows::io::{AsRawHandle, HandleOrNull}; use crate::sys::handle::Handle; use crate::sys::{c, stack_overflow}; use crate::sys_common::FromInner; -use crate::time::{Duration, Instant}; +use crate::time::Duration; use crate::{io, ptr}; pub const DEFAULT_MIN_STACK_SIZE: usize = 2 * 1024 * 1024; From 124a1f5b8dcb73f45221636dd274e6642ccec8e5 Mon Sep 17 00:00:00 2001 From: dvdsk Date: Sat, 3 Aug 2024 14:16:08 +0200 Subject: [PATCH 11/19] (lib/sleep_until) mac, check for aborted and comment on docs --- library/std/src/sys/pal/unix/thread.rs | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/library/std/src/sys/pal/unix/thread.rs b/library/std/src/sys/pal/unix/thread.rs index bd58c10e2a312..0d2d9a8c23156 100644 --- a/library/std/src/sys/pal/unix/thread.rs +++ b/library/std/src/sys/pal/unix/thread.rs @@ -375,7 +375,15 @@ impl Thread { let info = info.assume_init(); let ticks = nanos * (info.denom as u64) / (info.numer as u64); - let ret = mach_wait_until(ticks); + loop { + // There are no docs on the mach_wait_until some details can be + // learned from the `Apple OSS Distributions` xnu source code. + // Specifically: xnu/osfmk/clock.h commit 94d3b45 on Github + let ret = mach_wait_until(ticks); + if ret != KERN_ABORTED { + break; + } + } assert_eq!(ret, KERN_SUCCESS); } } @@ -395,8 +403,12 @@ impl Thread { } } +// these come from the `Apple OSS Distributions` xnu source code. +// Specifically: xnu/osfmk/mach/kern_return.h commit 94d3b45 on Github #[cfg(target_vendor = "apple")] const KERN_SUCCESS: libc::c_int = 0; +#[cfg(target_vendor = "apple")] +const KERN_SUCCESS: libc::c_int = 14; #[cfg(target_vendor = "apple")] #[repr(C)] From 840188df398257cad3527460ae5b4c926d08a597 Mon Sep 17 00:00:00 2001 From: dvdsk Date: Mon, 5 Aug 2024 13:02:42 +0200 Subject: [PATCH 12/19] (lib/sleep_util) fix missing import --- library/std/src/sys/pal/unix/thread.rs | 2 +- library/std/src/sys/pal/windows/thread.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/library/std/src/sys/pal/unix/thread.rs b/library/std/src/sys/pal/unix/thread.rs index 0d2d9a8c23156..cb520ad92e293 100644 --- a/library/std/src/sys/pal/unix/thread.rs +++ b/library/std/src/sys/pal/unix/thread.rs @@ -408,7 +408,7 @@ impl Thread { #[cfg(target_vendor = "apple")] const KERN_SUCCESS: libc::c_int = 0; #[cfg(target_vendor = "apple")] -const KERN_SUCCESS: libc::c_int = 14; +const KERN_ABORTED: libc::c_int = 14; #[cfg(target_vendor = "apple")] #[repr(C)] diff --git a/library/std/src/sys/pal/windows/thread.rs b/library/std/src/sys/pal/windows/thread.rs index 0a3ff28fe17f0..ebf1251f05dc7 100644 --- a/library/std/src/sys/pal/windows/thread.rs +++ b/library/std/src/sys/pal/windows/thread.rs @@ -8,7 +8,7 @@ use crate::os::windows::io::{AsRawHandle, HandleOrNull}; use crate::sys::handle::Handle; use crate::sys::{c, stack_overflow}; use crate::sys_common::FromInner; -use crate::time::Duration; +use crate::time::{Duration, Instant}; use crate::{io, ptr}; pub const DEFAULT_MIN_STACK_SIZE: usize = 2 * 1024 * 1024; From 7f65a9d021e909b5a45ad5ebd09bc72de6e4be6b Mon Sep 17 00:00:00 2001 From: dvdsk Date: Fri, 9 Aug 2024 11:44:03 +0200 Subject: [PATCH 13/19] (lib/sleep_until) add vxworks (os) clock_nanosleep impl --- library/std/src/sys/pal/unix/thread.rs | 2 ++ library/std/src/thread/mod.rs | 1 + 2 files changed, 3 insertions(+) diff --git a/library/std/src/sys/pal/unix/thread.rs b/library/std/src/sys/pal/unix/thread.rs index cb520ad92e293..5bc0c66a228f9 100644 --- a/library/std/src/sys/pal/unix/thread.rs +++ b/library/std/src/sys/pal/unix/thread.rs @@ -313,6 +313,7 @@ impl Thread { target_os = "dragonfly", target_os = "hurd", target_os = "fuchsia", + target_os = "vxworks", target_vendor = "apple" )))] pub fn sleep_until(deadline: Instant) { @@ -334,6 +335,7 @@ impl Thread { target_os = "dragonfly", target_os = "hurd", target_os = "fuchsia", + target_os = "vxworks", ))] pub fn sleep_until(deadline: crate::time::Instant) { let mut ts = deadline diff --git a/library/std/src/thread/mod.rs b/library/std/src/thread/mod.rs index 6fe5e525cbb06..5902b44ae7c72 100644 --- a/library/std/src/thread/mod.rs +++ b/library/std/src/thread/mod.rs @@ -897,6 +897,7 @@ pub fn sleep(dur: Duration) { /// | Dragonfly | [clock_nanosleep] (Monotonic Clock)] | /// | Hurd | [clock_nanosleep] (Monotonic Clock)] | /// | Fuchsia | [clock_nanosleep] (Monotonic Clock)] | +/// | Vxworks | [clock_nanosleep] (Monotonic Clock)] | /// | Darwin | [mach_wait_until] | /// | WASI | [subscription_clock] | /// | Other | `sleep_until` uses [`sleep`] and does not issue a syscall itself | From a779c23730641f171497d58b4c1e2fb7b2accdd8 Mon Sep 17 00:00:00 2001 From: dvdsk Date: Sun, 13 Oct 2024 02:11:38 +0200 Subject: [PATCH 14/19] sleep_until: fixes incorrect assert, improves comments to docs with links Co-authored-by: joboet --- library/std/src/sys/pal/unix/thread.rs | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/library/std/src/sys/pal/unix/thread.rs b/library/std/src/sys/pal/unix/thread.rs index 5bc0c66a228f9..3b2679dd900d6 100644 --- a/library/std/src/sys/pal/unix/thread.rs +++ b/library/std/src/sys/pal/unix/thread.rs @@ -363,7 +363,6 @@ impl Thread { #[cfg(target_vendor = "apple")] pub fn sleep_until(deadline: crate::time::Instant) { use core::mem::MaybeUninit; - use super::time::Timespec; let Timespec { tv_sec, tv_nsec } = deadline.into_inner().into_timespec(); @@ -379,14 +378,14 @@ impl Thread { loop { // There are no docs on the mach_wait_until some details can be - // learned from the `Apple OSS Distributions` xnu source code. - // Specifically: xnu/osfmk/clock.h commit 94d3b45 on Github + // learned from the XNU source code: + // https://github.com/apple-oss-distributions/xnu/blob/94d3b452840153a99b38a3a9659680b2a006908e/osfmk/kern/clock.c#L1507-L1543 let ret = mach_wait_until(ticks); - if ret != KERN_ABORTED { + if ret == KERN_SUCCESS { break; } + assert_eq!(KERN_ABORTED, "mach_wait_until returned error, code: {ret}"); } - assert_eq!(ret, KERN_SUCCESS); } } @@ -405,13 +404,13 @@ impl Thread { } } -// these come from the `Apple OSS Distributions` xnu source code. -// Specifically: xnu/osfmk/mach/kern_return.h commit 94d3b45 on Github +// See https://github.com/apple-oss-distributions/xnu/blob/94d3b452840153a99b38a3a9659680b2a006908e/osfmk/mach/kern_return.h #[cfg(target_vendor = "apple")] const KERN_SUCCESS: libc::c_int = 0; #[cfg(target_vendor = "apple")] const KERN_ABORTED: libc::c_int = 14; +// See https://github.com/apple-oss-distributions/xnu/blob/94d3b452840153a99b38a3a9659680b2a006908e/osfmk/mach/mach_time.h #[cfg(target_vendor = "apple")] #[repr(C)] struct mach_timebase_info_type { From 237923c719f850f9e4c39f0781d16756d081889c Mon Sep 17 00:00:00 2001 From: dvdsk Date: Sun, 13 Oct 2024 02:35:49 +0200 Subject: [PATCH 15/19] fixes test --- library/std/src/sys/pal/unix/thread.rs | 1 + library/std/tests/thread.rs | 5 ++--- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/library/std/src/sys/pal/unix/thread.rs b/library/std/src/sys/pal/unix/thread.rs index 3b2679dd900d6..4948058f9fb8e 100644 --- a/library/std/src/sys/pal/unix/thread.rs +++ b/library/std/src/sys/pal/unix/thread.rs @@ -363,6 +363,7 @@ impl Thread { #[cfg(target_vendor = "apple")] pub fn sleep_until(deadline: crate::time::Instant) { use core::mem::MaybeUninit; + use super::time::Timespec; let Timespec { tv_sec, tv_nsec } = deadline.into_inner().into_timespec(); diff --git a/library/std/tests/thread.rs b/library/std/tests/thread.rs index ab83e1ef34ba9..db9e306e0be63 100644 --- a/library/std/tests/thread.rs +++ b/library/std/tests/thread.rs @@ -1,9 +1,8 @@ +#![feature(thread_sleep_until)] use std::cell::{Cell, RefCell}; use std::sync::{Arc, Mutex}; use std::thread; -use std::time::Duration; -#[feature(thread_sleep_until)] -use std::time::Instant; +use std::time::{Duration, Instant}; #[test] #[cfg_attr(any(target_os = "emscripten", target_os = "wasi"), ignore)] // no threads From 47361f731e75a890771bc504a1988066473d3aef Mon Sep 17 00:00:00 2001 From: dvdsk Date: Sun, 13 Oct 2024 02:47:20 +0200 Subject: [PATCH 16/19] try fix assert_eq --- library/std/src/sys/pal/unix/thread.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/std/src/sys/pal/unix/thread.rs b/library/std/src/sys/pal/unix/thread.rs index 4948058f9fb8e..02b303548c9f2 100644 --- a/library/std/src/sys/pal/unix/thread.rs +++ b/library/std/src/sys/pal/unix/thread.rs @@ -385,7 +385,7 @@ impl Thread { if ret == KERN_SUCCESS { break; } - assert_eq!(KERN_ABORTED, "mach_wait_until returned error, code: {ret}"); + assert_eq!(KERN_ABORTED, "mach_wait_until returned error, code: {}", ret); } } } From 314db2ae50b1df6860057809443b20169edb4ee4 Mon Sep 17 00:00:00 2001 From: dvdsk Date: Sun, 13 Oct 2024 11:08:07 +0200 Subject: [PATCH 17/19] fix assert macro --- library/std/src/sys/pal/unix/thread.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/std/src/sys/pal/unix/thread.rs b/library/std/src/sys/pal/unix/thread.rs index 02b303548c9f2..d987875742d09 100644 --- a/library/std/src/sys/pal/unix/thread.rs +++ b/library/std/src/sys/pal/unix/thread.rs @@ -385,7 +385,7 @@ impl Thread { if ret == KERN_SUCCESS { break; } - assert_eq!(KERN_ABORTED, "mach_wait_until returned error, code: {}", ret); + assert_eq!(KERN_ABORTED, "mach_wait_until returned error"); } } } From 801807e2c5f08a0407e76f08e74e3ff867a4d7b2 Mon Sep 17 00:00:00 2001 From: dvdsk Date: Sun, 13 Oct 2024 11:08:12 +0200 Subject: [PATCH 18/19] fix assert macro --- library/std/src/sys/pal/unix/thread.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/std/src/sys/pal/unix/thread.rs b/library/std/src/sys/pal/unix/thread.rs index d987875742d09..26301ecf4fc82 100644 --- a/library/std/src/sys/pal/unix/thread.rs +++ b/library/std/src/sys/pal/unix/thread.rs @@ -385,7 +385,7 @@ impl Thread { if ret == KERN_SUCCESS { break; } - assert_eq!(KERN_ABORTED, "mach_wait_until returned error"); + assert_eq!(ret, KERN_ABORTED, "mach_wait_until returned error, code: {}", ret); } } } From 0a45de6262cd679992ccf301d45474aa13320aab Mon Sep 17 00:00:00 2001 From: dvdsk Date: Sun, 13 Oct 2024 21:27:12 +0200 Subject: [PATCH 19/19] remove assert msg --- library/std/src/sys/pal/unix/thread.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/std/src/sys/pal/unix/thread.rs b/library/std/src/sys/pal/unix/thread.rs index 26301ecf4fc82..de7845b6e873b 100644 --- a/library/std/src/sys/pal/unix/thread.rs +++ b/library/std/src/sys/pal/unix/thread.rs @@ -385,7 +385,7 @@ impl Thread { if ret == KERN_SUCCESS { break; } - assert_eq!(ret, KERN_ABORTED, "mach_wait_until returned error, code: {}", ret); + assert_eq!(ret, KERN_ABORTED); } } }