summaryrefslogtreecommitdiff
path: root/src/common
diff options
context:
space:
mode:
Diffstat (limited to 'src/common')
-rw-r--r--src/common/announce_multiplayer_room.h2
-rw-r--r--src/common/fiber.cpp2
-rw-r--r--src/common/fixed_point.h2
-rw-r--r--src/common/host_memory.cpp4
-rw-r--r--src/common/input.h8
-rw-r--r--src/common/steady_clock.cpp25
-rw-r--r--src/common/steady_clock.h11
-rw-r--r--src/common/swap.h12
-rw-r--r--src/common/x64/native_clock.cpp38
-rw-r--r--src/common/x64/native_clock.h5
10 files changed, 87 insertions, 22 deletions
diff --git a/src/common/announce_multiplayer_room.h b/src/common/announce_multiplayer_room.h
index 4a3100fa4..f32060196 100644
--- a/src/common/announce_multiplayer_room.h
+++ b/src/common/announce_multiplayer_room.h
@@ -66,7 +66,7 @@ public:
66 * @param description The room description 66 * @param description The room description
67 * @param port The port of the room 67 * @param port The port of the room
68 * @param net_version The version of the libNetwork that gets used 68 * @param net_version The version of the libNetwork that gets used
69 * @param has_password True if the room is passowrd protected 69 * @param has_password True if the room is password protected
70 * @param preferred_game The preferred game of the room 70 * @param preferred_game The preferred game of the room
71 * @param preferred_game_id The title id of the preferred game 71 * @param preferred_game_id The title id of the preferred game
72 */ 72 */
diff --git a/src/common/fiber.cpp b/src/common/fiber.cpp
index bc92b360b..c991b7cf1 100644
--- a/src/common/fiber.cpp
+++ b/src/common/fiber.cpp
@@ -90,7 +90,7 @@ Fiber::~Fiber() {
90} 90}
91 91
92void Fiber::Exit() { 92void Fiber::Exit() {
93 ASSERT_MSG(impl->is_thread_fiber, "Exitting non main thread fiber"); 93 ASSERT_MSG(impl->is_thread_fiber, "Exiting non main thread fiber");
94 if (!impl->is_thread_fiber) { 94 if (!impl->is_thread_fiber) {
95 return; 95 return;
96 } 96 }
diff --git a/src/common/fixed_point.h b/src/common/fixed_point.h
index f899b0d54..b0f3ae2cc 100644
--- a/src/common/fixed_point.h
+++ b/src/common/fixed_point.h
@@ -22,7 +22,7 @@ class FixedPoint;
22namespace detail { 22namespace detail {
23 23
24// helper templates to make magic with types :) 24// helper templates to make magic with types :)
25// these allow us to determine resonable types from 25// these allow us to determine reasonable types from
26// a desired size, they also let us infer the next largest type 26// a desired size, they also let us infer the next largest type
27// from a type which is nice for the division op 27// from a type which is nice for the division op
28template <size_t T> 28template <size_t T>
diff --git a/src/common/host_memory.cpp b/src/common/host_memory.cpp
index 611c7d1a3..8e4f1f97a 100644
--- a/src/common/host_memory.cpp
+++ b/src/common/host_memory.cpp
@@ -322,7 +322,7 @@ private:
322 } 322 }
323 323
324 /// Return true when a given memory region is a "nieche" and the placeholders don't have to be 324 /// Return true when a given memory region is a "nieche" and the placeholders don't have to be
325 /// splitted. 325 /// split.
326 bool IsNiechePlaceholder(size_t virtual_offset, size_t length) const { 326 bool IsNiechePlaceholder(size_t virtual_offset, size_t length) const {
327 const auto it = placeholders.upper_bound({virtual_offset, virtual_offset + length}); 327 const auto it = placeholders.upper_bound({virtual_offset, virtual_offset + length});
328 if (it != placeholders.end() && it->lower() == virtual_offset + length) { 328 if (it != placeholders.end() && it->lower() == virtual_offset + length) {
@@ -484,7 +484,7 @@ class HostMemory::Impl {
484public: 484public:
485 explicit Impl(size_t /*backing_size */, size_t /* virtual_size */) { 485 explicit Impl(size_t /*backing_size */, size_t /* virtual_size */) {
486 // This is just a place holder. 486 // This is just a place holder.
487 // Please implement fastmem in a propper way on your platform. 487 // Please implement fastmem in a proper way on your platform.
488 throw std::bad_alloc{}; 488 throw std::bad_alloc{};
489 } 489 }
490 490
diff --git a/src/common/input.h b/src/common/input.h
index 98e934685..51b277c1f 100644
--- a/src/common/input.h
+++ b/src/common/input.h
@@ -15,7 +15,7 @@
15 15
16namespace Common::Input { 16namespace Common::Input {
17 17
18// Type of data that is expected to recieve or send 18// Type of data that is expected to receive or send
19enum class InputType { 19enum class InputType {
20 None, 20 None,
21 Battery, 21 Battery,
@@ -103,7 +103,7 @@ enum class VibrationAmplificationType {
103struct AnalogProperties { 103struct AnalogProperties {
104 // Anything below this value will be detected as zero 104 // Anything below this value will be detected as zero
105 float deadzone{}; 105 float deadzone{};
106 // Anyting above this values will be detected as one 106 // Anything above this values will be detected as one
107 float range{1.0f}; 107 float range{1.0f};
108 // Minimum value to be detected as active 108 // Minimum value to be detected as active
109 float threshold{0.5f}; 109 float threshold{0.5f};
@@ -209,7 +209,7 @@ struct LedStatus {
209 bool led_4{}; 209 bool led_4{};
210}; 210};
211 211
212// Raw data fom camera 212// Raw data from camera
213struct CameraStatus { 213struct CameraStatus {
214 CameraFormat format{CameraFormat::None}; 214 CameraFormat format{CameraFormat::None};
215 std::vector<u8> data{}; 215 std::vector<u8> data{};
@@ -428,7 +428,7 @@ inline void UnregisterOutputFactory(const std::string& name) {
428} 428}
429 429
430/** 430/**
431 * Create an input device from given paramters. 431 * Create an input device from given parameters.
432 * @tparam InputDeviceType the type of input devices to create 432 * @tparam InputDeviceType the type of input devices to create
433 * @param params a serialized ParamPackage string that contains all parameters for creating the 433 * @param params a serialized ParamPackage string that contains all parameters for creating the
434 * device 434 * device
diff --git a/src/common/steady_clock.cpp b/src/common/steady_clock.cpp
index 0d5908aa7..782859196 100644
--- a/src/common/steady_clock.cpp
+++ b/src/common/steady_clock.cpp
@@ -23,6 +23,19 @@ static s64 WindowsQueryPerformanceCounter() {
23 QueryPerformanceCounter(&counter); 23 QueryPerformanceCounter(&counter);
24 return counter.QuadPart; 24 return counter.QuadPart;
25} 25}
26
27static s64 GetSystemTimeNS() {
28 // GetSystemTimePreciseAsFileTime returns the file time in 100ns units.
29 static constexpr s64 Multiplier = 100;
30 // Convert Windows epoch to Unix epoch.
31 static constexpr s64 WindowsEpochToUnixEpochNS = 0x19DB1DED53E8000LL;
32
33 FILETIME filetime;
34 GetSystemTimePreciseAsFileTime(&filetime);
35 return Multiplier * ((static_cast<s64>(filetime.dwHighDateTime) << 32) +
36 static_cast<s64>(filetime.dwLowDateTime)) -
37 WindowsEpochToUnixEpochNS;
38}
26#endif 39#endif
27 40
28SteadyClock::time_point SteadyClock::Now() noexcept { 41SteadyClock::time_point SteadyClock::Now() noexcept {
@@ -53,4 +66,16 @@ SteadyClock::time_point SteadyClock::Now() noexcept {
53#endif 66#endif
54} 67}
55 68
69RealTimeClock::time_point RealTimeClock::Now() noexcept {
70#if defined(_WIN32)
71 return time_point{duration{GetSystemTimeNS()}};
72#elif defined(__APPLE__)
73 return time_point{duration{clock_gettime_nsec_np(CLOCK_REALTIME)}};
74#else
75 timespec ts;
76 clock_gettime(CLOCK_REALTIME, &ts);
77 return time_point{std::chrono::seconds{ts.tv_sec} + std::chrono::nanoseconds{ts.tv_nsec}};
78#endif
79}
80
56}; // namespace Common 81}; // namespace Common
diff --git a/src/common/steady_clock.h b/src/common/steady_clock.h
index 9497cf865..dbd0e2513 100644
--- a/src/common/steady_clock.h
+++ b/src/common/steady_clock.h
@@ -20,4 +20,15 @@ struct SteadyClock {
20 [[nodiscard]] static time_point Now() noexcept; 20 [[nodiscard]] static time_point Now() noexcept;
21}; 21};
22 22
23struct RealTimeClock {
24 using rep = s64;
25 using period = std::nano;
26 using duration = std::chrono::nanoseconds;
27 using time_point = std::chrono::time_point<RealTimeClock>;
28
29 static constexpr bool is_steady = false;
30
31 [[nodiscard]] static time_point Now() noexcept;
32};
33
23} // namespace Common 34} // namespace Common
diff --git a/src/common/swap.h b/src/common/swap.h
index 037b82781..085baaf9a 100644
--- a/src/common/swap.h
+++ b/src/common/swap.h
@@ -229,7 +229,7 @@ public:
229 value = swap(swap() - 1); 229 value = swap(swap() - 1);
230 return old; 230 return old;
231 } 231 }
232 // Comparaison 232 // Comparison
233 // v == i 233 // v == i
234 bool operator==(const swapped_t& i) const { 234 bool operator==(const swapped_t& i) const {
235 return swap() == i.swap(); 235 return swap() == i.swap();
@@ -368,7 +368,7 @@ public:
368 // Member 368 // Member
369 /** todo **/ 369 /** todo **/
370 370
371 // Arithmetics 371 // Arithmetic
372 template <typename S, typename T2, typename F2> 372 template <typename S, typename T2, typename F2>
373 friend S operator+(const S& p, const swapped_t v); 373 friend S operator+(const S& p, const swapped_t v);
374 374
@@ -384,7 +384,7 @@ public:
384 template <typename S, typename T2, typename F2> 384 template <typename S, typename T2, typename F2>
385 friend S operator%(const S& p, const swapped_t v); 385 friend S operator%(const S& p, const swapped_t v);
386 386
387 // Arithmetics + assignments 387 // Arithmetic + assignments
388 template <typename S, typename T2, typename F2> 388 template <typename S, typename T2, typename F2>
389 friend S operator+=(const S& p, const swapped_t v); 389 friend S operator+=(const S& p, const swapped_t v);
390 390
@@ -415,7 +415,7 @@ public:
415 friend bool operator==(const S& p, const swapped_t v); 415 friend bool operator==(const S& p, const swapped_t v);
416}; 416};
417 417
418// Arithmetics 418// Arithmetic
419template <typename S, typename T, typename F> 419template <typename S, typename T, typename F>
420S operator+(const S& i, const swap_struct_t<T, F> v) { 420S operator+(const S& i, const swap_struct_t<T, F> v) {
421 return i + v.swap(); 421 return i + v.swap();
@@ -441,7 +441,7 @@ S operator%(const S& i, const swap_struct_t<T, F> v) {
441 return i % v.swap(); 441 return i % v.swap();
442} 442}
443 443
444// Arithmetics + assignments 444// Arithmetic + assignments
445template <typename S, typename T, typename F> 445template <typename S, typename T, typename F>
446S& operator+=(S& i, const swap_struct_t<T, F> v) { 446S& operator+=(S& i, const swap_struct_t<T, F> v) {
447 i += v.swap(); 447 i += v.swap();
@@ -465,7 +465,7 @@ S operator&(const swap_struct_t<T, F> v, const S& i) {
465 return static_cast<S>(v.swap() & i); 465 return static_cast<S>(v.swap() & i);
466} 466}
467 467
468// Comparaison 468// Comparison
469template <typename S, typename T, typename F> 469template <typename S, typename T, typename F>
470bool operator<(const S& p, const swap_struct_t<T, F> v) { 470bool operator<(const S& p, const swap_struct_t<T, F> v) {
471 return p < v.swap(); 471 return p < v.swap();
diff --git a/src/common/x64/native_clock.cpp b/src/common/x64/native_clock.cpp
index bc1a973b0..76c66e7ee 100644
--- a/src/common/x64/native_clock.cpp
+++ b/src/common/x64/native_clock.cpp
@@ -53,11 +53,11 @@ u64 EstimateRDTSCFrequency() {
53 FencedRDTSC(); 53 FencedRDTSC();
54 54
55 // Get the current time. 55 // Get the current time.
56 const auto start_time = Common::SteadyClock::Now(); 56 const auto start_time = Common::RealTimeClock::Now();
57 const u64 tsc_start = FencedRDTSC(); 57 const u64 tsc_start = FencedRDTSC();
58 // Wait for 250 milliseconds. 58 // Wait for 250 milliseconds.
59 std::this_thread::sleep_for(std::chrono::milliseconds{250}); 59 std::this_thread::sleep_for(std::chrono::milliseconds{250});
60 const auto end_time = Common::SteadyClock::Now(); 60 const auto end_time = Common::RealTimeClock::Now();
61 const u64 tsc_end = FencedRDTSC(); 61 const u64 tsc_end = FencedRDTSC();
62 // Calculate differences. 62 // Calculate differences.
63 const u64 timer_diff = static_cast<u64>( 63 const u64 timer_diff = static_cast<u64>(
@@ -72,13 +72,29 @@ NativeClock::NativeClock(u64 emulated_cpu_frequency_, u64 emulated_clock_frequen
72 u64 rtsc_frequency_) 72 u64 rtsc_frequency_)
73 : WallClock(emulated_cpu_frequency_, emulated_clock_frequency_, true), rtsc_frequency{ 73 : WallClock(emulated_cpu_frequency_, emulated_clock_frequency_, true), rtsc_frequency{
74 rtsc_frequency_} { 74 rtsc_frequency_} {
75 // Thread to re-adjust the RDTSC frequency after 10 seconds has elapsed.
76 time_sync_thread = std::jthread{[this](std::stop_token token) {
77 // Get the current time.
78 const auto start_time = Common::RealTimeClock::Now();
79 const u64 tsc_start = FencedRDTSC();
80 // Wait for 10 seconds.
81 if (!Common::StoppableTimedWait(token, std::chrono::seconds{10})) {
82 return;
83 }
84 const auto end_time = Common::RealTimeClock::Now();
85 const u64 tsc_end = FencedRDTSC();
86 // Calculate differences.
87 const u64 timer_diff = static_cast<u64>(
88 std::chrono::duration_cast<std::chrono::nanoseconds>(end_time - start_time).count());
89 const u64 tsc_diff = tsc_end - tsc_start;
90 const u64 tsc_freq = MultiplyAndDivide64(tsc_diff, 1000000000ULL, timer_diff);
91 rtsc_frequency = tsc_freq;
92 CalculateAndSetFactors();
93 }};
94
75 time_point.inner.last_measure = FencedRDTSC(); 95 time_point.inner.last_measure = FencedRDTSC();
76 time_point.inner.accumulated_ticks = 0U; 96 time_point.inner.accumulated_ticks = 0U;
77 ns_rtsc_factor = GetFixedPoint64Factor(NS_RATIO, rtsc_frequency); 97 CalculateAndSetFactors();
78 us_rtsc_factor = GetFixedPoint64Factor(US_RATIO, rtsc_frequency);
79 ms_rtsc_factor = GetFixedPoint64Factor(MS_RATIO, rtsc_frequency);
80 clock_rtsc_factor = GetFixedPoint64Factor(emulated_clock_frequency, rtsc_frequency);
81 cpu_rtsc_factor = GetFixedPoint64Factor(emulated_cpu_frequency, rtsc_frequency);
82} 98}
83 99
84u64 NativeClock::GetRTSC() { 100u64 NativeClock::GetRTSC() {
@@ -138,6 +154,14 @@ u64 NativeClock::GetCPUCycles() {
138 return MultiplyHigh(rtsc_value, cpu_rtsc_factor); 154 return MultiplyHigh(rtsc_value, cpu_rtsc_factor);
139} 155}
140 156
157void NativeClock::CalculateAndSetFactors() {
158 ns_rtsc_factor = GetFixedPoint64Factor(NS_RATIO, rtsc_frequency);
159 us_rtsc_factor = GetFixedPoint64Factor(US_RATIO, rtsc_frequency);
160 ms_rtsc_factor = GetFixedPoint64Factor(MS_RATIO, rtsc_frequency);
161 clock_rtsc_factor = GetFixedPoint64Factor(emulated_clock_frequency, rtsc_frequency);
162 cpu_rtsc_factor = GetFixedPoint64Factor(emulated_cpu_frequency, rtsc_frequency);
163}
164
141} // namespace X64 165} // namespace X64
142 166
143} // namespace Common 167} // namespace Common
diff --git a/src/common/x64/native_clock.h b/src/common/x64/native_clock.h
index 38ae7a462..03ca291d8 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 "common/polyfill_thread.h"
6#include "common/wall_clock.h" 7#include "common/wall_clock.h"
7 8
8namespace Common { 9namespace Common {
@@ -28,6 +29,8 @@ public:
28private: 29private:
29 u64 GetRTSC(); 30 u64 GetRTSC();
30 31
32 void CalculateAndSetFactors();
33
31 union alignas(16) TimePoint { 34 union alignas(16) TimePoint {
32 TimePoint() : pack{} {} 35 TimePoint() : pack{} {}
33 u128 pack{}; 36 u128 pack{};
@@ -47,6 +50,8 @@ private:
47 u64 ms_rtsc_factor{}; 50 u64 ms_rtsc_factor{};
48 51
49 u64 rtsc_frequency; 52 u64 rtsc_frequency;
53
54 std::jthread time_sync_thread;
50}; 55};
51} // namespace X64 56} // namespace X64
52 57