summaryrefslogtreecommitdiff
path: root/src/common
diff options
context:
space:
mode:
authorGravatar Kelebek12023-10-29 13:50:55 +0000
committerGravatar Kelebek12024-01-24 04:26:55 +0000
commite4915fb7d2077584a11a15141bc81d28ed2b0125 (patch)
tree1783055dc2e98eaf9099e8e7b194b55f8f607747 /src/common
parentMerge pull request #12678 from german77/settings_impl (diff)
downloadyuzu-e4915fb7d2077584a11a15141bc81d28ed2b0125.tar.gz
yuzu-e4915fb7d2077584a11a15141bc81d28ed2b0125.tar.xz
yuzu-e4915fb7d2077584a11a15141bc81d28ed2b0125.zip
Rework time service to fix time passing offline.
Diffstat (limited to 'src/common')
-rw-r--r--src/common/arm64/native_clock.cpp24
-rw-r--r--src/common/arm64/native_clock.h10
-rw-r--r--src/common/memory_detect.h2
-rw-r--r--src/common/settings.h13
-rw-r--r--src/common/time_zone.cpp12
-rw-r--r--src/common/uuid.h12
-rw-r--r--src/common/wall_clock.cpp32
-rw-r--r--src/common/wall_clock.h9
-rw-r--r--src/common/x64/native_clock.cpp26
-rw-r--r--src/common/x64/native_clock.h9
10 files changed, 70 insertions, 79 deletions
diff --git a/src/common/arm64/native_clock.cpp b/src/common/arm64/native_clock.cpp
index f437d7187..76ffb74ba 100644
--- a/src/common/arm64/native_clock.cpp
+++ b/src/common/arm64/native_clock.cpp
@@ -30,27 +30,27 @@ NativeClock::NativeClock() {
30} 30}
31 31
32std::chrono::nanoseconds NativeClock::GetTimeNS() const { 32std::chrono::nanoseconds NativeClock::GetTimeNS() const {
33 return std::chrono::nanoseconds{MultiplyHigh(GetHostTicksElapsed(), ns_cntfrq_factor)}; 33 return std::chrono::nanoseconds{MultiplyHigh(GetUptime(), ns_cntfrq_factor)};
34} 34}
35 35
36std::chrono::microseconds NativeClock::GetTimeUS() const { 36std::chrono::microseconds NativeClock::GetTimeUS() const {
37 return std::chrono::microseconds{MultiplyHigh(GetHostTicksElapsed(), us_cntfrq_factor)}; 37 return std::chrono::microseconds{MultiplyHigh(GetUptime(), us_cntfrq_factor)};
38} 38}
39 39
40std::chrono::milliseconds NativeClock::GetTimeMS() const { 40std::chrono::milliseconds NativeClock::GetTimeMS() const {
41 return std::chrono::milliseconds{MultiplyHigh(GetHostTicksElapsed(), ms_cntfrq_factor)}; 41 return std::chrono::milliseconds{MultiplyHigh(GetUptime(), ms_cntfrq_factor)};
42} 42}
43 43
44u64 NativeClock::GetCNTPCT() const { 44s64 NativeClock::GetCNTPCT() const {
45 return MultiplyHigh(GetHostTicksElapsed(), guest_cntfrq_factor); 45 return MultiplyHigh(GetUptime(), guest_cntfrq_factor);
46} 46}
47 47
48u64 NativeClock::GetGPUTick() const { 48s64 NativeClock::GetGPUTick() const {
49 return MultiplyHigh(GetHostTicksElapsed(), gputick_cntfrq_factor); 49 return MultiplyHigh(GetUptime(), gputick_cntfrq_factor);
50} 50}
51 51
52u64 NativeClock::GetHostTicksNow() const { 52s64 NativeClock::GetUptime() const {
53 u64 cntvct_el0 = 0; 53 s64 cntvct_el0 = 0;
54 asm volatile("dsb ish\n\t" 54 asm volatile("dsb ish\n\t"
55 "mrs %[cntvct_el0], cntvct_el0\n\t" 55 "mrs %[cntvct_el0], cntvct_el0\n\t"
56 "dsb ish\n\t" 56 "dsb ish\n\t"
@@ -58,15 +58,11 @@ u64 NativeClock::GetHostTicksNow() const {
58 return cntvct_el0; 58 return cntvct_el0;
59} 59}
60 60
61u64 NativeClock::GetHostTicksElapsed() const {
62 return GetHostTicksNow();
63}
64
65bool NativeClock::IsNative() const { 61bool NativeClock::IsNative() const {
66 return true; 62 return true;
67} 63}
68 64
69u64 NativeClock::GetHostCNTFRQ() { 65s64 NativeClock::GetHostCNTFRQ() {
70 u64 cntfrq_el0 = 0; 66 u64 cntfrq_el0 = 0;
71 std::string_view board{""}; 67 std::string_view board{""};
72#ifdef ANDROID 68#ifdef ANDROID
diff --git a/src/common/arm64/native_clock.h b/src/common/arm64/native_clock.h
index a28b419f2..94bc1882e 100644
--- a/src/common/arm64/native_clock.h
+++ b/src/common/arm64/native_clock.h
@@ -17,17 +17,15 @@ public:
17 17
18 std::chrono::milliseconds GetTimeMS() const override; 18 std::chrono::milliseconds GetTimeMS() const override;
19 19
20 u64 GetCNTPCT() const override; 20 s64 GetCNTPCT() const override;
21 21
22 u64 GetGPUTick() const override; 22 s64 GetGPUTick() const override;
23 23
24 u64 GetHostTicksNow() const override; 24 s64 GetUptime() const override;
25
26 u64 GetHostTicksElapsed() const override;
27 25
28 bool IsNative() const override; 26 bool IsNative() const override;
29 27
30 static u64 GetHostCNTFRQ(); 28 static s64 GetHostCNTFRQ();
31 29
32public: 30public:
33 using FactorType = unsigned __int128; 31 using FactorType = unsigned __int128;
diff --git a/src/common/memory_detect.h b/src/common/memory_detect.h
index a345e6d28..c8f239aed 100644
--- a/src/common/memory_detect.h
+++ b/src/common/memory_detect.h
@@ -18,4 +18,4 @@ struct MemoryInfo {
18 */ 18 */
19[[nodiscard]] const MemoryInfo& GetMemInfo(); 19[[nodiscard]] const MemoryInfo& GetMemInfo();
20 20
21} // namespace Common \ No newline at end of file 21} // namespace Common
diff --git a/src/common/settings.h b/src/common/settings.h
index 07dba53ab..16749ab68 100644
--- a/src/common/settings.h
+++ b/src/common/settings.h
@@ -419,9 +419,16 @@ struct Values {
419 linkage, false, "custom_rtc_enabled", Category::System, Specialization::Paired, true, true}; 419 linkage, false, "custom_rtc_enabled", Category::System, Specialization::Paired, true, true};
420 SwitchableSetting<s64> custom_rtc{ 420 SwitchableSetting<s64> custom_rtc{
421 linkage, 0, "custom_rtc", Category::System, Specialization::Time, 421 linkage, 0, "custom_rtc", Category::System, Specialization::Time,
422 true, true, &custom_rtc_enabled}; 422 false, true, &custom_rtc_enabled};
423 // Set on game boot, reset on stop. Seconds difference between current time and `custom_rtc` 423 SwitchableSetting<s64, true> custom_rtc_offset{linkage,
424 s64 custom_rtc_differential; 424 0,
425 std::numeric_limits<int>::min(),
426 std::numeric_limits<int>::max(),
427 "custom_rtc_offset",
428 Category::System,
429 Specialization::Countable,
430 true,
431 true};
425 SwitchableSetting<bool> rng_seed_enabled{ 432 SwitchableSetting<bool> rng_seed_enabled{
426 linkage, false, "rng_seed_enabled", Category::System, Specialization::Paired, true, true}; 433 linkage, false, "rng_seed_enabled", Category::System, Specialization::Paired, true, true};
427 SwitchableSetting<u32> rng_seed{ 434 SwitchableSetting<u32> rng_seed{
diff --git a/src/common/time_zone.cpp b/src/common/time_zone.cpp
index 69e728a9d..f77df604f 100644
--- a/src/common/time_zone.cpp
+++ b/src/common/time_zone.cpp
@@ -88,7 +88,17 @@ std::string FindSystemTimeZone() {
88 LOG_ERROR(Common, "Time zone {} not handled, defaulting to hour offset.", tz_index); 88 LOG_ERROR(Common, "Time zone {} not handled, defaulting to hour offset.", tz_index);
89 } 89 }
90 } 90 }
91 return fmt::format("Etc/GMT{:s}{:d}", hours > 0 ? "-" : "+", std::abs(hours)); 91
92 // For some reason the Etc/GMT times are reversed. GMT+6 contains -21600 as its offset,
93 // -6 hours instead of +6 hours, so these signs are purposefully reversed to fix it.
94 std::string postfix{""};
95 if (hours > 0) {
96 postfix = fmt::format("-{:d}", std::abs(hours));
97 } else if (hours < 0) {
98 postfix = fmt::format("+{:d}", std::abs(hours));
99 }
100
101 return fmt::format("Etc/GMT{:s}", postfix);
92} 102}
93 103
94} // namespace Common::TimeZone 104} // namespace Common::TimeZone
diff --git a/src/common/uuid.h b/src/common/uuid.h
index 7172ca165..81bfefbbb 100644
--- a/src/common/uuid.h
+++ b/src/common/uuid.h
@@ -12,9 +12,8 @@
12namespace Common { 12namespace Common {
13 13
14struct UUID { 14struct UUID {
15 std::array<u8, 0x10> uuid{}; 15 std::array<u8, 0x10> uuid;
16 16
17 /// Constructs an invalid UUID.
18 constexpr UUID() = default; 17 constexpr UUID() = default;
19 18
20 /// Constructs a UUID from a reference to a 128 bit array. 19 /// Constructs a UUID from a reference to a 128 bit array.
@@ -34,14 +33,6 @@ struct UUID {
34 */ 33 */
35 explicit UUID(std::string_view uuid_string); 34 explicit UUID(std::string_view uuid_string);
36 35
37 ~UUID() = default;
38
39 constexpr UUID(const UUID&) noexcept = default;
40 constexpr UUID(UUID&&) noexcept = default;
41
42 constexpr UUID& operator=(const UUID&) noexcept = default;
43 constexpr UUID& operator=(UUID&&) noexcept = default;
44
45 /** 36 /**
46 * Returns whether the stored UUID is valid or not. 37 * Returns whether the stored UUID is valid or not.
47 * 38 *
@@ -121,6 +112,7 @@ struct UUID {
121 friend constexpr bool operator==(const UUID& lhs, const UUID& rhs) = default; 112 friend constexpr bool operator==(const UUID& lhs, const UUID& rhs) = default;
122}; 113};
123static_assert(sizeof(UUID) == 0x10, "UUID has incorrect size."); 114static_assert(sizeof(UUID) == 0x10, "UUID has incorrect size.");
115static_assert(std::is_trivial_v<UUID>);
124 116
125/// An invalid UUID. This UUID has all its bytes set to 0. 117/// An invalid UUID. This UUID has all its bytes set to 0.
126constexpr UUID InvalidUUID = {}; 118constexpr UUID InvalidUUID = {};
diff --git a/src/common/wall_clock.cpp b/src/common/wall_clock.cpp
index 012fdc1e0..e14bf3e65 100644
--- a/src/common/wall_clock.cpp
+++ b/src/common/wall_clock.cpp
@@ -18,42 +18,40 @@ namespace Common {
18 18
19class StandardWallClock final : public WallClock { 19class StandardWallClock final : public WallClock {
20public: 20public:
21 explicit StandardWallClock() : start_time{SteadyClock::Now()} {} 21 explicit StandardWallClock() {}
22 22
23 std::chrono::nanoseconds GetTimeNS() const override { 23 std::chrono::nanoseconds GetTimeNS() const override {
24 return SteadyClock::Now() - start_time; 24 return std::chrono::duration_cast<std::chrono::nanoseconds>(
25 std::chrono::system_clock::now().time_since_epoch());
25 } 26 }
26 27
27 std::chrono::microseconds GetTimeUS() const override { 28 std::chrono::microseconds GetTimeUS() const override {
28 return static_cast<std::chrono::microseconds>(GetHostTicksElapsed() / NsToUsRatio::den); 29 return std::chrono::duration_cast<std::chrono::microseconds>(
30 std::chrono::system_clock::now().time_since_epoch());
29 } 31 }
30 32
31 std::chrono::milliseconds GetTimeMS() const override { 33 std::chrono::milliseconds GetTimeMS() const override {
32 return static_cast<std::chrono::milliseconds>(GetHostTicksElapsed() / NsToMsRatio::den); 34 return std::chrono::duration_cast<std::chrono::milliseconds>(
35 std::chrono::system_clock::now().time_since_epoch());
33 } 36 }
34 37
35 u64 GetCNTPCT() const override { 38 s64 GetCNTPCT() const override {
36 return GetHostTicksElapsed() * NsToCNTPCTRatio::num / NsToCNTPCTRatio::den; 39 return GetUptime() * NsToCNTPCTRatio::num / NsToCNTPCTRatio::den;
37 } 40 }
38 41
39 u64 GetGPUTick() const override { 42 s64 GetGPUTick() const override {
40 return GetHostTicksElapsed() * NsToGPUTickRatio::num / NsToGPUTickRatio::den; 43 return GetUptime() * NsToGPUTickRatio::num / NsToGPUTickRatio::den;
41 } 44 }
42 45
43 u64 GetHostTicksNow() const override { 46 s64 GetUptime() const override {
44 return static_cast<u64>(SteadyClock::Now().time_since_epoch().count()); 47 return std::chrono::duration_cast<std::chrono::nanoseconds>(
45 } 48 std::chrono::steady_clock::now().time_since_epoch())
46 49 .count();
47 u64 GetHostTicksElapsed() const override {
48 return static_cast<u64>(GetTimeNS().count());
49 } 50 }
50 51
51 bool IsNative() const override { 52 bool IsNative() const override {
52 return false; 53 return false;
53 } 54 }
54
55private:
56 SteadyClock::time_point start_time;
57}; 55};
58 56
59std::unique_ptr<WallClock> CreateOptimalClock() { 57std::unique_ptr<WallClock> CreateOptimalClock() {
diff --git a/src/common/wall_clock.h b/src/common/wall_clock.h
index f45d3d8c5..3a0c43909 100644
--- a/src/common/wall_clock.h
+++ b/src/common/wall_clock.h
@@ -29,16 +29,13 @@ public:
29 virtual std::chrono::milliseconds GetTimeMS() const = 0; 29 virtual std::chrono::milliseconds GetTimeMS() const = 0;
30 30
31 /// @returns The guest CNTPCT ticks since the construction of this clock. 31 /// @returns The guest CNTPCT ticks since the construction of this clock.
32 virtual u64 GetCNTPCT() const = 0; 32 virtual s64 GetCNTPCT() const = 0;
33 33
34 /// @returns The guest GPU ticks since the construction of this clock. 34 /// @returns The guest GPU ticks since the construction of this clock.
35 virtual u64 GetGPUTick() const = 0; 35 virtual s64 GetGPUTick() const = 0;
36 36
37 /// @returns The raw host timer ticks since an indeterminate epoch. 37 /// @returns The raw host timer ticks since an indeterminate epoch.
38 virtual u64 GetHostTicksNow() const = 0; 38 virtual s64 GetUptime() const = 0;
39
40 /// @returns The raw host timer ticks since the construction of this clock.
41 virtual u64 GetHostTicksElapsed() const = 0;
42 39
43 /// @returns Whether the clock directly uses the host's hardware clock. 40 /// @returns Whether the clock directly uses the host's hardware clock.
44 virtual bool IsNative() const = 0; 41 virtual bool IsNative() const = 0;
diff --git a/src/common/x64/native_clock.cpp b/src/common/x64/native_clock.cpp
index 7d2a26bd9..d2d27fafe 100644
--- a/src/common/x64/native_clock.cpp
+++ b/src/common/x64/native_clock.cpp
@@ -8,39 +8,35 @@
8namespace Common::X64 { 8namespace Common::X64 {
9 9
10NativeClock::NativeClock(u64 rdtsc_frequency_) 10NativeClock::NativeClock(u64 rdtsc_frequency_)
11 : start_ticks{FencedRDTSC()}, rdtsc_frequency{rdtsc_frequency_}, 11 : rdtsc_frequency{rdtsc_frequency_}, ns_rdtsc_factor{GetFixedPoint64Factor(NsRatio::den,
12 ns_rdtsc_factor{GetFixedPoint64Factor(NsRatio::den, rdtsc_frequency)}, 12 rdtsc_frequency)},
13 us_rdtsc_factor{GetFixedPoint64Factor(UsRatio::den, rdtsc_frequency)}, 13 us_rdtsc_factor{GetFixedPoint64Factor(UsRatio::den, rdtsc_frequency)},
14 ms_rdtsc_factor{GetFixedPoint64Factor(MsRatio::den, rdtsc_frequency)}, 14 ms_rdtsc_factor{GetFixedPoint64Factor(MsRatio::den, rdtsc_frequency)},
15 cntpct_rdtsc_factor{GetFixedPoint64Factor(CNTFRQ, rdtsc_frequency)}, 15 cntpct_rdtsc_factor{GetFixedPoint64Factor(CNTFRQ, rdtsc_frequency)},
16 gputick_rdtsc_factor{GetFixedPoint64Factor(GPUTickFreq, rdtsc_frequency)} {} 16 gputick_rdtsc_factor{GetFixedPoint64Factor(GPUTickFreq, rdtsc_frequency)} {}
17 17
18std::chrono::nanoseconds NativeClock::GetTimeNS() const { 18std::chrono::nanoseconds NativeClock::GetTimeNS() const {
19 return std::chrono::nanoseconds{MultiplyHigh(GetHostTicksElapsed(), ns_rdtsc_factor)}; 19 return std::chrono::nanoseconds{MultiplyHigh(GetUptime(), ns_rdtsc_factor)};
20} 20}
21 21
22std::chrono::microseconds NativeClock::GetTimeUS() const { 22std::chrono::microseconds NativeClock::GetTimeUS() const {
23 return std::chrono::microseconds{MultiplyHigh(GetHostTicksElapsed(), us_rdtsc_factor)}; 23 return std::chrono::microseconds{MultiplyHigh(GetUptime(), us_rdtsc_factor)};
24} 24}
25 25
26std::chrono::milliseconds NativeClock::GetTimeMS() const { 26std::chrono::milliseconds NativeClock::GetTimeMS() const {
27 return std::chrono::milliseconds{MultiplyHigh(GetHostTicksElapsed(), ms_rdtsc_factor)}; 27 return std::chrono::milliseconds{MultiplyHigh(GetUptime(), ms_rdtsc_factor)};
28} 28}
29 29
30u64 NativeClock::GetCNTPCT() const { 30s64 NativeClock::GetCNTPCT() const {
31 return MultiplyHigh(GetHostTicksElapsed(), cntpct_rdtsc_factor); 31 return MultiplyHigh(GetUptime(), cntpct_rdtsc_factor);
32} 32}
33 33
34u64 NativeClock::GetGPUTick() const { 34s64 NativeClock::GetGPUTick() const {
35 return MultiplyHigh(GetHostTicksElapsed(), gputick_rdtsc_factor); 35 return MultiplyHigh(GetUptime(), gputick_rdtsc_factor);
36} 36}
37 37
38u64 NativeClock::GetHostTicksNow() const { 38s64 NativeClock::GetUptime() const {
39 return FencedRDTSC(); 39 return static_cast<s64>(FencedRDTSC());
40}
41
42u64 NativeClock::GetHostTicksElapsed() const {
43 return FencedRDTSC() - start_ticks;
44} 40}
45 41
46bool NativeClock::IsNative() const { 42bool NativeClock::IsNative() const {
diff --git a/src/common/x64/native_clock.h b/src/common/x64/native_clock.h
index 334415eff..b2629b031 100644
--- a/src/common/x64/native_clock.h
+++ b/src/common/x64/native_clock.h
@@ -17,18 +17,15 @@ public:
17 17
18 std::chrono::milliseconds GetTimeMS() const override; 18 std::chrono::milliseconds GetTimeMS() const override;
19 19
20 u64 GetCNTPCT() const override; 20 s64 GetCNTPCT() const override;
21 21
22 u64 GetGPUTick() const override; 22 s64 GetGPUTick() const override;
23 23
24 u64 GetHostTicksNow() const override; 24 s64 GetUptime() const override;
25
26 u64 GetHostTicksElapsed() const override;
27 25
28 bool IsNative() const override; 26 bool IsNative() const override;
29 27
30private: 28private:
31 u64 start_ticks;
32 u64 rdtsc_frequency; 29 u64 rdtsc_frequency;
33 30
34 u64 ns_rdtsc_factor; 31 u64 ns_rdtsc_factor;