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
use {crate::SHARED_INFO, core::arch::x86_64::_rdtsc};
pub fn get_system_time() -> u64 {
let shared_info = &unsafe { *SHARED_INFO };
let mut wc_version;
let mut version;
let mut seconds;
let mut nanoseconds;
let mut system_time;
let mut old_tsc;
let mut shift;
let mut mul;
loop {
loop {
wc_version = shared_info.wc_version;
version = shared_info.vcpu_info[0].time.version;
if !(version & 1 == 1 || wc_version & 1 == 1) {
break;
}
}
seconds = shared_info.wc_sec;
nanoseconds = shared_info.wc_nsec;
system_time = shared_info.vcpu_info[0].time.system_time;
old_tsc = shared_info.vcpu_info[0].time.tsc_timestamp;
shift = shared_info.vcpu_info[0].time.tsc_shift;
mul = shared_info.vcpu_info[0].time.tsc_to_system_mul;
if !(version != shared_info.vcpu_info[0].time.version
|| wc_version != shared_info.wc_version)
{
break;
}
}
let tsc_nanos = {
let mut delta = unsafe { _rdtsc() } - old_tsc;
if shift < 0 {
delta >>= -shift;
} else {
delta <<= shift;
}
(delta * u64::from(mul)) >> 32
};
system_time
+ tsc_nanos
+ (u64::from(seconds) * 1_000_000_000)
+ u64::from(nanoseconds)
}