aboutsummaryrefslogtreecommitdiff
path: root/v_windows/v/vlib/time/time_darwin.c.v
blob: d16c66b275a3d64052e62ec7dbc6acdeca436d09 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
module time

#include <mach/mach_time.h>

const (
	// start_time is needed on Darwin and Windows because of potential overflows
	start_time = C.mach_absolute_time()
	time_base  = init_time_base()
)

[typedef]
struct C.mach_timebase_info_data_t {
	numer u32
	denom u32
}

fn C.mach_absolute_time() u64

fn C.mach_timebase_info(&C.mach_timebase_info_data_t)

fn C.clock_gettime_nsec_np(int) u64

struct InternalTimeBase {
	numer u32 = 1
	denom u32 = 1
}

pub struct C.timeval {
	tv_sec  u64
	tv_usec u64
}

fn init_time_base() C.mach_timebase_info_data_t {
	tb := C.mach_timebase_info_data_t{}
	C.mach_timebase_info(&tb)
	return C.mach_timebase_info_data_t{
		numer: tb.numer
		denom: tb.denom
	}
}

fn sys_mono_now_darwin() u64 {
	tm := C.mach_absolute_time()
	if time.time_base.denom == 0 {
		C.mach_timebase_info(&time.time_base)
	}
	return (tm - time.start_time) * time.time_base.numer / time.time_base.denom
}

// NB: vpc_now_darwin is used by `v -profile` .
// It should NOT call *any other v function*, just C functions and casts.
[inline]
fn vpc_now_darwin() u64 {
	tm := C.mach_absolute_time()
	if time.time_base.denom == 0 {
		C.mach_timebase_info(&time.time_base)
	}
	return (tm - time.start_time) * time.time_base.numer / time.time_base.denom
}

// darwin_now returns a better precision current time for Darwin based operating system
// this should be implemented with native system calls eventually
// but for now a bit tweaky. It uses the deprecated  gettimeofday clock to get
// the microseconds seconds part and converts to local time
fn darwin_now() Time {
	// get the high precision time as UTC clock
	tv := C.timeval{}
	C.gettimeofday(&tv, 0)
	loc_tm := C.tm{}
	asec := voidptr(&tv.tv_sec)
	C.localtime_r(asec, &loc_tm)
	return convert_ctime(loc_tm, int(tv.tv_usec))
}

// darwin_utc returns a better precision current time for Darwin based operating system
// this should be implemented with native system calls eventually
// but for now a bit tweaky. It uses the deprecated  gettimeofday clock to get
// the microseconds seconds part and normal local time to get correct local time
fn darwin_utc() Time {
	// get the high precision time as UTC clock
	tv := C.timeval{}
	C.gettimeofday(&tv, 0)
	return unix2(i64(tv.tv_sec), int(tv.tv_usec))
}