// 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 #else #include #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