summaryrefslogtreecommitdiff
path: root/src/common/x64/native_clock.cpp
diff options
context:
space:
mode:
authorGravatar Morph2023-03-04 21:44:31 -0500
committerGravatar Morph2023-03-07 21:17:46 -0500
commitdcd13a7566340e80c042da7f626f9747ac71b8a7 (patch)
tree599ff3c744fc4dc0c8eef4bb986cf034ce93977c /src/common/x64/native_clock.cpp
parentMerge pull request #9889 from Morph1984/time-is-ticking (diff)
downloadyuzu-dcd13a7566340e80c042da7f626f9747ac71b8a7.tar.gz
yuzu-dcd13a7566340e80c042da7f626f9747ac71b8a7.tar.xz
yuzu-dcd13a7566340e80c042da7f626f9747ac71b8a7.zip
native_clock: Re-adjust the RDTSC frequency
The RDTSC frequency reported by CPUID is not accurate to its true frequency. We will spawn a separate thread to calculate the true RDTSC frequency after a measurement period of 30 seconds has elapsed.
Diffstat (limited to 'src/common/x64/native_clock.cpp')
-rw-r--r--src/common/x64/native_clock.cpp34
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
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