summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/common/x64/native_clock.cpp34
-rw-r--r--src/common/x64/native_clock.h5
2 files changed, 34 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
84u64 NativeClock::GetRTSC() { 100u64 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
157void 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
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 @@
3 3
4#pragma once 4#pragma once
5 5
6#include "common/polyfill_thread.h"
6#include "common/wall_clock.h" 7#include "common/wall_clock.h"
7 8
8namespace Common { 9namespace Common {
@@ -28,6 +29,8 @@ public:
28private: 29private:
29 u64 GetRTSC(); 30 u64 GetRTSC();
30 31
32 void CalculateAndSetFactors();
33
31 union alignas(16) TimePoint { 34 union alignas(16) TimePoint {
32 TimePoint() : pack{} {} 35 TimePoint() : pack{} {}
33 u128 pack{}; 36 u128 pack{};
@@ -47,6 +50,8 @@ private:
47 u64 ms_rtsc_factor{}; 50 u64 ms_rtsc_factor{};
48 51
49 u64 rtsc_frequency; 52 u64 rtsc_frequency;
53
54 std::jthread time_sync_thread;
50}; 55};
51} // namespace X64 56} // namespace X64
52 57