diff options
Diffstat (limited to 'src/common/x64')
| -rw-r--r-- | src/common/x64/native_clock.cpp | 38 | ||||
| -rw-r--r-- | src/common/x64/native_clock.h | 5 | 
2 files changed, 36 insertions, 7 deletions
| diff --git a/src/common/x64/native_clock.cpp b/src/common/x64/native_clock.cpp index bc1a973b0..76c66e7ee 100644 --- a/src/common/x64/native_clock.cpp +++ b/src/common/x64/native_clock.cpp @@ -53,11 +53,11 @@ u64 EstimateRDTSCFrequency() {      FencedRDTSC();      // Get the current time. -    const auto start_time = Common::SteadyClock::Now(); +    const auto start_time = Common::RealTimeClock::Now();      const u64 tsc_start = FencedRDTSC();      // Wait for 250 milliseconds.      std::this_thread::sleep_for(std::chrono::milliseconds{250}); -    const auto end_time = Common::SteadyClock::Now(); +    const auto end_time = Common::RealTimeClock::Now();      const u64 tsc_end = FencedRDTSC();      // Calculate differences.      const u64 timer_diff = static_cast<u64>( @@ -72,13 +72,29 @@ NativeClock::NativeClock(u64 emulated_cpu_frequency_, u64 emulated_clock_frequen                           u64 rtsc_frequency_)      : WallClock(emulated_cpu_frequency_, emulated_clock_frequency_, true), rtsc_frequency{                                                                                 rtsc_frequency_} { +    // Thread to re-adjust the RDTSC frequency after 10 seconds has elapsed. +    time_sync_thread = std::jthread{[this](std::stop_token token) { +        // Get the current time. +        const auto start_time = Common::RealTimeClock::Now(); +        const u64 tsc_start = FencedRDTSC(); +        // Wait for 10 seconds. +        if (!Common::StoppableTimedWait(token, std::chrono::seconds{10})) { +            return; +        } +        const auto end_time = Common::RealTimeClock::Now(); +        const u64 tsc_end = FencedRDTSC(); +        // Calculate differences. +        const u64 timer_diff = static_cast<u64>( +            std::chrono::duration_cast<std::chrono::nanoseconds>(end_time - start_time).count()); +        const u64 tsc_diff = tsc_end - tsc_start; +        const u64 tsc_freq = MultiplyAndDivide64(tsc_diff, 1000000000ULL, timer_diff); +        rtsc_frequency = tsc_freq; +        CalculateAndSetFactors(); +    }}; +      time_point.inner.last_measure = FencedRDTSC();      time_point.inner.accumulated_ticks = 0U; -    ns_rtsc_factor = GetFixedPoint64Factor(NS_RATIO, rtsc_frequency); -    us_rtsc_factor = GetFixedPoint64Factor(US_RATIO, rtsc_frequency); -    ms_rtsc_factor = GetFixedPoint64Factor(MS_RATIO, rtsc_frequency); -    clock_rtsc_factor = GetFixedPoint64Factor(emulated_clock_frequency, rtsc_frequency); -    cpu_rtsc_factor = GetFixedPoint64Factor(emulated_cpu_frequency, rtsc_frequency); +    CalculateAndSetFactors();  }  u64 NativeClock::GetRTSC() { @@ -138,6 +154,14 @@ u64 NativeClock::GetCPUCycles() {      return MultiplyHigh(rtsc_value, cpu_rtsc_factor);  } +void NativeClock::CalculateAndSetFactors() { +    ns_rtsc_factor = GetFixedPoint64Factor(NS_RATIO, rtsc_frequency); +    us_rtsc_factor = GetFixedPoint64Factor(US_RATIO, rtsc_frequency); +    ms_rtsc_factor = GetFixedPoint64Factor(MS_RATIO, rtsc_frequency); +    clock_rtsc_factor = GetFixedPoint64Factor(emulated_clock_frequency, rtsc_frequency); +    cpu_rtsc_factor = GetFixedPoint64Factor(emulated_cpu_frequency, rtsc_frequency); +} +  } // namespace X64  } // namespace Common diff --git a/src/common/x64/native_clock.h b/src/common/x64/native_clock.h index 38ae7a462..03ca291d8 100644 --- a/src/common/x64/native_clock.h +++ b/src/common/x64/native_clock.h @@ -3,6 +3,7 @@  #pragma once +#include "common/polyfill_thread.h"  #include "common/wall_clock.h"  namespace Common { @@ -28,6 +29,8 @@ public:  private:      u64 GetRTSC(); +    void CalculateAndSetFactors(); +      union alignas(16) TimePoint {          TimePoint() : pack{} {}          u128 pack{}; @@ -47,6 +50,8 @@ private:      u64 ms_rtsc_factor{};      u64 rtsc_frequency; + +    std::jthread time_sync_thread;  };  } // namespace X64 | 
