From 2575a93dc6d15bb4c60c18be1635b48f37355059 Mon Sep 17 00:00:00 2001
From: Fernando Sahmkow <fsahmkow27@gmail.com>
Date: Tue, 28 Jun 2022 22:42:00 +0200
Subject: [PATCH] Native clock: Use atomic ops as before.

---
 src/common/x64/native_clock.cpp | 39 +++++++++++++++++----------------
 src/common/x64/native_clock.h   | 14 +++++++-----
 2 files changed, 29 insertions(+), 24 deletions(-)

diff --git a/src/common/x64/native_clock.cpp b/src/common/x64/native_clock.cpp
index 488c8c905c..c0d38cf6be 100644
--- a/src/common/x64/native_clock.cpp
+++ b/src/common/x64/native_clock.cpp
@@ -65,10 +65,8 @@ NativeClock::NativeClock(u64 emulated_cpu_frequency_, u64 emulated_clock_frequen
                          u64 rtsc_frequency_)
     : WallClock(emulated_cpu_frequency_, emulated_clock_frequency_, true), rtsc_frequency{
                                                                                rtsc_frequency_} {
-    TimePoint new_time_point{};
-    new_time_point.last_measure = FencedRDTSC();
-    new_time_point.accumulated_ticks = 0U;
-    time_point.store(new_time_point);
+    time_point.inner.last_measure = FencedRDTSC();
+    time_point.inner.accumulated_ticks = 0U;
     ns_rtsc_factor = GetFixedPoint64Factor(NS_RATIO, rtsc_frequency);
     us_rtsc_factor = GetFixedPoint64Factor(US_RATIO, rtsc_frequency);
     ms_rtsc_factor = GetFixedPoint64Factor(MS_RATIO, rtsc_frequency);
@@ -77,32 +75,35 @@ NativeClock::NativeClock(u64 emulated_cpu_frequency_, u64 emulated_clock_frequen
 }
 
 u64 NativeClock::GetRTSC() {
+    TimePoint current_time_point{};
     TimePoint new_time_point{};
-    TimePoint current_time_point = time_point.load(std::memory_order_acquire);
+
+    current_time_point.pack = Common::AtomicLoad128(time_point.pack.data());
     do {
         const u64 current_measure = FencedRDTSC();
-        u64 diff = current_measure - current_time_point.last_measure;
+        u64 diff = current_measure - current_time_point.inner.last_measure;
         diff = diff & ~static_cast<u64>(static_cast<s64>(diff) >> 63); // max(diff, 0)
-        new_time_point.last_measure = current_measure > current_time_point.last_measure
-                                          ? current_measure
-                                          : current_time_point.last_measure;
-        new_time_point.accumulated_ticks = current_time_point.accumulated_ticks + diff;
-    } while (!time_point.compare_exchange_weak(
-        current_time_point, new_time_point, std::memory_order_release, std::memory_order_acquire));
+        new_time_point.inner.last_measure = current_measure > current_time_point.inner.last_measure
+                                                ? current_measure
+                                                : 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));
     /// The clock cannot be more precise than the guest timer, remove the lower bits
-    return new_time_point.accumulated_ticks;
+    return new_time_point.inner.accumulated_ticks;
 }
 
 void NativeClock::Pause(bool is_paused) {
     if (!is_paused) {
+        TimePoint current_time_point{};
         TimePoint new_time_point{};
-        TimePoint current_time_point = time_point.load(std::memory_order_acquire);
+
+        current_time_point.pack = Common::AtomicLoad128(time_point.pack.data());
         do {
-            new_time_point = current_time_point;
-            new_time_point.last_measure = FencedRDTSC();
-        } while (!time_point.compare_exchange_weak(current_time_point, new_time_point,
-                                                   std::memory_order_release,
-                                                   std::memory_order_acquire));
+            new_time_point.pack = current_time_point.pack;
+            new_time_point.inner.last_measure = FencedRDTSC();
+        } while (!Common::AtomicCompareAndSwap(time_point.pack.data(), new_time_point.pack,
+                                               current_time_point.pack, current_time_point.pack));
     }
 }
 
diff --git a/src/common/x64/native_clock.h b/src/common/x64/native_clock.h
index 046cea0952..38ae7a4625 100644
--- a/src/common/x64/native_clock.h
+++ b/src/common/x64/native_clock.h
@@ -3,7 +3,6 @@
 
 #pragma once
 
-#include <atomic>
 #include "common/wall_clock.h"
 
 namespace Common {
@@ -29,12 +28,17 @@ public:
 private:
     u64 GetRTSC();
 
-    struct alignas(16) TimePoint {
-        u64 last_measure{};
-        u64 accumulated_ticks{};
+    union alignas(16) TimePoint {
+        TimePoint() : pack{} {}
+        u128 pack{};
+        struct Inner {
+            u64 last_measure{};
+            u64 accumulated_ticks{};
+        } inner;
     };
 
-    std::atomic<TimePoint> time_point;
+    TimePoint time_point;
+
     // factors
     u64 clock_rtsc_factor{};
     u64 cpu_rtsc_factor{};