From 979e53b87b5288c582392beff618da978ca4152c Mon Sep 17 00:00:00 2001
From: merry <git@mary.rs>
Date: Sat, 2 Apr 2022 21:05:49 +0100
Subject: [PATCH] native_clock: Use writeback from CAS to avoid double-loading

---
 src/common/x64/native_clock.cpp | 10 ++++++----
 1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/src/common/x64/native_clock.cpp b/src/common/x64/native_clock.cpp
index 2a2664e5d5..7a3f21dcf1 100644
--- a/src/common/x64/native_clock.cpp
+++ b/src/common/x64/native_clock.cpp
@@ -55,8 +55,9 @@ NativeClock::NativeClock(u64 emulated_cpu_frequency_, u64 emulated_clock_frequen
 u64 NativeClock::GetRTSC() {
     TimePoint new_time_point{};
     TimePoint current_time_point{};
+
+    current_time_point.pack = Common::AtomicLoad128(time_point.pack.data());
     do {
-        current_time_point.pack = Common::AtomicLoad128(time_point.pack.data());
         _mm_mfence();
         const u64 current_measure = __rdtsc();
         u64 diff = current_measure - current_time_point.inner.last_measure;
@@ -66,7 +67,7 @@ u64 NativeClock::GetRTSC() {
                                                 : current_time_point.inner.last_measure;
         new_time_point.inner.accumulated_ticks = current_time_point.inner.accumulated_ticks + diff;
     } while (!Common::AtomicCompareAndSwap(time_point.pack.data(), new_time_point.pack,
-                                           current_time_point.pack));
+                                           current_time_point.pack, current_time_point.pack));
     /// The clock cannot be more precise than the guest timer, remove the lower bits
     return new_time_point.inner.accumulated_ticks & inaccuracy_mask;
 }
@@ -75,13 +76,14 @@ void NativeClock::Pause(bool is_paused) {
     if (!is_paused) {
         TimePoint current_time_point{};
         TimePoint new_time_point{};
+
+        current_time_point.pack = Common::AtomicLoad128(time_point.pack.data());
         do {
-            current_time_point.pack = Common::AtomicLoad128(time_point.pack.data());
             new_time_point.pack = current_time_point.pack;
             _mm_mfence();
             new_time_point.inner.last_measure = __rdtsc();
         } while (!Common::AtomicCompareAndSwap(time_point.pack.data(), new_time_point.pack,
-                                               current_time_point.pack));
+                                               current_time_point.pack, current_time_point.pack));
     }
 }