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: * @param description The room description * @param port The port of the room * @param net_version The version of the libNetwork that gets used - * @param has_password True if the room is passowrd protected + * @param has_password True if the room is password protected * @param preferred_game The preferred game of the room * @param preferred_game_id The title id of the preferred game */ 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() { } void Fiber::Exit() { - ASSERT_MSG(impl->is_thread_fiber, "Exitting non main thread fiber"); + ASSERT_MSG(impl->is_thread_fiber, "Exiting non main thread fiber"); if (!impl->is_thread_fiber) { return; } 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; namespace detail { // helper templates to make magic with types :) -// these allow us to determine resonable types from +// these allow us to determine reasonable types from // a desired size, they also let us infer the next largest type // from a type which is nice for the division op 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: } /// Return true when a given memory region is a "nieche" and the placeholders don't have to be - /// splitted. + /// split. bool IsNiechePlaceholder(size_t virtual_offset, size_t length) const { const auto it = placeholders.upper_bound({virtual_offset, virtual_offset + length}); if (it != placeholders.end() && it->lower() == virtual_offset + length) { @@ -484,7 +484,7 @@ class HostMemory::Impl { public: explicit Impl(size_t /*backing_size */, size_t /* virtual_size */) { // This is just a place holder. - // Please implement fastmem in a propper way on your platform. + // Please implement fastmem in a proper way on your platform. throw std::bad_alloc{}; } 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 @@ namespace Common::Input { -// Type of data that is expected to recieve or send +// Type of data that is expected to receive or send enum class InputType { None, Battery, @@ -103,7 +103,7 @@ enum class VibrationAmplificationType { struct AnalogProperties { // Anything below this value will be detected as zero float deadzone{}; - // Anyting above this values will be detected as one + // Anything above this values will be detected as one float range{1.0f}; // Minimum value to be detected as active float threshold{0.5f}; @@ -209,7 +209,7 @@ struct LedStatus { bool led_4{}; }; -// Raw data fom camera +// Raw data from camera struct CameraStatus { CameraFormat format{CameraFormat::None}; std::vector<u8> data{}; @@ -428,7 +428,7 @@ inline void UnregisterOutputFactory(const std::string& name) { } /** - * Create an input device from given paramters. + * Create an input device from given parameters. * @tparam InputDeviceType the type of input devices to create * @param params a serialized ParamPackage string that contains all parameters for creating the * 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() { QueryPerformanceCounter(&counter); return counter.QuadPart; } + +static s64 GetSystemTimeNS() { + // GetSystemTimePreciseAsFileTime returns the file time in 100ns units. + static constexpr s64 Multiplier = 100; + // Convert Windows epoch to Unix epoch. + static constexpr s64 WindowsEpochToUnixEpochNS = 0x19DB1DED53E8000LL; + + FILETIME filetime; + GetSystemTimePreciseAsFileTime(&filetime); + return Multiplier * ((static_cast<s64>(filetime.dwHighDateTime) << 32) + + static_cast<s64>(filetime.dwLowDateTime)) - + WindowsEpochToUnixEpochNS; +} #endif SteadyClock::time_point SteadyClock::Now() noexcept { @@ -53,4 +66,16 @@ SteadyClock::time_point SteadyClock::Now() noexcept { #endif } +RealTimeClock::time_point RealTimeClock::Now() noexcept { +#if defined(_WIN32) + return time_point{duration{GetSystemTimeNS()}}; +#elif defined(__APPLE__) + return time_point{duration{clock_gettime_nsec_np(CLOCK_REALTIME)}}; +#else + timespec ts; + clock_gettime(CLOCK_REALTIME, &ts); + return time_point{std::chrono::seconds{ts.tv_sec} + std::chrono::nanoseconds{ts.tv_nsec}}; +#endif +} + }; // 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 { [[nodiscard]] static time_point Now() noexcept; }; +struct RealTimeClock { + using rep = s64; + using period = std::nano; + using duration = std::chrono::nanoseconds; + using time_point = std::chrono::time_point<RealTimeClock>; + + static constexpr bool is_steady = false; + + [[nodiscard]] static time_point Now() noexcept; +}; + } // 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: value = swap(swap() - 1); return old; } - // Comparaison + // Comparison // v == i bool operator==(const swapped_t& i) const { return swap() == i.swap(); @@ -368,7 +368,7 @@ public: // Member /** todo **/ - // Arithmetics + // Arithmetic template <typename S, typename T2, typename F2> friend S operator+(const S& p, const swapped_t v); @@ -384,7 +384,7 @@ public: template <typename S, typename T2, typename F2> friend S operator%(const S& p, const swapped_t v); - // Arithmetics + assignments + // Arithmetic + assignments template <typename S, typename T2, typename F2> friend S operator+=(const S& p, const swapped_t v); @@ -415,7 +415,7 @@ public: friend bool operator==(const S& p, const swapped_t v); }; -// Arithmetics +// Arithmetic template <typename S, typename T, typename F> S operator+(const S& i, const swap_struct_t<T, F> v) { return i + v.swap(); @@ -441,7 +441,7 @@ S operator%(const S& i, const swap_struct_t<T, F> v) { return i % v.swap(); } -// Arithmetics + assignments +// Arithmetic + assignments template <typename S, typename T, typename F> S& operator+=(S& i, const swap_struct_t<T, F> v) { i += v.swap(); @@ -465,7 +465,7 @@ S operator&(const swap_struct_t<T, F> v, const S& i) { return static_cast<S>(v.swap() & i); } -// Comparaison +// Comparison template <typename S, typename T, typename F> bool operator<(const S& p, const swap_struct_t<T, F> v) { 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() { FencedRDTSC(); // Get the current time. - const auto start_time = Common::SteadyClock::Now(); + const auto start_time = Common::RealTimeClock::Now(); const u64 tsc_start = FencedRDTSC(); // Wait for 250 milliseconds. std::this_thread::sleep_for(std::chrono::milliseconds{250}); - const auto end_time = Common::SteadyClock::Now(); + const auto end_time = Common::RealTimeClock::Now(); const u64 tsc_end = FencedRDTSC(); // Calculate differences. const u64 timer_diff = static_cast<u64>( @@ -72,13 +72,29 @@ NativeClock::NativeClock(u64 emulated_cpu_frequency_, u64 emulated_clock_frequen u64 rtsc_frequency_) : WallClock(emulated_cpu_frequency_, emulated_clock_frequency_, true), rtsc_frequency{ rtsc_frequency_} { + // Thread to re-adjust the RDTSC frequency after 10 seconds has elapsed. + time_sync_thread = std::jthread{[this](std::stop_token token) { + // Get the current time. + const auto start_time = Common::RealTimeClock::Now(); + const u64 tsc_start = FencedRDTSC(); + // Wait for 10 seconds. + if (!Common::StoppableTimedWait(token, std::chrono::seconds{10})) { + return; + } + const auto end_time = Common::RealTimeClock::Now(); + const u64 tsc_end = FencedRDTSC(); + // Calculate differences. + const u64 timer_diff = static_cast<u64>( + std::chrono::duration_cast<std::chrono::nanoseconds>(end_time - start_time).count()); + const u64 tsc_diff = tsc_end - tsc_start; + const u64 tsc_freq = MultiplyAndDivide64(tsc_diff, 1000000000ULL, timer_diff); + rtsc_frequency = tsc_freq; + CalculateAndSetFactors(); + }}; + time_point.inner.last_measure = FencedRDTSC(); time_point.inner.accumulated_ticks = 0U; - ns_rtsc_factor = GetFixedPoint64Factor(NS_RATIO, rtsc_frequency); - us_rtsc_factor = GetFixedPoint64Factor(US_RATIO, rtsc_frequency); - ms_rtsc_factor = GetFixedPoint64Factor(MS_RATIO, rtsc_frequency); - clock_rtsc_factor = GetFixedPoint64Factor(emulated_clock_frequency, rtsc_frequency); - cpu_rtsc_factor = GetFixedPoint64Factor(emulated_cpu_frequency, rtsc_frequency); + CalculateAndSetFactors(); } u64 NativeClock::GetRTSC() { @@ -138,6 +154,14 @@ u64 NativeClock::GetCPUCycles() { return MultiplyHigh(rtsc_value, cpu_rtsc_factor); } +void NativeClock::CalculateAndSetFactors() { + ns_rtsc_factor = GetFixedPoint64Factor(NS_RATIO, rtsc_frequency); + us_rtsc_factor = GetFixedPoint64Factor(US_RATIO, rtsc_frequency); + ms_rtsc_factor = GetFixedPoint64Factor(MS_RATIO, rtsc_frequency); + clock_rtsc_factor = GetFixedPoint64Factor(emulated_clock_frequency, rtsc_frequency); + cpu_rtsc_factor = GetFixedPoint64Factor(emulated_cpu_frequency, rtsc_frequency); +} + } // namespace X64 } // 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 @@ #pragma once +#include "common/polyfill_thread.h" #include "common/wall_clock.h" namespace Common { @@ -28,6 +29,8 @@ public: private: u64 GetRTSC(); + void CalculateAndSetFactors(); + union alignas(16) TimePoint { TimePoint() : pack{} {} u128 pack{}; @@ -47,6 +50,8 @@ private: u64 ms_rtsc_factor{}; u64 rtsc_frequency; + + std::jthread time_sync_thread; }; } // namespace X64 |