Skip to content

Commit 0de580b

Browse files
committed
adds specialized impl for sleep_until for macos/ios/watchos/tvos
1 parent 6e992b2 commit 0de580b

File tree

2 files changed

+47
-1
lines changed

2 files changed

+47
-1
lines changed

library/std/src/sys/unix/thread.rs

+46
Original file line numberDiff line numberDiff line change
@@ -271,6 +271,10 @@ impl Thread {
271271
target_os = "android",
272272
target_os = "solaris",
273273
target_os = "illumos",
274+
target_os = "macos",
275+
target_os = "ios",
276+
target_os = "tvos",
277+
target_os = "watchos"
274278
)))]
275279
pub fn sleep_until(deadline: Instant) {
276280
let now = Instant::now();
@@ -312,6 +316,31 @@ impl Thread {
312316
}
313317
}
314318

319+
#[cfg(any(target_os = "macos", target_os = "ios", target_os = "tvos", target_os = "watchos"))]
320+
pub fn sleep_until(deadline: crate::time::Instant) {
321+
// does not count during sleep/suspend same as clock monotonic
322+
// does instant use mach_absolute_time?
323+
// https://developer.apple.com/library/archive/technotes/tn2169/_index.html
324+
325+
use super::time::Timespec;
326+
use core::mem::MaybeUninit;
327+
328+
let Timespec { tv_sec, tv_nsec } = deadline.into_inner().into_timespec();
329+
let nanos = (tv_sec as u64).saturating_mul(1_000_000_000).saturating_add(tv_nsec.0 as u64);
330+
331+
let mut info = MaybeUninit::uninit();
332+
unsafe {
333+
let ret = mach_timebase_info(info.as_mut_ptr());
334+
assert_eq!(ret, KERN_SUCCESS);
335+
336+
let info = info.assume_init();
337+
let ticks = nanos * (info.denom as u64) / (info.numer as u64);
338+
339+
mach_wait_until(ticks);
340+
assert_eq!(ret, KERN_SUCCESS);
341+
}
342+
}
343+
315344
pub fn join(self) {
316345
unsafe {
317346
let ret = libc::pthread_join(self.id, ptr::null_mut());
@@ -331,6 +360,23 @@ impl Thread {
331360
}
332361
}
333362

363+
#[cfg(any(target_os = "macos", target_os = "ios", target_os = "tvos", target_os = "watchos"))]
364+
const KERN_SUCCESS: libc::c_int = 0;
365+
366+
#[cfg(any(target_os = "macos", target_os = "ios", target_os = "tvos", target_os = "watchos"))]
367+
#[repr(C)]
368+
struct mach_timebase_info_type {
369+
numer: u32,
370+
denom: u32,
371+
}
372+
373+
#[cfg(any(target_os = "macos", target_os = "ios", target_os = "tvos", target_os = "watchos"))]
374+
extern "C" {
375+
fn mach_wait_until(deadline: u64) -> libc::c_int;
376+
fn mach_timebase_info(info: *mut mach_timebase_info_type) -> libc::c_int;
377+
378+
}
379+
334380
impl Drop for Thread {
335381
fn drop(&mut self) {
336382
let ret = unsafe { libc::pthread_detach(self.id) };

library/std/src/sys/unix/time.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ pub(super) const TIMESPEC_MAX_CAPPED: libc::timespec = libc::timespec {
1919
#[repr(transparent)]
2020
#[rustc_layout_scalar_valid_range_start(0)]
2121
#[rustc_layout_scalar_valid_range_end(999_999_999)]
22-
struct Nanoseconds(u32);
22+
pub(in crate::sys::unix) struct Nanoseconds(pub(in crate::sys::unix) u32);
2323

2424
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
2525
pub struct SystemTime {

0 commit comments

Comments
 (0)