summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar Fernando Sahmkow2021-11-23 03:29:00 +0100
committerGravatar Fernando Sahmkow2022-06-28 01:06:48 +0200
commit096366ead51345bcd170e31b6160b14aaf73e996 (patch)
treedb99c0d032466f4bd94871baaecf0544fec82f25 /src
parentMerge pull request #8504 from comex/mesosphere-current-process (diff)
downloadyuzu-096366ead51345bcd170e31b6160b14aaf73e996.tar.gz
yuzu-096366ead51345bcd170e31b6160b14aaf73e996.tar.xz
yuzu-096366ead51345bcd170e31b6160b14aaf73e996.zip
Common: improve native clock.
Diffstat (limited to 'src')
-rw-r--r--src/common/uint128.h5
-rw-r--r--src/common/x64/native_clock.cpp40
-rw-r--r--src/common/x64/native_clock.h13
3 files changed, 29 insertions, 29 deletions
diff --git a/src/common/uint128.h b/src/common/uint128.h
index f890ffec2..199d0f55e 100644
--- a/src/common/uint128.h
+++ b/src/common/uint128.h
@@ -31,12 +31,17 @@ namespace Common {
31 return _udiv128(r[1], r[0], d, &remainder); 31 return _udiv128(r[1], r[0], d, &remainder);
32#endif 32#endif
33#else 33#else
34#ifdef __SIZEOF_INT128__
35 const auto product = static_cast<unsigned __int128>(a) * static_cast<unsigned __int128>(b);
36 return static_cast<u64>(product / d);
37#else
34 const u64 diva = a / d; 38 const u64 diva = a / d;
35 const u64 moda = a % d; 39 const u64 moda = a % d;
36 const u64 divb = b / d; 40 const u64 divb = b / d;
37 const u64 modb = b % d; 41 const u64 modb = b % d;
38 return diva * b + moda * divb + moda * modb / d; 42 return diva * b + moda * divb + moda * modb / d;
39#endif 43#endif
44#endif
40} 45}
41 46
42// This function multiplies 2 u64 values and produces a u128 value; 47// This function multiplies 2 u64 values and produces a u128 value;
diff --git a/src/common/x64/native_clock.cpp b/src/common/x64/native_clock.cpp
index 1b7194503..427a382cd 100644
--- a/src/common/x64/native_clock.cpp
+++ b/src/common/x64/native_clock.cpp
@@ -5,7 +5,6 @@
5#include <chrono> 5#include <chrono>
6#include <thread> 6#include <thread>
7 7
8#include "common/atomic_ops.h"
9#include "common/uint128.h" 8#include "common/uint128.h"
10#include "common/x64/native_clock.h" 9#include "common/x64/native_clock.h"
11 10
@@ -65,8 +64,10 @@ NativeClock::NativeClock(u64 emulated_cpu_frequency_, u64 emulated_clock_frequen
65 u64 rtsc_frequency_) 64 u64 rtsc_frequency_)
66 : WallClock(emulated_cpu_frequency_, emulated_clock_frequency_, true), rtsc_frequency{ 65 : WallClock(emulated_cpu_frequency_, emulated_clock_frequency_, true), rtsc_frequency{
67 rtsc_frequency_} { 66 rtsc_frequency_} {
68 time_point.inner.last_measure = FencedRDTSC(); 67 TimePoint new_time_point{};
69 time_point.inner.accumulated_ticks = 0U; 68 new_time_point.last_measure = FencedRDTSC();
69 new_time_point.accumulated_ticks = 0U;
70 time_point.store(new_time_point);
70 ns_rtsc_factor = GetFixedPoint64Factor(NS_RATIO, rtsc_frequency); 71 ns_rtsc_factor = GetFixedPoint64Factor(NS_RATIO, rtsc_frequency);
71 us_rtsc_factor = GetFixedPoint64Factor(US_RATIO, rtsc_frequency); 72 us_rtsc_factor = GetFixedPoint64Factor(US_RATIO, rtsc_frequency);
72 ms_rtsc_factor = GetFixedPoint64Factor(MS_RATIO, rtsc_frequency); 73 ms_rtsc_factor = GetFixedPoint64Factor(MS_RATIO, rtsc_frequency);
@@ -76,34 +77,31 @@ NativeClock::NativeClock(u64 emulated_cpu_frequency_, u64 emulated_clock_frequen
76 77
77u64 NativeClock::GetRTSC() { 78u64 NativeClock::GetRTSC() {
78 TimePoint new_time_point{}; 79 TimePoint new_time_point{};
79 TimePoint current_time_point{}; 80 TimePoint current_time_point = time_point.load(std::memory_order_acquire);
80
81 current_time_point.pack = Common::AtomicLoad128(time_point.pack.data());
82 do { 81 do {
83 const u64 current_measure = FencedRDTSC(); 82 const u64 current_measure = FencedRDTSC();
84 u64 diff = current_measure - current_time_point.inner.last_measure; 83 u64 diff = current_measure - current_time_point.last_measure;
85 diff = diff & ~static_cast<u64>(static_cast<s64>(diff) >> 63); // max(diff, 0) 84 diff = diff & ~static_cast<u64>(static_cast<s64>(diff) >> 63); // max(diff, 0)
86 new_time_point.inner.last_measure = current_measure > current_time_point.inner.last_measure 85 new_time_point.last_measure = current_measure > current_time_point.last_measure
87 ? current_measure 86 ? current_measure
88 : current_time_point.inner.last_measure; 87 : current_time_point.last_measure;
89 new_time_point.inner.accumulated_ticks = current_time_point.inner.accumulated_ticks + diff; 88 new_time_point.accumulated_ticks = current_time_point.accumulated_ticks + diff;
90 } while (!Common::AtomicCompareAndSwap(time_point.pack.data(), new_time_point.pack, 89 } while (!time_point.compare_exchange_weak(
91 current_time_point.pack, current_time_point.pack)); 90 current_time_point, new_time_point, std::memory_order_release, std::memory_order_acquire));
92 /// The clock cannot be more precise than the guest timer, remove the lower bits 91 /// The clock cannot be more precise than the guest timer, remove the lower bits
93 return new_time_point.inner.accumulated_ticks & inaccuracy_mask; 92 return new_time_point.accumulated_ticks & inaccuracy_mask;
94} 93}
95 94
96void NativeClock::Pause(bool is_paused) { 95void NativeClock::Pause(bool is_paused) {
97 if (!is_paused) { 96 if (!is_paused) {
98 TimePoint current_time_point{};
99 TimePoint new_time_point{}; 97 TimePoint new_time_point{};
100 98 TimePoint current_time_point = time_point.load(std::memory_order_acquire);
101 current_time_point.pack = Common::AtomicLoad128(time_point.pack.data());
102 do { 99 do {
103 new_time_point.pack = current_time_point.pack; 100 new_time_point = current_time_point;
104 new_time_point.inner.last_measure = FencedRDTSC(); 101 new_time_point.last_measure = FencedRDTSC();
105 } while (!Common::AtomicCompareAndSwap(time_point.pack.data(), new_time_point.pack, 102 } while (!time_point.compare_exchange_weak(current_time_point, new_time_point,
106 current_time_point.pack, current_time_point.pack)); 103 std::memory_order_release,
104 std::memory_order_acquire));
107 } 105 }
108} 106}
109 107
diff --git a/src/common/x64/native_clock.h b/src/common/x64/native_clock.h
index 30d2ba2e9..e57446cb9 100644
--- a/src/common/x64/native_clock.h
+++ b/src/common/x64/native_clock.h
@@ -3,6 +3,7 @@
3 3
4#pragma once 4#pragma once
5 5
6#include <atomic>
6#include "common/wall_clock.h" 7#include "common/wall_clock.h"
7 8
8namespace Common { 9namespace Common {
@@ -28,13 +29,9 @@ public:
28private: 29private:
29 u64 GetRTSC(); 30 u64 GetRTSC();
30 31
31 union alignas(16) TimePoint { 32 struct alignas(16) TimePoint {
32 TimePoint() : pack{} {} 33 u64 last_measure{};
33 u128 pack{}; 34 u64 accumulated_ticks{};
34 struct Inner {
35 u64 last_measure{};
36 u64 accumulated_ticks{};
37 } inner;
38 }; 35 };
39 36
40 /// value used to reduce the native clocks accuracy as some apss rely on 37 /// value used to reduce the native clocks accuracy as some apss rely on
@@ -42,7 +39,7 @@ private:
42 /// be higher. 39 /// be higher.
43 static constexpr u64 inaccuracy_mask = ~(UINT64_C(0x400) - 1); 40 static constexpr u64 inaccuracy_mask = ~(UINT64_C(0x400) - 1);
44 41
45 TimePoint time_point; 42 std::atomic<TimePoint> time_point;
46 // factors 43 // factors
47 u64 clock_rtsc_factor{}; 44 u64 clock_rtsc_factor{};
48 u64 cpu_rtsc_factor{}; 45 u64 cpu_rtsc_factor{};