Browse Source
[common] remove ptr indirection on WallClock (#3864)
[common] remove ptr indirection on WallClock (#3864)
also devirtualizes manually since compiler doesn't do it with LTO Signed-off-by: lizzie <lizzie@eden-emu.dev> Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3864 Reviewed-by: crueter <crueter@eden-emu.dev>lizzie/stable-shader-pools
committed by
crueter
No known key found for this signature in database
GPG Key ID: 425ACD2D4830EBC6
14 changed files with 288 additions and 392 deletions
-
6src/common/CMakeLists.txt
-
87src/common/arm64/native_clock.cpp
-
45src/common/arm64/native_clock.h
-
205src/common/wall_clock.cpp
-
45src/common/wall_clock.h
-
46src/common/x64/native_clock.cpp
-
38src/common/x64/native_clock.h
-
9src/core/arm/dynarmic/arm_dynarmic_32.cpp
-
6src/core/arm/dynarmic/arm_dynarmic_64.cpp
-
8src/core/arm/nce/patcher.cpp
-
155src/core/core_timing.cpp
-
18src/core/core_timing.h
-
9src/core/hle/service/nvnflinger/buffer_queue_producer.cpp
-
3src/core/hle/service/nvnflinger/buffer_queue_producer.h
@ -1,87 +0,0 @@ |
|||||
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
|
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
|
||||
|
|
||||
#ifdef ANDROID
|
|
||||
#include <sys/system_properties.h>
|
|
||||
#endif
|
|
||||
#include "common/arm64/native_clock.h"
|
|
||||
|
|
||||
namespace Common::Arm64 { |
|
||||
|
|
||||
namespace { |
|
||||
|
|
||||
NativeClock::FactorType GetFixedPointFactor(u64 num, u64 den) { |
|
||||
return (static_cast<NativeClock::FactorType>(num) << 64) / den; |
|
||||
} |
|
||||
|
|
||||
u64 MultiplyHigh(u64 m, NativeClock::FactorType factor) { |
|
||||
return static_cast<u64>((m * factor) >> 64); |
|
||||
} |
|
||||
|
|
||||
} // namespace
|
|
||||
|
|
||||
NativeClock::NativeClock() { |
|
||||
const u64 host_cntfrq = GetHostCNTFRQ(); |
|
||||
ns_cntfrq_factor = GetFixedPointFactor(NsRatio::den, host_cntfrq); |
|
||||
us_cntfrq_factor = GetFixedPointFactor(UsRatio::den, host_cntfrq); |
|
||||
ms_cntfrq_factor = GetFixedPointFactor(MsRatio::den, host_cntfrq); |
|
||||
guest_cntfrq_factor = GetFixedPointFactor(CNTFRQ, host_cntfrq); |
|
||||
gputick_cntfrq_factor = GetFixedPointFactor(GPUTickFreq, host_cntfrq); |
|
||||
} |
|
||||
|
|
||||
std::chrono::nanoseconds NativeClock::GetTimeNS() const { |
|
||||
return std::chrono::nanoseconds{MultiplyHigh(GetUptime(), ns_cntfrq_factor)}; |
|
||||
} |
|
||||
|
|
||||
std::chrono::microseconds NativeClock::GetTimeUS() const { |
|
||||
return std::chrono::microseconds{MultiplyHigh(GetUptime(), us_cntfrq_factor)}; |
|
||||
} |
|
||||
|
|
||||
std::chrono::milliseconds NativeClock::GetTimeMS() const { |
|
||||
return std::chrono::milliseconds{MultiplyHigh(GetUptime(), ms_cntfrq_factor)}; |
|
||||
} |
|
||||
|
|
||||
s64 NativeClock::GetCNTPCT() const { |
|
||||
return MultiplyHigh(GetUptime(), guest_cntfrq_factor); |
|
||||
} |
|
||||
|
|
||||
s64 NativeClock::GetGPUTick() const { |
|
||||
return MultiplyHigh(GetUptime(), gputick_cntfrq_factor); |
|
||||
} |
|
||||
|
|
||||
s64 NativeClock::GetUptime() const { |
|
||||
s64 cntvct_el0 = 0; |
|
||||
asm volatile("dsb ish\n\t" |
|
||||
"mrs %[cntvct_el0], cntvct_el0\n\t" |
|
||||
"dsb ish\n\t" |
|
||||
: [cntvct_el0] "=r"(cntvct_el0)); |
|
||||
return cntvct_el0; |
|
||||
} |
|
||||
|
|
||||
bool NativeClock::IsNative() const { |
|
||||
return true; |
|
||||
} |
|
||||
|
|
||||
s64 NativeClock::GetHostCNTFRQ() { |
|
||||
u64 cntfrq_el0 = 0; |
|
||||
std::string_view board{""}; |
|
||||
#ifdef ANDROID
|
|
||||
char buffer[PROP_VALUE_MAX]; |
|
||||
int len{__system_property_get("ro.product.board", buffer)}; |
|
||||
board = std::string_view(buffer, static_cast<size_t>(len)); |
|
||||
#endif
|
|
||||
if (board == "s5e9925") { // Exynos 2200
|
|
||||
cntfrq_el0 = 25600000; |
|
||||
} else if (board == "exynos2100") { // Exynos 2100
|
|
||||
cntfrq_el0 = 26000000; |
|
||||
} else if (board == "exynos9810") { // Exynos 9810
|
|
||||
cntfrq_el0 = 26000000; |
|
||||
} else if (board == "s5e8825") { // Exynos 1280
|
|
||||
cntfrq_el0 = 26000000; |
|
||||
} else { |
|
||||
asm("mrs %[cntfrq_el0], cntfrq_el0" : [cntfrq_el0] "=r"(cntfrq_el0)); |
|
||||
} |
|
||||
return cntfrq_el0; |
|
||||
} |
|
||||
|
|
||||
} // namespace Common::Arm64
|
|
||||
@ -1,45 +0,0 @@ |
|||||
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project |
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
|
|
||||
#pragma once |
|
||||
|
|
||||
#include "common/wall_clock.h" |
|
||||
|
|
||||
namespace Common::Arm64 { |
|
||||
|
|
||||
class NativeClock final : public WallClock { |
|
||||
public: |
|
||||
explicit NativeClock(); |
|
||||
|
|
||||
std::chrono::nanoseconds GetTimeNS() const override; |
|
||||
|
|
||||
std::chrono::microseconds GetTimeUS() const override; |
|
||||
|
|
||||
std::chrono::milliseconds GetTimeMS() const override; |
|
||||
|
|
||||
s64 GetCNTPCT() const override; |
|
||||
|
|
||||
s64 GetGPUTick() const override; |
|
||||
|
|
||||
s64 GetUptime() const override; |
|
||||
|
|
||||
bool IsNative() const override; |
|
||||
|
|
||||
static s64 GetHostCNTFRQ(); |
|
||||
|
|
||||
public: |
|
||||
using FactorType = unsigned __int128; |
|
||||
|
|
||||
FactorType GetGuestCNTFRQFactor() const { |
|
||||
return guest_cntfrq_factor; |
|
||||
} |
|
||||
|
|
||||
private: |
|
||||
FactorType ns_cntfrq_factor; |
|
||||
FactorType us_cntfrq_factor; |
|
||||
FactorType ms_cntfrq_factor; |
|
||||
FactorType guest_cntfrq_factor; |
|
||||
FactorType gputick_cntfrq_factor; |
|
||||
}; |
|
||||
|
|
||||
} // namespace Common::Arm64 |
|
||||
@ -1,77 +1,196 @@ |
|||||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
|
||||
|
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
|
||||
// SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
|
||||
#include "common/steady_clock.h"
|
#include "common/steady_clock.h"
|
||||
|
#include "common/uint128.h"
|
||||
#include "common/wall_clock.h"
|
#include "common/wall_clock.h"
|
||||
|
|
||||
|
#ifdef __ANDROID__
|
||||
|
#include <sys/system_properties.h>
|
||||
|
#endif
|
||||
#ifdef ARCHITECTURE_x86_64
|
#ifdef ARCHITECTURE_x86_64
|
||||
#include "common/x64/cpu_detect.h"
|
#include "common/x64/cpu_detect.h"
|
||||
#include "common/x64/native_clock.h"
|
|
||||
#include "common/x64/rdtsc.h"
|
#include "common/x64/rdtsc.h"
|
||||
#endif
|
#endif
|
||||
#ifdef HAS_NCE
|
|
||||
#include "common/arm64/native_clock.h"
|
|
||||
#endif
|
|
||||
|
|
||||
namespace Common { |
namespace Common { |
||||
|
|
||||
class StandardWallClock final : public WallClock { |
|
||||
public: |
|
||||
explicit StandardWallClock() {} |
|
||||
|
#if defined(ARCHITECTURE_x86_64)
|
||||
|
WallClock::WallClock(bool invariant_, u64 rdtsc_frequency_) noexcept |
||||
|
: invariant{invariant_} |
||||
|
, rdtsc_frequency{rdtsc_frequency_} |
||||
|
, ns_rdtsc_factor{GetFixedPoint64Factor(NsRatio::den, rdtsc_frequency_)} |
||||
|
, us_rdtsc_factor{GetFixedPoint64Factor(UsRatio::den, rdtsc_frequency_)} |
||||
|
, ms_rdtsc_factor{GetFixedPoint64Factor(MsRatio::den, rdtsc_frequency_)} |
||||
|
, cntpct_rdtsc_factor{GetFixedPoint64Factor(CNTFRQ, rdtsc_frequency_)} |
||||
|
, gputick_rdtsc_factor{GetFixedPoint64Factor(GPUTickFreq, rdtsc_frequency_)} |
||||
|
{} |
||||
|
|
||||
std::chrono::nanoseconds GetTimeNS() const override { |
|
||||
return std::chrono::duration_cast<std::chrono::nanoseconds>( |
|
||||
std::chrono::system_clock::now().time_since_epoch()); |
|
||||
} |
|
||||
|
std::chrono::nanoseconds WallClock::GetTimeNS() const { |
||||
|
if (invariant) |
||||
|
return std::chrono::duration_cast<std::chrono::nanoseconds>(std::chrono::system_clock::now().time_since_epoch()); |
||||
|
return std::chrono::nanoseconds{MultiplyHigh(GetUptime(), ns_rdtsc_factor)}; |
||||
|
} |
||||
|
|
||||
std::chrono::microseconds GetTimeUS() const override { |
|
||||
return std::chrono::duration_cast<std::chrono::microseconds>( |
|
||||
std::chrono::system_clock::now().time_since_epoch()); |
|
||||
} |
|
||||
|
std::chrono::microseconds WallClock::GetTimeUS() const { |
||||
|
if (invariant) |
||||
|
return std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::system_clock::now().time_since_epoch()); |
||||
|
return std::chrono::microseconds{MultiplyHigh(GetUptime(), us_rdtsc_factor)}; |
||||
|
} |
||||
|
|
||||
std::chrono::milliseconds GetTimeMS() const override { |
|
||||
return std::chrono::duration_cast<std::chrono::milliseconds>( |
|
||||
std::chrono::system_clock::now().time_since_epoch()); |
|
||||
} |
|
||||
|
std::chrono::milliseconds WallClock::GetTimeMS() const { |
||||
|
if (invariant) |
||||
|
return std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now().time_since_epoch()); |
||||
|
return std::chrono::milliseconds{MultiplyHigh(GetUptime(), ms_rdtsc_factor)}; |
||||
|
} |
||||
|
|
||||
s64 GetCNTPCT() const override { |
|
||||
|
s64 WallClock::GetCNTPCT() const { |
||||
|
if (invariant) |
||||
return GetUptime() * NsToCNTPCTRatio::num / NsToCNTPCTRatio::den; |
return GetUptime() * NsToCNTPCTRatio::num / NsToCNTPCTRatio::den; |
||||
} |
|
||||
|
return MultiplyHigh(GetUptime(), cntpct_rdtsc_factor); |
||||
|
} |
||||
|
|
||||
s64 GetGPUTick() const override { |
|
||||
|
s64 WallClock::GetGPUTick() const { |
||||
|
if (invariant) |
||||
return GetUptime() * NsToGPUTickRatio::num / NsToGPUTickRatio::den; |
return GetUptime() * NsToGPUTickRatio::num / NsToGPUTickRatio::den; |
||||
} |
|
||||
|
return MultiplyHigh(GetUptime(), gputick_rdtsc_factor); |
||||
|
} |
||||
|
|
||||
s64 GetUptime() const override { |
|
||||
return std::chrono::duration_cast<std::chrono::nanoseconds>( |
|
||||
std::chrono::steady_clock::now().time_since_epoch()) |
|
||||
.count(); |
|
||||
} |
|
||||
|
s64 WallClock::GetUptime() const { |
||||
|
if (invariant) |
||||
|
return std::chrono::duration_cast<std::chrono::nanoseconds>(std::chrono::steady_clock::now().time_since_epoch()).count(); |
||||
|
return s64(Common::X64::FencedRDTSC()); |
||||
|
} |
||||
|
|
||||
bool IsNative() const override { |
|
||||
|
bool WallClock::IsNative() const { |
||||
|
if (invariant) |
||||
return false; |
return false; |
||||
} |
|
||||
}; |
|
||||
|
return true; |
||||
|
} |
||||
|
#elif defined(HAS_NCE)
|
||||
|
namespace { |
||||
|
|
||||
std::unique_ptr<WallClock> CreateOptimalClock() { |
|
||||
#if defined(ARCHITECTURE_x86_64)
|
|
||||
const auto& caps = GetCPUCaps(); |
|
||||
|
[[nodiscard]] WallClock::FactorType GetFixedPointFactor(u64 num, u64 den) noexcept { |
||||
|
return (WallClock::FactorType(num) << 64) / den; |
||||
|
} |
||||
|
|
||||
|
[[nodiscard]] u64 MultiplyHigh(u64 m, WallClock::FactorType factor) noexcept { |
||||
|
return static_cast<u64>((m * factor) >> 64); |
||||
|
} |
||||
|
|
||||
if (caps.invariant_tsc && caps.tsc_frequency >= std::nano::den) { |
|
||||
return std::make_unique<X64::NativeClock>(caps.tsc_frequency); |
|
||||
|
[[nodiscard]] s64 GetHostCNTFRQ() noexcept { |
||||
|
u64 cntfrq_el0 = 0; |
||||
|
#ifdef ANDROID
|
||||
|
std::string_view board{""}; |
||||
|
char buffer[PROP_VALUE_MAX]; |
||||
|
int len{__system_property_get("ro.product.board", buffer)}; |
||||
|
board = std::string_view(buffer, static_cast<size_t>(len)); |
||||
|
if (board == "s5e9925") { // Exynos 2200
|
||||
|
cntfrq_el0 = 25600000; |
||||
|
} else if (board == "exynos2100") { // Exynos 2100
|
||||
|
cntfrq_el0 = 26000000; |
||||
|
} else if (board == "exynos9810") { // Exynos 9810
|
||||
|
cntfrq_el0 = 26000000; |
||||
|
} else if (board == "s5e8825") { // Exynos 1280
|
||||
|
cntfrq_el0 = 26000000; |
||||
} else { |
} else { |
||||
// Fallback to StandardWallClock if the hardware TSC
|
|
||||
// - Is not invariant
|
|
||||
// - Is not more precise than 1 GHz (1ns resolution)
|
|
||||
return std::make_unique<StandardWallClock>(); |
|
||||
|
asm volatile("mrs %[cntfrq_el0], cntfrq_el0" : [cntfrq_el0] "=r"(cntfrq_el0)); |
||||
} |
} |
||||
|
return cntfrq_el0; |
||||
|
#else
|
||||
|
asm volatile("mrs %[cntfrq_el0], cntfrq_el0" : [cntfrq_el0] "=r"(cntfrq_el0)); |
||||
|
return cntfrq_el0; |
||||
|
#endif
|
||||
|
} |
||||
|
|
||||
|
} // namespace
|
||||
|
|
||||
|
WallClock::WallClock(bool invariant_, u64 rdtsc_frequency_) noexcept { |
||||
|
const u64 host_cntfrq = std::max<u64>(GetHostCNTFRQ(), 1); |
||||
|
ns_cntfrq_factor = GetFixedPointFactor(NsRatio::den, host_cntfrq); |
||||
|
us_cntfrq_factor = GetFixedPointFactor(UsRatio::den, host_cntfrq); |
||||
|
ms_cntfrq_factor = GetFixedPointFactor(MsRatio::den, host_cntfrq); |
||||
|
guest_cntfrq_factor = GetFixedPointFactor(CNTFRQ, host_cntfrq); |
||||
|
gputick_cntfrq_factor = GetFixedPointFactor(GPUTickFreq, host_cntfrq); |
||||
|
} |
||||
|
|
||||
|
std::chrono::nanoseconds WallClock::GetTimeNS() const { |
||||
|
return std::chrono::nanoseconds{MultiplyHigh(GetUptime(), ns_cntfrq_factor)}; |
||||
|
} |
||||
|
|
||||
|
std::chrono::microseconds WallClock::GetTimeUS() const { |
||||
|
return std::chrono::microseconds{MultiplyHigh(GetUptime(), us_cntfrq_factor)}; |
||||
|
} |
||||
|
|
||||
|
std::chrono::milliseconds WallClock::GetTimeMS() const { |
||||
|
return std::chrono::milliseconds{MultiplyHigh(GetUptime(), ms_cntfrq_factor)}; |
||||
|
} |
||||
|
|
||||
|
s64 WallClock::GetCNTPCT() const { |
||||
|
return MultiplyHigh(GetUptime(), guest_cntfrq_factor); |
||||
|
} |
||||
|
|
||||
|
s64 WallClock::GetGPUTick() const { |
||||
|
return MultiplyHigh(GetUptime(), gputick_cntfrq_factor); |
||||
|
} |
||||
|
|
||||
|
s64 WallClock::GetUptime() const { |
||||
|
s64 cntvct_el0 = 0; |
||||
|
asm volatile( |
||||
|
"dsb ish\n\t" |
||||
|
"mrs %[cntvct_el0], cntvct_el0\n\t" |
||||
|
"dsb ish\n\t" |
||||
|
: [cntvct_el0] "=r"(cntvct_el0) |
||||
|
); |
||||
|
return cntvct_el0; |
||||
|
} |
||||
|
|
||||
|
bool WallClock::IsNative() const { |
||||
|
return true; |
||||
|
} |
||||
|
#else
|
||||
|
WallClock::WallClock(bool invariant_, u64 rdtsc_frequency_) noexcept {} |
||||
|
|
||||
|
std::chrono::nanoseconds WallClock::GetTimeNS() const { |
||||
|
return std::chrono::duration_cast<std::chrono::nanoseconds>(std::chrono::system_clock::now().time_since_epoch()); |
||||
|
} |
||||
|
|
||||
|
std::chrono::microseconds WallClock::GetTimeUS() const { |
||||
|
return std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::system_clock::now().time_since_epoch()); |
||||
|
} |
||||
|
|
||||
|
std::chrono::milliseconds WallClock::GetTimeMS() const { |
||||
|
return std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now().time_since_epoch()); |
||||
|
} |
||||
|
|
||||
|
s64 WallClock::GetCNTPCT() const { |
||||
|
return GetUptime() * NsToCNTPCTRatio::num / NsToCNTPCTRatio::den; |
||||
|
} |
||||
|
|
||||
|
s64 WallClock::GetGPUTick() const { |
||||
|
return GetUptime() * NsToGPUTickRatio::num / NsToGPUTickRatio::den; |
||||
|
} |
||||
|
|
||||
|
s64 WallClock::GetUptime() const { |
||||
|
return std::chrono::duration_cast<std::chrono::nanoseconds>(std::chrono::steady_clock::now().time_since_epoch()).count(); |
||||
|
} |
||||
|
|
||||
|
bool WallClock::IsNative() const { |
||||
|
return false; |
||||
|
} |
||||
|
#endif
|
||||
|
|
||||
|
WallClock CreateOptimalClock() noexcept { |
||||
|
#if defined(ARCHITECTURE_x86_64)
|
||||
|
auto const& caps = GetCPUCaps(); |
||||
|
return WallClock(!(caps.invariant_tsc && caps.tsc_frequency >= std::nano::den), std::max<u64>(caps.tsc_frequency, 1)); |
||||
#elif defined(HAS_NCE)
|
#elif defined(HAS_NCE)
|
||||
return std::make_unique<Arm64::NativeClock>(); |
|
||||
|
return WallClock(false, 1); |
||||
#else
|
#else
|
||||
return std::make_unique<StandardWallClock>(); |
|
||||
|
return WallClock(true, 1); |
||||
#endif
|
#endif
|
||||
} |
} |
||||
|
|
||||
|
|||||
@ -1,46 +0,0 @@ |
|||||
// SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project
|
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
|
||||
|
|
||||
#include "common/uint128.h"
|
|
||||
#include "common/x64/native_clock.h"
|
|
||||
#include "common/x64/rdtsc.h"
|
|
||||
|
|
||||
namespace Common::X64 { |
|
||||
|
|
||||
NativeClock::NativeClock(u64 rdtsc_frequency_) |
|
||||
: rdtsc_frequency{rdtsc_frequency_}, ns_rdtsc_factor{GetFixedPoint64Factor(NsRatio::den, |
|
||||
rdtsc_frequency)}, |
|
||||
us_rdtsc_factor{GetFixedPoint64Factor(UsRatio::den, rdtsc_frequency)}, |
|
||||
ms_rdtsc_factor{GetFixedPoint64Factor(MsRatio::den, rdtsc_frequency)}, |
|
||||
cntpct_rdtsc_factor{GetFixedPoint64Factor(CNTFRQ, rdtsc_frequency)}, |
|
||||
gputick_rdtsc_factor{GetFixedPoint64Factor(GPUTickFreq, rdtsc_frequency)} {} |
|
||||
|
|
||||
std::chrono::nanoseconds NativeClock::GetTimeNS() const { |
|
||||
return std::chrono::nanoseconds{MultiplyHigh(GetUptime(), ns_rdtsc_factor)}; |
|
||||
} |
|
||||
|
|
||||
std::chrono::microseconds NativeClock::GetTimeUS() const { |
|
||||
return std::chrono::microseconds{MultiplyHigh(GetUptime(), us_rdtsc_factor)}; |
|
||||
} |
|
||||
|
|
||||
std::chrono::milliseconds NativeClock::GetTimeMS() const { |
|
||||
return std::chrono::milliseconds{MultiplyHigh(GetUptime(), ms_rdtsc_factor)}; |
|
||||
} |
|
||||
|
|
||||
s64 NativeClock::GetCNTPCT() const { |
|
||||
return MultiplyHigh(GetUptime(), cntpct_rdtsc_factor); |
|
||||
} |
|
||||
|
|
||||
s64 NativeClock::GetGPUTick() const { |
|
||||
return MultiplyHigh(GetUptime(), gputick_rdtsc_factor); |
|
||||
} |
|
||||
|
|
||||
s64 NativeClock::GetUptime() const { |
|
||||
return static_cast<s64>(FencedRDTSC()); |
|
||||
} |
|
||||
|
|
||||
bool NativeClock::IsNative() const { |
|
||||
return true; |
|
||||
} |
|
||||
|
|
||||
} // namespace Common::X64
|
|
||||
@ -1,38 +0,0 @@ |
|||||
// SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project |
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
|
|
||||
#pragma once |
|
||||
|
|
||||
#include "common/wall_clock.h" |
|
||||
|
|
||||
namespace Common::X64 { |
|
||||
|
|
||||
class NativeClock final : public WallClock { |
|
||||
public: |
|
||||
explicit NativeClock(u64 rdtsc_frequency_); |
|
||||
|
|
||||
std::chrono::nanoseconds GetTimeNS() const override; |
|
||||
|
|
||||
std::chrono::microseconds GetTimeUS() const override; |
|
||||
|
|
||||
std::chrono::milliseconds GetTimeMS() const override; |
|
||||
|
|
||||
s64 GetCNTPCT() const override; |
|
||||
|
|
||||
s64 GetGPUTick() const override; |
|
||||
|
|
||||
s64 GetUptime() const override; |
|
||||
|
|
||||
bool IsNative() const override; |
|
||||
|
|
||||
private: |
|
||||
u64 rdtsc_frequency; |
|
||||
|
|
||||
u64 ns_rdtsc_factor; |
|
||||
u64 us_rdtsc_factor; |
|
||||
u64 ms_rdtsc_factor; |
|
||||
u64 cntpct_rdtsc_factor; |
|
||||
u64 gputick_rdtsc_factor; |
|
||||
}; |
|
||||
|
|
||||
} // namespace Common::X64 |
|
||||
Write
Preview
Loading…
Cancel
Save
Reference in new issue