1module time 2 3#include <mach/mach_time.h> 4 5const ( 6 // start_time is needed on Darwin and Windows because of potential overflows 7 start_time = C.mach_absolute_time() 8 time_base = init_time_base() 9) 10 11[typedef] 12struct C.mach_timebase_info_data_t { 13 numer u32 14 denom u32 15} 16 17fn C.mach_absolute_time() u64 18fn C.mach_timebase_info(&C.mach_timebase_info_data_t) 19fn C.clock_gettime_nsec_np(int) u64 20 21struct InternalTimeBase { 22 numer u32 = 1 23 denom u32 = 1 24} 25 26pub struct C.timeval { 27 tv_sec u64 28 tv_usec u64 29} 30 31fn init_time_base() InternalTimeBase { 32 tb := C.mach_timebase_info_data_t{} 33 C.mach_timebase_info(&tb) 34 return InternalTimeBase{numer:tb.numer, denom:tb.denom} 35} 36 37fn sys_mono_now_darwin() u64 { 38 tm := C.mach_absolute_time() 39 if time_base.denom == 0 { 40 C.mach_timebase_info(&time_base) 41 } 42 return (tm - start_time) * time_base.numer / time_base.denom 43} 44 45// NB: vpc_now_darwin is used by `v -profile` . 46// It should NOT call *any other v function*, just C functions and casts. 47[inline] 48fn vpc_now_darwin() u64 { 49 tm := C.mach_absolute_time() 50 if time_base.denom == 0 { 51 C.mach_timebase_info(&time_base) 52 } 53 return (tm - start_time) * time_base.numer / time_base.denom 54} 55 56// darwin_now returns a better precision current time for Darwin based operating system 57// this should be implemented with native system calls eventually 58// but for now a bit tweaky. It uses the deprecated gettimeofday clock to get 59// the microseconds seconds part and converts to local time 60[inline] 61fn darwin_now() Time { 62 63 // get the high precision time as UTC clock 64 tv := C.timeval{} 65 C.gettimeofday(&tv, 0) 66 67 loc_tm := C.tm{} 68 C.localtime_r(&tv.tv_sec, &loc_tm) 69 70 return convert_ctime(loc_tm, int(tv.tv_usec)) 71} 72 73// darwin_utc returns a better precision current time for Darwin based operating system 74// this should be implemented with native system calls eventually 75// but for now a bit tweaky. It uses the deprecated gettimeofday clock to get 76// the microseconds seconds part and normal local time to get correct local time 77[inline] 78fn darwin_utc() Time { 79 80 // get the high precision time as UTC clock 81 tv := C.timeval{} 82 C.gettimeofday(&tv, 0) 83 84 return unix2(int(tv.tv_sec), int(tv.tv_usec)) 85} 86