From 33f6f5bba3f1be0f8cc3b00a9defd3c35bd48b37 Mon Sep 17 00:00:00 2001 From: lizzie Date: Sun, 24 May 2026 01:48:00 +0000 Subject: [PATCH] fuckery squared --- src/common/cpu_features.cpp | 16 +++++++++++++--- src/common/cpu_features.h | 11 +++++------ src/common/thread.cpp | 2 +- 3 files changed, 19 insertions(+), 10 deletions(-) diff --git a/src/common/cpu_features.cpp b/src/common/cpu_features.cpp index 2bfcf9baec..bb1c7c8577 100644 --- a/src/common/cpu_features.cpp +++ b/src/common/cpu_features.cpp @@ -238,9 +238,6 @@ const CPUCaps g_cpu_caps = [] { } else { caps.tsc_frequency = X64::EstimateRDTSCFrequency(); } - caps.tsc_to_ns_ratio = GetFixedPoint64Factor(NsRatio::den, caps.tsc_frequency); - } else { - caps.tsc_to_ns_ratio = 1; } if (max_std_fn >= 0x16) { @@ -262,6 +259,7 @@ WallClock::WallClock(bool invariant_, u64 rdtsc_frequency_) noexcept , ns_rdtsc_factor{invariant_ ? GetFixedPoint64Factor(NsRatio::den, rdtsc_frequency_) : 0} , us_rdtsc_factor{invariant_ ? GetFixedPoint64Factor(UsRatio::den, rdtsc_frequency_) : 0} , ms_rdtsc_factor{invariant_ ? GetFixedPoint64Factor(MsRatio::den, rdtsc_frequency_) : 0} + , rdtsc_ns_factor{invariant_ ? GetFixedPoint64Factor(rdtsc_frequency_, NsRatio::den) : 1} , cntpct_rdtsc_factor{invariant_ ? GetFixedPoint64Factor(CNTFRQ, rdtsc_frequency_) : 0} , gputick_rdtsc_factor{invariant_ ? GetFixedPoint64Factor(GPUTickFreq, rdtsc_frequency_) : 0} , invariant{invariant_} @@ -306,6 +304,10 @@ s64 WallClock::GetUptime() const { bool WallClock::IsNative() const { return invariant; } + +u64 WallClock::NsToTicks(std::chrono::nanoseconds ns) const { + return invariant ? MultiplyHigh(ns.count(), rdtsc_ns_factor) : ns.count(); +} #elif defined(HAS_NCE) namespace { @@ -387,6 +389,10 @@ s64 WallClock::GetUptime() const { bool WallClock::IsNative() const { return true; } + +u64 WallClock::NsToTicks(std::chrono::nanoseconds ns) const { + return ns; +} #else WallClock::WallClock(bool invariant_, u64 rdtsc_frequency_) noexcept {} @@ -417,6 +423,10 @@ s64 WallClock::GetUptime() const { bool WallClock::IsNative() const { return false; } + +u64 WallClock::NsToTicks(std::chrono::nanoseconds ns) const { + return ns; +} #endif // Wall clock MUST be initialized AFTER g_cpu_caps diff --git a/src/common/cpu_features.h b/src/common/cpu_features.h index b332dbde85..9655af3ee6 100644 --- a/src/common/cpu_features.h +++ b/src/common/cpu_features.h @@ -46,6 +46,9 @@ public: /// @returns Whether the clock directly uses the host's hardware clock. bool IsNative() const; + // @returns Nanoseconds to native ticks + u64 NsToTicks(std::chrono::nanoseconds ns) const; + static inline u64 NSToCNTPCT(u64 ns) { return ns * NsToCNTPCTRatio::num / NsToCNTPCTRatio::den; } @@ -72,7 +75,6 @@ public: return cpu_tick * CPUTickToGPUTickRatio::num / CPUTickToGPUTickRatio::den; } -protected: using NsRatio = std::nano; using UsRatio = std::micro; using MsRatio = std::milli; @@ -94,17 +96,15 @@ protected: u64 ns_rdtsc_factor; u64 us_rdtsc_factor; u64 ms_rdtsc_factor; + u64 rdtsc_ns_factor; u64 cntpct_rdtsc_factor; u64 gputick_rdtsc_factor; bool invariant; #elif defined(HAS_NCE) -public: using FactorType = unsigned __int128; - - FactorType GetGuestCNTFRQFactor() const { + [[nodiscard]] inline FactorType GetGuestCNTFRQFactor() const { return guest_cntfrq_factor; } -protected: FactorType ns_cntfrq_factor; FactorType us_cntfrq_factor; FactorType ms_cntfrq_factor; @@ -138,7 +138,6 @@ struct CPUCaps { u32 tsc_crystal_ratio_numerator; u32 crystal_frequency; u64 tsc_frequency; // Derived from the above three values - u64 tsc_to_ns_ratio; // Derived bool sse3 : 1; bool ssse3 : 1; diff --git a/src/common/thread.cpp b/src/common/thread.cpp index 1a02adc4eb..d53ba59131 100644 --- a/src/common/thread.cpp +++ b/src/common/thread.cpp @@ -174,7 +174,7 @@ __attribute__((target("waitpkg,mwaitx"))) bool Event::WaitFor(const std::chrono::nanoseconds time) { auto const start = Common::X64::FencedRDTSC(); auto const& caps = Common::g_cpu_caps; - [[maybe_unused]] auto const end = start + time.count() * caps.tsc_to_ns_ratio; + [[maybe_unused]] auto const end = start + Common::g_wall_clock.NsToTicks(time); if (caps.monitorx) { while (true) { // Armed monitor, as per manual, MWAITX must be conditional if the condition isn't satisfied