Просмотр исходного кода

common: wall_clock: Check precision against the emulated CPU and CNTFRQ

In addition to requiring nanosecond precision, using the native clock requires that the hardware TSC has a precision greater than the emulated CPU and its clock counter.
Morph 4 лет назад
Родитель
Сommit
6267110b69
2 измененных файлов с 12 добавлено и 8 удалено
  1. 10 6
      src/common/wall_clock.cpp
  2. 2 2
      src/common/wall_clock.h

+ 10 - 6
src/common/wall_clock.cpp

@@ -65,16 +65,20 @@ private:
 
 #ifdef ARCHITECTURE_x86_64
 
-std::unique_ptr<WallClock> CreateBestMatchingClock(u32 emulated_cpu_frequency,
-                                                   u32 emulated_clock_frequency) {
+std::unique_ptr<WallClock> CreateBestMatchingClock(u64 emulated_cpu_frequency,
+                                                   u64 emulated_clock_frequency) {
     const auto& caps = GetCPUCaps();
     u64 rtsc_frequency = 0;
     if (caps.invariant_tsc) {
         rtsc_frequency = EstimateRDTSCFrequency();
     }
 
-    // Fallback to StandardWallClock if the hardware TSC does not have nanosecond precision.
-    if (rtsc_frequency <= WallClock::NS_RATIO) {
+    // Fallback to StandardWallClock if the hardware TSC does not have the precision greater than:
+    // - A nanosecond
+    // - The emulated CPU frequency
+    // - The emulated clock counter frequency (CNTFRQ)
+    if (rtsc_frequency <= WallClock::NS_RATIO || rtsc_frequency <= emulated_cpu_frequency ||
+        rtsc_frequency <= emulated_clock_frequency) {
         return std::make_unique<StandardWallClock>(emulated_cpu_frequency,
                                                    emulated_clock_frequency);
     } else {
@@ -85,8 +89,8 @@ std::unique_ptr<WallClock> CreateBestMatchingClock(u32 emulated_cpu_frequency,
 
 #else
 
-std::unique_ptr<WallClock> CreateBestMatchingClock(u32 emulated_cpu_frequency,
-                                                   u32 emulated_clock_frequency) {
+std::unique_ptr<WallClock> CreateBestMatchingClock(u64 emulated_cpu_frequency,
+                                                   u64 emulated_clock_frequency) {
     return std::make_unique<StandardWallClock>(emulated_cpu_frequency, emulated_clock_frequency);
 }
 

+ 2 - 2
src/common/wall_clock.h

@@ -53,7 +53,7 @@ private:
     bool is_native;
 };
 
-[[nodiscard]] std::unique_ptr<WallClock> CreateBestMatchingClock(u32 emulated_cpu_frequency,
-                                                                 u32 emulated_clock_frequency);
+[[nodiscard]] std::unique_ptr<WallClock> CreateBestMatchingClock(u64 emulated_cpu_frequency,
+                                                                 u64 emulated_clock_frequency);
 
 } // namespace Common