Skip to content

Commit e9492ff

Browse files
committed
adds specialized impl for sleep_until for macos/ios/watchos/tvos
1 parent 193e6e3 commit e9492ff

File tree

2 files changed

+49
-3
lines changed

2 files changed

+49
-3
lines changed

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

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -272,6 +272,10 @@ impl Thread {
272272
target_os = "android",
273273
target_os = "solaris",
274274
target_os = "illumos",
275+
target_os = "macos",
276+
target_os = "ios",
277+
target_os = "tvos",
278+
target_os = "watchos"
275279
)))]
276280
pub fn sleep_until(deadline: Instant) {
277281
let now = Instant::now();
@@ -313,6 +317,31 @@ impl Thread {
313317
}
314318
}
315319

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

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

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

Lines changed: 3 additions & 3 deletions
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 {
@@ -28,8 +28,8 @@ pub struct SystemTime {
2828

2929
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
3030
pub(in crate::sys::unix) struct Timespec {
31-
tv_sec: i64,
32-
tv_nsec: Nanoseconds,
31+
pub(in crate::sys::unix) tv_sec: i64,
32+
pub(in crate::sys::unix) tv_nsec: Nanoseconds,
3333
}
3434

3535
impl SystemTime {

0 commit comments

Comments
 (0)