micromegas_tracing/
time.rs1use chrono::{DateTime, Utc};
3
4#[derive(Debug)]
5pub struct DualTime {
6 pub ticks: i64,
7 pub time: DateTime<Utc>,
8}
9
10impl DualTime {
11 pub fn now() -> Self {
12 Self {
13 ticks: now(),
14 time: Utc::now(),
15 }
16 }
17}
18
19#[cfg(windows)]
20pub fn now_windows() -> i64 {
21 unsafe {
22 let mut tick_count = std::mem::zeroed();
23 winapi::um::profileapi::QueryPerformanceCounter(&mut tick_count);
24 *tick_count.QuadPart() as i64
25 }
26}
27
28#[cfg(windows)]
29pub fn freq_windows() -> i64 {
30 unsafe {
31 let mut tick_count = std::mem::zeroed();
32 winapi::um::profileapi::QueryPerformanceFrequency(&mut tick_count);
33 *tick_count.QuadPart() as i64
34 }
35}
36
37#[allow(unreachable_code, clippy::cast_possible_wrap)]
38#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
39pub fn now() -> i64 {
40 #[cfg(windows)]
41 return now_windows();
42
43 use core::arch::x86_64::_rdtsc;
47 unsafe { _rdtsc() as i64 }
48}
49
50#[allow(clippy::cast_possible_wrap)]
51#[cfg(target_arch = "aarch64")]
52pub fn now() -> i64 {
53 let tick_counter: i64;
56 unsafe {
57 core::arch::asm!(
58 "mrs x0, cntvct_el0",
59 out("x0") tick_counter
60 );
61 }
62 tick_counter
63}
64
65#[cfg(target_arch = "wasm32")]
66pub fn now() -> i64 {
67 (js_sys::Date::now() * 1000.0) as i64 }
69
70#[allow(unreachable_code)]
71#[cfg(not(target_arch = "wasm32"))]
72pub fn frequency() -> i64 {
73 #[cfg(windows)]
74 return freq_windows();
75
76 #[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
77 {
78 let cpuid = raw_cpuid::CpuId::new();
79 return cpuid
80 .get_tsc_info()
81 .map(|tsc_info| tsc_info.tsc_frequency().unwrap_or(0))
82 .unwrap_or(0) as i64;
83 }
84 #[cfg(target_arch = "aarch64")]
85 {
86 let counter_frequency: i64;
87 unsafe {
88 core::arch::asm!(
89 "mrs x0, cntfrq_el0",
90 out("x0") counter_frequency
91 );
92 }
93 return counter_frequency;
94 }
95 0
96}
97
98#[cfg(target_arch = "wasm32")]
99pub fn frequency() -> i64 {
100 1_000_000 }
102
103#[allow(unused_imports)]
104#[cfg(test)]
105mod tests {
106 use crate::time::frequency;
107
108 #[test]
109 fn test_frequency() {
110 eprintln!("cpu frequency: {}", frequency());
111 }
112}