diff options
Diffstat (limited to 'src/common/x64/native_clock.cpp')
| -rw-r--r-- | src/common/x64/native_clock.cpp | 34 |
1 files changed, 29 insertions, 5 deletions
diff --git a/src/common/x64/native_clock.cpp b/src/common/x64/native_clock.cpp index bc1a973b0..c11590291 100644 --- a/src/common/x64/native_clock.cpp +++ b/src/common/x64/native_clock.cpp | |||
| @@ -72,13 +72,29 @@ NativeClock::NativeClock(u64 emulated_cpu_frequency_, u64 emulated_clock_frequen | |||
| 72 | u64 rtsc_frequency_) | 72 | u64 rtsc_frequency_) |
| 73 | : WallClock(emulated_cpu_frequency_, emulated_clock_frequency_, true), rtsc_frequency{ | 73 | : WallClock(emulated_cpu_frequency_, emulated_clock_frequency_, true), rtsc_frequency{ |
| 74 | rtsc_frequency_} { | 74 | rtsc_frequency_} { |
| 75 | // Thread to re-adjust the RDTSC frequency after 30 seconds has elapsed. | ||
| 76 | time_sync_thread = std::jthread{[this](std::stop_token token) { | ||
| 77 | // Get the current time. | ||
| 78 | const auto start_time = Common::SteadyClock::Now(); | ||
| 79 | const u64 tsc_start = FencedRDTSC(); | ||
| 80 | // Wait for 30 seconds. | ||
| 81 | if (!Common::StoppableTimedWait(token, std::chrono::seconds{30})) { | ||
| 82 | return; | ||
| 83 | } | ||
| 84 | const auto end_time = Common::SteadyClock::Now(); | ||
| 85 | const u64 tsc_end = FencedRDTSC(); | ||
| 86 | // Calculate differences. | ||
| 87 | const u64 timer_diff = static_cast<u64>( | ||
| 88 | std::chrono::duration_cast<std::chrono::nanoseconds>(end_time - start_time).count()); | ||
| 89 | const u64 tsc_diff = tsc_end - tsc_start; | ||
| 90 | const u64 tsc_freq = MultiplyAndDivide64(tsc_diff, 1000000000ULL, timer_diff); | ||
| 91 | rtsc_frequency = tsc_freq; | ||
| 92 | CalculateAndSetFactors(); | ||
| 93 | }}; | ||
| 94 | |||
| 75 | time_point.inner.last_measure = FencedRDTSC(); | 95 | time_point.inner.last_measure = FencedRDTSC(); |
| 76 | time_point.inner.accumulated_ticks = 0U; | 96 | time_point.inner.accumulated_ticks = 0U; |
| 77 | ns_rtsc_factor = GetFixedPoint64Factor(NS_RATIO, rtsc_frequency); | 97 | CalculateAndSetFactors(); |
| 78 | us_rtsc_factor = GetFixedPoint64Factor(US_RATIO, rtsc_frequency); | ||
| 79 | ms_rtsc_factor = GetFixedPoint64Factor(MS_RATIO, rtsc_frequency); | ||
| 80 | clock_rtsc_factor = GetFixedPoint64Factor(emulated_clock_frequency, rtsc_frequency); | ||
| 81 | cpu_rtsc_factor = GetFixedPoint64Factor(emulated_cpu_frequency, rtsc_frequency); | ||
| 82 | } | 98 | } |
| 83 | 99 | ||
| 84 | u64 NativeClock::GetRTSC() { | 100 | u64 NativeClock::GetRTSC() { |
| @@ -138,6 +154,14 @@ u64 NativeClock::GetCPUCycles() { | |||
| 138 | return MultiplyHigh(rtsc_value, cpu_rtsc_factor); | 154 | return MultiplyHigh(rtsc_value, cpu_rtsc_factor); |
| 139 | } | 155 | } |
| 140 | 156 | ||
| 157 | void NativeClock::CalculateAndSetFactors() { | ||
| 158 | ns_rtsc_factor = GetFixedPoint64Factor(NS_RATIO, rtsc_frequency); | ||
| 159 | us_rtsc_factor = GetFixedPoint64Factor(US_RATIO, rtsc_frequency); | ||
| 160 | ms_rtsc_factor = GetFixedPoint64Factor(MS_RATIO, rtsc_frequency); | ||
| 161 | clock_rtsc_factor = GetFixedPoint64Factor(emulated_clock_frequency, rtsc_frequency); | ||
| 162 | cpu_rtsc_factor = GetFixedPoint64Factor(emulated_cpu_frequency, rtsc_frequency); | ||
| 163 | } | ||
| 164 | |||
| 141 | } // namespace X64 | 165 | } // namespace X64 |
| 142 | 166 | ||
| 143 | } // namespace Common | 167 | } // namespace Common |