blob: c516a12d65e2eb4611cd5817a589fac447a6134b (
plain) (
blame)
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
|
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#if defined(_WIN32)
#include <windows.h>
#else
#include <time.h>
#endif
#include "common/steady_clock.h"
namespace Common {
#ifdef _WIN32
static s64 WindowsQueryPerformanceFrequency() {
LARGE_INTEGER frequency;
QueryPerformanceFrequency(&frequency);
return frequency.QuadPart;
}
static s64 WindowsQueryPerformanceCounter() {
LARGE_INTEGER counter;
QueryPerformanceCounter(&counter);
return counter.QuadPart;
}
static s64 GetSystemTimeNS() {
static auto pf = (decltype(&GetSystemTimePreciseAsFileTime))(void*)GetProcAddress(GetModuleHandle(TEXT("Kernel32.dll")), "GetSystemTimePreciseAsFileTime"); // Windows 8+
if (pf) {
// GetSystemTimePreciseAsFileTime returns the file time in 100ns units.
constexpr s64 Multiplier = 100;
// Convert Windows epoch to Unix epoch.
constexpr s64 WindowsEpochToUnixEpoch = 0x19DB1DED53E8000LL;
FILETIME filetime;
pf(&filetime);
return Multiplier * ((s64(filetime.dwHighDateTime) << 32) + s64(filetime.dwLowDateTime) - WindowsEpochToUnixEpoch);
} else {
// Only Windows XP and below error out here
LARGE_INTEGER ticks;
QueryPerformanceCounter(&ticks);
return ticks.QuadPart;
}
}
#endif
SteadyClock::time_point SteadyClock::Now() noexcept {
#if defined(_WIN32)
static const auto timer_freq = WindowsQueryPerformanceFrequency();
const auto counter = WindowsQueryPerformanceCounter();
const auto whole = (counter / timer_freq) * period::den;
const auto part = (counter % timer_freq) * period::den / timer_freq;
return time_point{duration{whole + part}};
#elif defined(__APPLE__)
return time_point{duration{clock_gettime_nsec_np(CLOCK_MONOTONIC_RAW)}};
#else
timespec ts;
clock_gettime(CLOCK_MONOTONIC, &ts);
return time_point{std::chrono::seconds{ts.tv_sec} + std::chrono::nanoseconds{ts.tv_nsec}};
#endif
}
RealTimeClock::time_point RealTimeClock::Now() noexcept {
#if defined(_WIN32)
return time_point{duration{GetSystemTimeNS()}};
#elif defined(__APPLE__)
return time_point{duration{clock_gettime_nsec_np(CLOCK_REALTIME)}};
#else
timespec ts;
clock_gettime(CLOCK_REALTIME, &ts);
return time_point{std::chrono::seconds{ts.tv_sec} + std::chrono::nanoseconds{ts.tv_nsec}};
#endif
}
}; // namespace Common
|