@@ -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+
369415impl Drop for Thread {
370416 fn drop ( & mut self ) {
371417 let ret = unsafe { libc:: pthread_detach ( self . id ) } ;
0 commit comments