2020-04-24 08:33:25 +03:00
|
|
|
module time
|
|
|
|
|
|
|
|
#include <mach/mach_time.h>
|
2021-02-01 16:50:41 +03:00
|
|
|
|
2023-08-05 23:41:23 +03:00
|
|
|
// start_time is needed on Darwin and Windows because of potential overflows
|
|
|
|
const start_time = C.mach_absolute_time()
|
|
|
|
|
|
|
|
const time_base = init_time_base()
|
2020-04-24 08:33:25 +03:00
|
|
|
|
|
|
|
[typedef]
|
|
|
|
struct C.mach_timebase_info_data_t {
|
2020-04-26 20:36:38 +03:00
|
|
|
numer u32
|
|
|
|
denom u32
|
2020-04-24 08:33:25 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
fn C.mach_absolute_time() u64
|
2020-12-06 17:19:39 +03:00
|
|
|
|
2020-04-24 08:33:25 +03:00
|
|
|
fn C.mach_timebase_info(&C.mach_timebase_info_data_t)
|
2020-12-06 17:19:39 +03:00
|
|
|
|
2020-04-26 20:36:38 +03:00
|
|
|
fn C.clock_gettime_nsec_np(int) u64
|
2020-04-24 08:33:25 +03:00
|
|
|
|
|
|
|
struct InternalTimeBase {
|
2020-04-26 20:36:38 +03:00
|
|
|
numer u32 = 1
|
|
|
|
denom u32 = 1
|
2020-04-24 08:33:25 +03:00
|
|
|
}
|
|
|
|
|
2020-11-29 22:23:37 +03:00
|
|
|
fn init_time_base() C.mach_timebase_info_data_t {
|
2020-04-26 20:36:38 +03:00
|
|
|
tb := C.mach_timebase_info_data_t{}
|
2020-04-24 08:33:25 +03:00
|
|
|
C.mach_timebase_info(&tb)
|
2020-12-06 17:19:39 +03:00
|
|
|
return C.mach_timebase_info_data_t{
|
|
|
|
numer: tb.numer
|
|
|
|
denom: tb.denom
|
|
|
|
}
|
2020-04-24 08:33:25 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
fn sys_mono_now_darwin() u64 {
|
|
|
|
tm := C.mach_absolute_time()
|
2021-01-25 12:26:20 +03:00
|
|
|
if time.time_base.denom == 0 {
|
2022-07-03 08:41:26 +03:00
|
|
|
unsafe {
|
|
|
|
C.mach_timebase_info(&time.time_base)
|
|
|
|
}
|
2020-04-26 20:36:38 +03:00
|
|
|
}
|
2021-01-25 12:26:20 +03:00
|
|
|
return (tm - time.start_time) * time.time_base.numer / time.time_base.denom
|
2020-04-24 08:33:25 +03:00
|
|
|
}
|
2020-05-05 17:19:25 +03:00
|
|
|
|
2022-03-06 20:01:22 +03:00
|
|
|
// Note: vpc_now_darwin is used by `v -profile` .
|
2020-05-05 17:19:25 +03:00
|
|
|
// It should NOT call *any other v function*, just C functions and casts.
|
|
|
|
[inline]
|
|
|
|
fn vpc_now_darwin() u64 {
|
|
|
|
tm := C.mach_absolute_time()
|
2021-01-25 12:26:20 +03:00
|
|
|
if time.time_base.denom == 0 {
|
2022-07-03 08:41:26 +03:00
|
|
|
unsafe {
|
|
|
|
C.mach_timebase_info(&time.time_base)
|
|
|
|
}
|
2020-05-05 17:19:25 +03:00
|
|
|
}
|
2021-01-25 12:26:20 +03:00
|
|
|
return (tm - time.start_time) * time.time_base.numer / time.time_base.denom
|
2020-05-05 17:19:25 +03:00
|
|
|
}
|
2020-06-07 16:19:09 +03:00
|
|
|
|
2023-08-05 23:41:23 +03:00
|
|
|
// darwin_now returns a better precision current time for macos
|
2020-06-07 16:19:09 +03:00
|
|
|
fn darwin_now() Time {
|
2023-08-05 23:41:23 +03:00
|
|
|
// get the high precision time as UTC realtime clock, and use the nanoseconds part
|
|
|
|
mut ts := C.timespec{}
|
|
|
|
C.clock_gettime(C.CLOCK_REALTIME, &ts)
|
2020-06-10 12:14:55 +03:00
|
|
|
loc_tm := C.tm{}
|
2023-08-05 23:41:23 +03:00
|
|
|
C.localtime_r(voidptr(&ts.tv_sec), &loc_tm)
|
|
|
|
return convert_ctime(loc_tm, int(ts.tv_nsec))
|
2020-06-10 12:14:55 +03:00
|
|
|
}
|
|
|
|
|
2023-08-05 23:41:23 +03:00
|
|
|
// darwin_utc returns a better precision current time for macos
|
2020-06-10 12:14:55 +03:00
|
|
|
fn darwin_utc() Time {
|
|
|
|
// get the high precision time as UTC clock
|
2023-08-05 23:41:23 +03:00
|
|
|
mut ts := C.timespec{}
|
|
|
|
C.clock_gettime(C.CLOCK_REALTIME, &ts)
|
|
|
|
return unix_nanosecond(i64(ts.tv_sec), int(ts.tv_nsec))
|
2020-06-07 16:19:09 +03:00
|
|
|
}
|
2021-09-06 19:50:16 +03:00
|
|
|
|
|
|
|
// dummy to compile with all compilers
|
2023-07-31 11:02:10 +03:00
|
|
|
fn solaris_now() Time {
|
2021-09-06 19:50:16 +03:00
|
|
|
return Time{}
|
|
|
|
}
|
|
|
|
|
|
|
|
// dummy to compile with all compilers
|
2023-07-31 11:02:10 +03:00
|
|
|
fn solaris_utc() Time {
|
2021-09-06 19:50:16 +03:00
|
|
|
return Time{}
|
|
|
|
}
|