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