diff options
Diffstat (limited to 'src/common')
| -rw-r--r-- | src/common/announce_multiplayer_room.h | 2 | ||||
| -rw-r--r-- | src/common/fiber.cpp | 2 | ||||
| -rw-r--r-- | src/common/fixed_point.h | 2 | ||||
| -rw-r--r-- | src/common/host_memory.cpp | 4 | ||||
| -rw-r--r-- | src/common/input.h | 8 | ||||
| -rw-r--r-- | src/common/steady_clock.cpp | 25 | ||||
| -rw-r--r-- | src/common/steady_clock.h | 11 | ||||
| -rw-r--r-- | src/common/swap.h | 12 | ||||
| -rw-r--r-- | src/common/x64/native_clock.cpp | 38 | ||||
| -rw-r--r-- | src/common/x64/native_clock.h | 5 |
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 | ||
| 92 | void Fiber::Exit() { | 92 | void 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; | |||
| 22 | namespace detail { | 22 | namespace 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 |
| 28 | template <size_t T> | 28 | template <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 { | |||
| 484 | public: | 484 | public: |
| 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 | ||
| 16 | namespace Common::Input { | 16 | namespace 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 |
| 19 | enum class InputType { | 19 | enum class InputType { |
| 20 | None, | 20 | None, |
| 21 | Battery, | 21 | Battery, |
| @@ -103,7 +103,7 @@ enum class VibrationAmplificationType { | |||
| 103 | struct AnalogProperties { | 103 | struct 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 |
| 213 | struct CameraStatus { | 213 | struct 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 | |||
| 27 | static 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 | ||
| 28 | SteadyClock::time_point SteadyClock::Now() noexcept { | 41 | SteadyClock::time_point SteadyClock::Now() noexcept { |
| @@ -53,4 +66,16 @@ SteadyClock::time_point SteadyClock::Now() noexcept { | |||
| 53 | #endif | 66 | #endif |
| 54 | } | 67 | } |
| 55 | 68 | ||
| 69 | RealTimeClock::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 | ||
| 23 | struct 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 |
| 419 | template <typename S, typename T, typename F> | 419 | template <typename S, typename T, typename F> |
| 420 | S operator+(const S& i, const swap_struct_t<T, F> v) { | 420 | S 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 |
| 445 | template <typename S, typename T, typename F> | 445 | template <typename S, typename T, typename F> |
| 446 | S& operator+=(S& i, const swap_struct_t<T, F> v) { | 446 | S& 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 |
| 469 | template <typename S, typename T, typename F> | 469 | template <typename S, typename T, typename F> |
| 470 | bool operator<(const S& p, const swap_struct_t<T, F> v) { | 470 | bool 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 | ||
| 84 | u64 NativeClock::GetRTSC() { | 100 | u64 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 | ||
| 157 | void 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 | ||
| 8 | namespace Common { | 9 | namespace Common { |
| @@ -28,6 +29,8 @@ public: | |||
| 28 | private: | 29 | private: |
| 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 | ||