summaryrefslogtreecommitdiff
path: root/src/common
diff options
context:
space:
mode:
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/common_types.h1
-rw-r--r--src/common/fs/file.h2
-rw-r--r--src/common/memory_detect.h2
-rw-r--r--src/common/overflow.h18
-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
13 files changed, 90 insertions, 80 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/common_types.h b/src/common/common_types.h
index 0fc225aff..ae04c4d60 100644
--- a/src/common/common_types.h
+++ b/src/common/common_types.h
@@ -45,6 +45,7 @@ using f32 = float; ///< 32-bit floating point
45using f64 = double; ///< 64-bit floating point 45using f64 = double; ///< 64-bit floating point
46 46
47using VAddr = u64; ///< Represents a pointer in the userspace virtual address space. 47using VAddr = u64; ///< Represents a pointer in the userspace virtual address space.
48using DAddr = u64; ///< Represents a pointer in the device specific virtual address space.
48using PAddr = u64; ///< Represents a pointer in the ARM11 physical address space. 49using PAddr = u64; ///< Represents a pointer in the ARM11 physical address space.
49using GPUVAddr = u64; ///< Represents a pointer in the GPU virtual address space. 50using GPUVAddr = u64; ///< Represents a pointer in the GPU virtual address space.
50 51
diff --git a/src/common/fs/file.h b/src/common/fs/file.h
index 167c4d826..2e2396075 100644
--- a/src/common/fs/file.h
+++ b/src/common/fs/file.h
@@ -37,7 +37,7 @@ void OpenFileStream(FileStream& file_stream, const std::filesystem::path& path,
37template <typename FileStream, typename Path> 37template <typename FileStream, typename Path>
38void OpenFileStream(FileStream& file_stream, const Path& path, std::ios_base::openmode open_mode) { 38void OpenFileStream(FileStream& file_stream, const Path& path, std::ios_base::openmode open_mode) {
39 if constexpr (IsChar<typename Path::value_type>) { 39 if constexpr (IsChar<typename Path::value_type>) {
40 file_stream.open(ToU8String(path), open_mode); 40 file_stream.open(std::filesystem::path{ToU8String(path)}, open_mode);
41 } else { 41 } else {
42 file_stream.open(std::filesystem::path{path}, open_mode); 42 file_stream.open(std::filesystem::path{path}, open_mode);
43 } 43 }
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/overflow.h b/src/common/overflow.h
index 44d8e7e73..e184ead95 100644
--- a/src/common/overflow.h
+++ b/src/common/overflow.h
@@ -3,6 +3,7 @@
3 3
4#pragma once 4#pragma once
5 5
6#include <algorithm>
6#include <type_traits> 7#include <type_traits>
7#include "bit_cast.h" 8#include "bit_cast.h"
8 9
@@ -19,4 +20,21 @@ inline T WrappingAdd(T lhs, T rhs) {
19 return BitCast<T>(lhs_u + rhs_u); 20 return BitCast<T>(lhs_u + rhs_u);
20} 21}
21 22
23template <typename T>
24 requires(std::is_integral_v<T> && std::is_signed_v<T>)
25inline bool CanAddWithoutOverflow(T lhs, T rhs) {
26#ifdef _MSC_VER
27 if (lhs >= 0 && rhs >= 0) {
28 return WrappingAdd(lhs, rhs) >= std::max(lhs, rhs);
29 } else if (lhs < 0 && rhs < 0) {
30 return WrappingAdd(lhs, rhs) <= std::min(lhs, rhs);
31 } else {
32 return true;
33 }
34#else
35 T res;
36 return !__builtin_add_overflow(lhs, rhs, &res);
37#endif
38}
39
22} // namespace Common 40} // 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;