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