v / vlib / time / time_darwin.c.v
86 lines · 71 sloc · 1.99 KB · 5196349d96a9813d04d425dee3443fa3042e617b
Raw
1module time
2
3#include <mach/mach_time.h>
4
5// start_time is needed on Darwin and Windows because of potential overflows
6const start_time = C.mach_absolute_time()
7
8const time_base = init_time_base()
9
10@[typedef]
11pub struct C.mach_timebase_info_data_t {
12 numer u32
13 denom u32
14}
15
16fn C.mach_absolute_time() u64
17
18fn C.mach_timebase_info(&C.mach_timebase_info_data_t)
19
20fn C.clock_gettime_nsec_np(i32) u64
21
22struct InternalTimeBase {
23 numer u32 = 1
24 denom u32 = 1
25}
26
27fn init_time_base() C.mach_timebase_info_data_t {
28 tb := C.mach_timebase_info_data_t{}
29 C.mach_timebase_info(&tb)
30 return C.mach_timebase_info_data_t{
31 numer: tb.numer
32 denom: tb.denom
33 }
34}
35
36fn sys_mono_now_darwin() u64 {
37 tm := C.mach_absolute_time()
38 if time_base.denom == 0 {
39 unsafe {
40 C.mach_timebase_info(&time_base)
41 }
42 }
43 return (tm - start_time) * time_base.numer / time_base.denom
44}
45
46// Note: vpc_now_darwin is used by `v -profile` .
47// It should NOT call *any other v function*, just C functions and casts.
48@[inline]
49fn vpc_now_darwin() u64 {
50 tm := C.mach_absolute_time()
51 if time_base.denom == 0 {
52 unsafe {
53 C.mach_timebase_info(&time_base)
54 }
55 }
56 return (tm - start_time) * time_base.numer / time_base.denom
57}
58
59// darwin_now returns a better precision current time for macos
60fn darwin_now() Time {
61 // Use clock_gettime_nsec_np to avoid field-address lowering on C.timespec.
62 epoch_ns := i64(C.clock_gettime_nsec_np(C.CLOCK_REALTIME))
63 sec := epoch_ns / i64(second)
64 nsec := int(epoch_ns % i64(second))
65 loc_tm := C.tm{}
66 C.localtime_r(voidptr(&sec), &loc_tm)
67 return convert_ctime_with_unix(loc_tm, nsec, sec + i64(loc_tm.tm_gmtoff))
68}
69
70// darwin_utc returns a better precision current time for macos
71fn darwin_utc() Time {
72 epoch_ns := i64(C.clock_gettime_nsec_np(C.CLOCK_REALTIME))
73 sec := epoch_ns / i64(second)
74 nsec := int(epoch_ns % i64(second))
75 return unix_nanosecond(sec, nsec)
76}
77
78// dummy to compile with all compilers
79fn solaris_now() Time {
80 return Time{}
81}
82
83// dummy to compile with all compilers
84fn solaris_utc() Time {
85 return Time{}
86}
87