Skip to content

Commit c9e56ac

Browse files
committed
adds specialized impl for sleep_until for macos/ios/watchos/tvos
1 parent 3a1d38f commit c9e56ac

File tree

2 files changed

+47
-1
lines changed

2 files changed

+47
-1
lines changed

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

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -310,6 +310,10 @@ impl Thread {
310310
target_os = "android",
311311
target_os = "solaris",
312312
target_os = "illumos",
313+
target_os = "macos",
314+
target_os = "ios",
315+
target_os = "tvos",
316+
target_os = "watchos"
313317
)))]
314318
pub fn sleep_until(deadline: Instant) {
315319
let now = Instant::now();
@@ -351,6 +355,31 @@ impl Thread {
351355
}
352356
}
353357

358+
#[cfg(any(target_os = "macos", target_os = "ios", target_os = "tvos", target_os = "watchos"))]
359+
pub fn sleep_until(deadline: crate::time::Instant) {
360+
// does not count during sleep/suspend same as clock monotonic
361+
// does instant use mach_absolute_time?
362+
// https://developer.apple.com/library/archive/technotes/tn2169/_index.html
363+
364+
use super::time::Timespec;
365+
use core::mem::MaybeUninit;
366+
367+
let Timespec { tv_sec, tv_nsec } = deadline.into_inner().into_timespec();
368+
let nanos = (tv_sec as u64).saturating_mul(1_000_000_000).saturating_add(tv_nsec.0 as u64);
369+
370+
let mut info = MaybeUninit::uninit();
371+
unsafe {
372+
let ret = mach_timebase_info(info.as_mut_ptr());
373+
assert_eq!(ret, KERN_SUCCESS);
374+
375+
let info = info.assume_init();
376+
let ticks = nanos * (info.denom as u64) / (info.numer as u64);
377+
378+
mach_wait_until(ticks);
379+
assert_eq!(ret, KERN_SUCCESS);
380+
}
381+
}
382+
354383
pub fn join(self) {
355384
let id = self.into_id();
356385
let ret = unsafe { libc::pthread_join(id, ptr::null_mut()) };
@@ -366,6 +395,23 @@ impl Thread {
366395
}
367396
}
368397

398+
#[cfg(any(target_os = "macos", target_os = "ios", target_os = "tvos", target_os = "watchos"))]
399+
const KERN_SUCCESS: libc::c_int = 0;
400+
401+
#[cfg(any(target_os = "macos", target_os = "ios", target_os = "tvos", target_os = "watchos"))]
402+
#[repr(C)]
403+
struct mach_timebase_info_type {
404+
numer: u32,
405+
denom: u32,
406+
}
407+
408+
#[cfg(any(target_os = "macos", target_os = "ios", target_os = "tvos", target_os = "watchos"))]
409+
extern "C" {
410+
fn mach_wait_until(deadline: u64) -> libc::c_int;
411+
fn mach_timebase_info(info: *mut mach_timebase_info_type) -> libc::c_int;
412+
413+
}
414+
369415
impl Drop for Thread {
370416
fn drop(&mut self) {
371417
let ret = unsafe { libc::pthread_detach(self.id) };

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ pub(in crate::sys) 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)