61# if TIME_SHIELD_PLATFORM_WINDOWS
62 static std::once_flag init_flag;
63 static int64_t s_perf_freq = 0;
64 static int64_t s_anchor_perf = 0;
65 static int64_t s_anchor_realtime_us = 0;
67 std::call_once(init_flag, []() {
68 LARGE_INTEGER freq = {};
69 LARGE_INTEGER counter = {};
70 ::QueryPerformanceFrequency(&freq);
71 ::QueryPerformanceCounter(&counter);
73 s_perf_freq =
static_cast<int64_t
>(freq.QuadPart);
74 s_anchor_perf =
static_cast<int64_t
>(counter.QuadPart);
77 ::GetSystemTimeAsFileTime(&ft);
80 uli.LowPart = ft.dwLowDateTime;
81 uli.HighPart = ft.dwHighDateTime;
84 const int64_t k_epoch_diff_100ns = 116444736000000000LL;
86 const int64_t filetime_100ns =
static_cast<int64_t
>(uli.QuadPart);
88 s_anchor_realtime_us = (filetime_100ns - k_epoch_diff_100ns) / 10;
91 LARGE_INTEGER
now = {};
92 ::QueryPerformanceCounter(&
now);
94 const int64_t now_ticks =
static_cast<int64_t
>(
now.QuadPart);
95 const int64_t delta_ticks = now_ticks - s_anchor_perf;
98 const int64_t q = delta_ticks / s_perf_freq;
99 const int64_t r = delta_ticks % s_perf_freq;
101 const int64_t delta_us =
102 q * 1000000LL + (r * 1000000LL) / s_perf_freq;
104 return s_anchor_realtime_us + delta_us;
106 static std::once_flag init_flag;
107 static int64_t s_anchor_realtime_us = 0;
108 static int64_t s_anchor_mono_ns = 0;
110 std::call_once(init_flag, []() {
111 struct timespec realtime_ts{};
112 struct timespec mono_ts{};
114# if defined(CLOCK_MONOTONIC_RAW)
115 clock_gettime(CLOCK_MONOTONIC_RAW, &mono_ts);
117 clock_gettime(CLOCK_MONOTONIC, &mono_ts);
119 clock_gettime(CLOCK_REALTIME, &realtime_ts);
121 s_anchor_realtime_us =
static_cast<int64_t
>(realtime_ts.tv_sec) * 1000000LL
122 + realtime_ts.tv_nsec / 1000;
123 s_anchor_mono_ns =
static_cast<int64_t
>(mono_ts.tv_sec) * 1000000000LL
127 struct timespec mono_now_ts{};
128# if defined(CLOCK_MONOTONIC_RAW)
129 clock_gettime(CLOCK_MONOTONIC_RAW, &mono_now_ts);
131 clock_gettime(CLOCK_MONOTONIC, &mono_now_ts);
134 const int64_t mono_now_ns =
static_cast<int64_t
>(mono_now_ts.tv_sec) * 1000000000LL
135 + mono_now_ts.tv_nsec;
136 const int64_t delta_ns = mono_now_ns - s_anchor_mono_ns;
137 return s_anchor_realtime_us + delta_ns / 1000;
248# if TIME_SHIELD_PLATFORM_WINDOWS
249 FILETIME create_time{}, exit_time{}, kernel_time{}, user_time{};
250 if (GetProcessTimes(GetCurrentProcess(), &create_time, &exit_time, &kernel_time, &user_time)) {
252 li.LowPart = user_time.dwLowDateTime;
253 li.HighPart = user_time.dwHighDateTime;
254 return static_cast<double>(li.QuadPart) / 10000000.0;
256# elif TIME_SHIELD_PLATFORM_UNIX
258# if defined(_POSIX_TIMERS) && (_POSIX_TIMERS > 0)
259 clockid_t
id = (clockid_t)-1;
260# if defined(_POSIX_CPUTIME) && (_POSIX_CPUTIME > 0)
261 if (clock_getcpuclockid(0, &
id) != 0) {
262# if defined(CLOCK_PROCESS_CPUTIME_ID)
263 id = CLOCK_PROCESS_CPUTIME_ID;
264# elif defined(CLOCK_VIRTUAL)
268# elif defined(CLOCK_PROCESS_CPUTIME_ID)
269 id = CLOCK_PROCESS_CPUTIME_ID;
270# elif defined(CLOCK_VIRTUAL)
273 if (
id != (clockid_t)-1) {
275 if (clock_gettime(
id, &
ts) == 0) {
276 return static_cast<double>(
ts.tv_sec) +
static_cast<double>(
ts.tv_nsec) / 1e9;
281# if defined(RUSAGE_SELF)
282 struct rusage usage{};
283 if (getrusage(RUSAGE_SELF, &usage) == 0) {
284 return static_cast<double>(usage.ru_utime.tv_sec) +
static_cast<double>(usage.ru_utime.tv_usec) / 1e6;
288# if defined(_SC_CLK_TCK)
290 if (times(&t) != (clock_t)-1) {
291 return static_cast<double>(t.tms_utime) /
static_cast<double>(sysconf(_SC_CLK_TCK));
295# if defined(CLOCKS_PER_SEC)
296 clock_t cl = clock();
297 if (cl != (clock_t)-1) {
298 return static_cast<double>(cl) /
static_cast<double>(CLOCKS_PER_SEC);
302# warning "get_cpu_time() may not work correctly: unsupported platform"
304 return std::numeric_limits<double>::quiet_NaN();