|
|
@ -0,0 +1,56 @@ |
|
|
|
|
|
// 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; |
|
|
|
|
|
} |
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
SteadyClock::time_point SteadyClock::Now() noexcept { |
|
|
|
|
|
#if defined(_WIN32)
|
|
|
|
|
|
static const auto freq = WindowsQueryPerformanceFrequency(); |
|
|
|
|
|
const auto counter = WindowsQueryPerformanceCounter(); |
|
|
|
|
|
|
|
|
|
|
|
// 10 MHz is a very common QPC frequency on modern PCs.
|
|
|
|
|
|
// Optimizing for this specific frequency can double the performance of
|
|
|
|
|
|
// this function by avoiding the expensive frequency conversion path.
|
|
|
|
|
|
static constexpr s64 TenMHz = 10'000'000; |
|
|
|
|
|
|
|
|
|
|
|
if (freq == TenMHz) [[likely]] { |
|
|
|
|
|
static_assert(period::den % TenMHz == 0); |
|
|
|
|
|
static constexpr s64 Multiplier = period::den / TenMHz; |
|
|
|
|
|
return time_point{duration{counter * Multiplier}}; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
const auto whole = (counter / freq) * period::den; |
|
|
|
|
|
const auto part = (counter % freq) * period::den / 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
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
}; // namespace Common
|