summaryrefslogtreecommitdiff
path: root/src/common/x64
diff options
context:
space:
mode:
Diffstat (limited to 'src/common/x64')
-rw-r--r--src/common/x64/native_clock.cpp14
-rw-r--r--src/common/x64/native_clock.h7
2 files changed, 18 insertions, 3 deletions
diff --git a/src/common/x64/native_clock.cpp b/src/common/x64/native_clock.cpp
index 26d4d0ba6..424b39b1f 100644
--- a/src/common/x64/native_clock.cpp
+++ b/src/common/x64/native_clock.cpp
@@ -3,6 +3,7 @@
3// Refer to the license.txt file included. 3// Refer to the license.txt file included.
4 4
5#include <chrono> 5#include <chrono>
6#include <mutex>
6#include <thread> 7#include <thread>
7 8
8#ifdef _MSC_VER 9#ifdef _MSC_VER
@@ -52,7 +53,7 @@ NativeClock::NativeClock(u64 emulated_cpu_frequency, u64 emulated_clock_frequenc
52} 53}
53 54
54u64 NativeClock::GetRTSC() { 55u64 NativeClock::GetRTSC() {
55 rtsc_serialize.lock(); 56 std::scoped_lock scope{rtsc_serialize};
56 _mm_mfence(); 57 _mm_mfence();
57 const u64 current_measure = __rdtsc(); 58 const u64 current_measure = __rdtsc();
58 u64 diff = current_measure - last_measure; 59 u64 diff = current_measure - last_measure;
@@ -61,8 +62,15 @@ u64 NativeClock::GetRTSC() {
61 last_measure = current_measure; 62 last_measure = current_measure;
62 } 63 }
63 accumulated_ticks += diff; 64 accumulated_ticks += diff;
64 rtsc_serialize.unlock(); 65 /// The clock cannot be more precise than the guest timer, remove the lower bits
65 return accumulated_ticks; 66 return accumulated_ticks & inaccuracy_mask;
67}
68
69void NativeClock::Pause(bool is_paused) {
70 if (!is_paused) {
71 _mm_mfence();
72 last_measure = __rdtsc();
73 }
66} 74}
67 75
68std::chrono::nanoseconds NativeClock::GetTimeNS() { 76std::chrono::nanoseconds NativeClock::GetTimeNS() {
diff --git a/src/common/x64/native_clock.h b/src/common/x64/native_clock.h
index b58cf9f5a..891a3bbfd 100644
--- a/src/common/x64/native_clock.h
+++ b/src/common/x64/native_clock.h
@@ -26,9 +26,16 @@ public:
26 26
27 u64 GetCPUCycles() override; 27 u64 GetCPUCycles() override;
28 28
29 void Pause(bool is_paused) override;
30
29private: 31private:
30 u64 GetRTSC(); 32 u64 GetRTSC();
31 33
34 /// value used to reduce the native clocks accuracy as some apss rely on
35 /// undefined behavior where the level of accuracy in the clock shouldn't
36 /// be higher.
37 static constexpr u64 inaccuracy_mask = ~(0x400 - 1);
38
32 SpinLock rtsc_serialize{}; 39 SpinLock rtsc_serialize{};
33 u64 last_measure{}; 40 u64 last_measure{};
34 u64 accumulated_ticks{}; 41 u64 accumulated_ticks{};