From 096366ead51345bcd170e31b6160b14aaf73e996 Mon Sep 17 00:00:00 2001 From: Fernando Sahmkow Date: Tue, 23 Nov 2021 03:29:00 +0100 Subject: Common: improve native clock. --- src/common/uint128.h | 5 +++++ src/common/x64/native_clock.cpp | 40 +++++++++++++++++++--------------------- src/common/x64/native_clock.h | 13 +++++-------- 3 files changed, 29 insertions(+), 29 deletions(-) (limited to 'src/common') diff --git a/src/common/uint128.h b/src/common/uint128.h index f890ffec2..199d0f55e 100644 --- a/src/common/uint128.h +++ b/src/common/uint128.h @@ -30,6 +30,10 @@ namespace Common { #else return _udiv128(r[1], r[0], d, &remainder); #endif +#else +#ifdef __SIZEOF_INT128__ + const auto product = static_cast(a) * static_cast(b); + return static_cast(product / d); #else const u64 diva = a / d; const u64 moda = a % d; @@ -37,6 +41,7 @@ namespace Common { const u64 modb = b % d; return diva * b + moda * divb + moda * modb / d; #endif +#endif } // This function multiplies 2 u64 values and produces a u128 value; diff --git a/src/common/x64/native_clock.cpp b/src/common/x64/native_clock.cpp index 1b7194503..427a382cd 100644 --- a/src/common/x64/native_clock.cpp +++ b/src/common/x64/native_clock.cpp @@ -5,7 +5,6 @@ #include #include -#include "common/atomic_ops.h" #include "common/uint128.h" #include "common/x64/native_clock.h" @@ -65,8 +64,10 @@ 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_} { - time_point.inner.last_measure = FencedRDTSC(); - time_point.inner.accumulated_ticks = 0U; + TimePoint new_time_point{}; + new_time_point.last_measure = FencedRDTSC(); + new_time_point.accumulated_ticks = 0U; + time_point.store(new_time_point); ns_rtsc_factor = GetFixedPoint64Factor(NS_RATIO, rtsc_frequency); us_rtsc_factor = GetFixedPoint64Factor(US_RATIO, rtsc_frequency); ms_rtsc_factor = GetFixedPoint64Factor(MS_RATIO, rtsc_frequency); @@ -76,34 +77,31 @@ NativeClock::NativeClock(u64 emulated_cpu_frequency_, u64 emulated_clock_frequen u64 NativeClock::GetRTSC() { TimePoint new_time_point{}; - TimePoint current_time_point{}; - - current_time_point.pack = Common::AtomicLoad128(time_point.pack.data()); + TimePoint current_time_point = time_point.load(std::memory_order_acquire); do { const u64 current_measure = FencedRDTSC(); - u64 diff = current_measure - current_time_point.inner.last_measure; + u64 diff = current_measure - current_time_point.last_measure; diff = diff & ~static_cast(static_cast(diff) >> 63); // max(diff, 0) - new_time_point.inner.last_measure = current_measure > current_time_point.inner.last_measure - ? current_measure - : current_time_point.inner.last_measure; - new_time_point.inner.accumulated_ticks = current_time_point.inner.accumulated_ticks + diff; - } while (!Common::AtomicCompareAndSwap(time_point.pack.data(), new_time_point.pack, - current_time_point.pack, current_time_point.pack)); + new_time_point.last_measure = current_measure > current_time_point.last_measure + ? current_measure + : current_time_point.last_measure; + new_time_point.accumulated_ticks = current_time_point.accumulated_ticks + diff; + } while (!time_point.compare_exchange_weak( + current_time_point, new_time_point, std::memory_order_release, std::memory_order_acquire)); /// The clock cannot be more precise than the guest timer, remove the lower bits - return new_time_point.inner.accumulated_ticks & inaccuracy_mask; + return new_time_point.accumulated_ticks & inaccuracy_mask; } void NativeClock::Pause(bool is_paused) { if (!is_paused) { - TimePoint current_time_point{}; TimePoint new_time_point{}; - - current_time_point.pack = Common::AtomicLoad128(time_point.pack.data()); + TimePoint current_time_point = time_point.load(std::memory_order_acquire); do { - new_time_point.pack = current_time_point.pack; - new_time_point.inner.last_measure = FencedRDTSC(); - } while (!Common::AtomicCompareAndSwap(time_point.pack.data(), new_time_point.pack, - current_time_point.pack, current_time_point.pack)); + new_time_point = current_time_point; + new_time_point.last_measure = FencedRDTSC(); + } while (!time_point.compare_exchange_weak(current_time_point, new_time_point, + std::memory_order_release, + std::memory_order_acquire)); } } diff --git a/src/common/x64/native_clock.h b/src/common/x64/native_clock.h index 30d2ba2e9..e57446cb9 100644 --- a/src/common/x64/native_clock.h +++ b/src/common/x64/native_clock.h @@ -3,6 +3,7 @@ #pragma once +#include #include "common/wall_clock.h" namespace Common { @@ -28,13 +29,9 @@ public: private: u64 GetRTSC(); - union alignas(16) TimePoint { - TimePoint() : pack{} {} - u128 pack{}; - struct Inner { - u64 last_measure{}; - u64 accumulated_ticks{}; - } inner; + struct alignas(16) TimePoint { + u64 last_measure{}; + u64 accumulated_ticks{}; }; /// value used to reduce the native clocks accuracy as some apss rely on @@ -42,7 +39,7 @@ private: /// be higher. static constexpr u64 inaccuracy_mask = ~(UINT64_C(0x400) - 1); - TimePoint time_point; + std::atomic time_point; // factors u64 clock_rtsc_factor{}; u64 cpu_rtsc_factor{}; -- cgit v1.2.3 From a2d29412cbda3e0dc57c49c5d4c098e8ba73cbb5 Mon Sep 17 00:00:00 2001 From: Fernando Sahmkow Date: Sat, 27 Nov 2021 20:31:46 +0100 Subject: Core/Common: Corrections to core timing and add critical priority. --- src/common/thread.cpp | 13 +++++++++---- src/common/thread.h | 1 + 2 files changed, 10 insertions(+), 4 deletions(-) (limited to 'src/common') diff --git a/src/common/thread.cpp b/src/common/thread.cpp index f932a7290..924f0df1b 100644 --- a/src/common/thread.cpp +++ b/src/common/thread.cpp @@ -47,6 +47,9 @@ void SetCurrentThreadPriority(ThreadPriority new_priority) { case ThreadPriority::VeryHigh: windows_priority = THREAD_PRIORITY_HIGHEST; break; + case ThreadPriority::Critical: + windows_priority = THREAD_PRIORITY_TIME_CRITICAL; + break; default: windows_priority = THREAD_PRIORITY_NORMAL; break; @@ -59,9 +62,11 @@ void SetCurrentThreadPriority(ThreadPriority new_priority) { void SetCurrentThreadPriority(ThreadPriority new_priority) { pthread_t this_thread = pthread_self(); - s32 max_prio = sched_get_priority_max(SCHED_OTHER); - s32 min_prio = sched_get_priority_min(SCHED_OTHER); - u32 level = static_cast(new_priority) + 1; + const auto scheduling_type = + new_priority != ThreadPriority::Critical ? SCHED_OTHER : SCHED_FIFO; + s32 max_prio = sched_get_priority_max(scheduling_type); + s32 min_prio = sched_get_priority_min(scheduling_type); + u32 level = std::max(static_cast(new_priority) + 1, 4U); struct sched_param params; if (max_prio > min_prio) { @@ -70,7 +75,7 @@ void SetCurrentThreadPriority(ThreadPriority new_priority) { params.sched_priority = min_prio - ((min_prio - max_prio) * level) / 4; } - pthread_setschedparam(this_thread, SCHED_OTHER, ¶ms); + pthread_setschedparam(this_thread, scheduling_type, ¶ms); } #endif diff --git a/src/common/thread.h b/src/common/thread.h index a63122516..1552f58e0 100644 --- a/src/common/thread.h +++ b/src/common/thread.h @@ -92,6 +92,7 @@ enum class ThreadPriority : u32 { Normal = 1, High = 2, VeryHigh = 3, + Critical = 4, }; void SetCurrentThreadPriority(ThreadPriority new_priority); -- cgit v1.2.3 From 9cafb0d91266210dab2c72e484b493bceae1cb02 Mon Sep 17 00:00:00 2001 From: Fernando Sahmkow Date: Sun, 28 Nov 2021 12:21:45 +0100 Subject: Core: Fix tests. --- src/common/thread.cpp | 3 +-- src/common/x64/native_clock.cpp | 1 + 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'src/common') diff --git a/src/common/thread.cpp b/src/common/thread.cpp index 924f0df1b..919e33af9 100644 --- a/src/common/thread.cpp +++ b/src/common/thread.cpp @@ -62,8 +62,7 @@ void SetCurrentThreadPriority(ThreadPriority new_priority) { void SetCurrentThreadPriority(ThreadPriority new_priority) { pthread_t this_thread = pthread_self(); - const auto scheduling_type = - new_priority != ThreadPriority::Critical ? SCHED_OTHER : SCHED_FIFO; + const auto scheduling_type = SCHED_OTHER; s32 max_prio = sched_get_priority_max(scheduling_type); s32 min_prio = sched_get_priority_min(scheduling_type); u32 level = std::max(static_cast(new_priority) + 1, 4U); diff --git a/src/common/x64/native_clock.cpp b/src/common/x64/native_clock.cpp index 427a382cd..0b89f9ed2 100644 --- a/src/common/x64/native_clock.cpp +++ b/src/common/x64/native_clock.cpp @@ -5,6 +5,7 @@ #include #include +#include "common/atomic_ops.h" #include "common/uint128.h" #include "common/x64/native_clock.h" -- cgit v1.2.3 From f5c1d7b8c8895b5d6b99685313be9061c8ed8a82 Mon Sep 17 00:00:00 2001 From: Fernando Sahmkow Date: Tue, 28 Jun 2022 01:47:00 +0200 Subject: Native Clock: remove inaccuracy mask. --- src/common/x64/native_clock.cpp | 2 +- src/common/x64/native_clock.h | 5 ----- 2 files changed, 1 insertion(+), 6 deletions(-) (limited to 'src/common') diff --git a/src/common/x64/native_clock.cpp b/src/common/x64/native_clock.cpp index 0b89f9ed2..488c8c905 100644 --- a/src/common/x64/native_clock.cpp +++ b/src/common/x64/native_clock.cpp @@ -90,7 +90,7 @@ u64 NativeClock::GetRTSC() { } while (!time_point.compare_exchange_weak( current_time_point, new_time_point, std::memory_order_release, std::memory_order_acquire)); /// The clock cannot be more precise than the guest timer, remove the lower bits - return new_time_point.accumulated_ticks & inaccuracy_mask; + return new_time_point.accumulated_ticks; } void NativeClock::Pause(bool is_paused) { diff --git a/src/common/x64/native_clock.h b/src/common/x64/native_clock.h index e57446cb9..046cea095 100644 --- a/src/common/x64/native_clock.h +++ b/src/common/x64/native_clock.h @@ -34,11 +34,6 @@ private: u64 accumulated_ticks{}; }; - /// value used to reduce the native clocks accuracy as some apss rely on - /// undefined behavior where the level of accuracy in the clock shouldn't - /// be higher. - static constexpr u64 inaccuracy_mask = ~(UINT64_C(0x400) - 1); - std::atomic time_point; // factors u64 clock_rtsc_factor{}; -- cgit v1.2.3 From 2575a93dc6d15bb4c60c18be1635b48f37355059 Mon Sep 17 00:00:00 2001 From: Fernando Sahmkow Date: Tue, 28 Jun 2022 22:42:00 +0200 Subject: Native clock: Use atomic ops as before. --- src/common/x64/native_clock.cpp | 39 ++++++++++++++++++++------------------- src/common/x64/native_clock.h | 14 +++++++++----- 2 files changed, 29 insertions(+), 24 deletions(-) (limited to 'src/common') diff --git a/src/common/x64/native_clock.cpp b/src/common/x64/native_clock.cpp index 488c8c905..c0d38cf6b 100644 --- a/src/common/x64/native_clock.cpp +++ b/src/common/x64/native_clock.cpp @@ -65,10 +65,8 @@ 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_} { - TimePoint new_time_point{}; - new_time_point.last_measure = FencedRDTSC(); - new_time_point.accumulated_ticks = 0U; - time_point.store(new_time_point); + 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); @@ -77,32 +75,35 @@ NativeClock::NativeClock(u64 emulated_cpu_frequency_, u64 emulated_clock_frequen } u64 NativeClock::GetRTSC() { + TimePoint current_time_point{}; TimePoint new_time_point{}; - TimePoint current_time_point = time_point.load(std::memory_order_acquire); + + current_time_point.pack = Common::AtomicLoad128(time_point.pack.data()); do { const u64 current_measure = FencedRDTSC(); - u64 diff = current_measure - current_time_point.last_measure; + u64 diff = current_measure - current_time_point.inner.last_measure; diff = diff & ~static_cast(static_cast(diff) >> 63); // max(diff, 0) - new_time_point.last_measure = current_measure > current_time_point.last_measure - ? current_measure - : current_time_point.last_measure; - new_time_point.accumulated_ticks = current_time_point.accumulated_ticks + diff; - } while (!time_point.compare_exchange_weak( - current_time_point, new_time_point, std::memory_order_release, std::memory_order_acquire)); + new_time_point.inner.last_measure = current_measure > current_time_point.inner.last_measure + ? current_measure + : current_time_point.inner.last_measure; + new_time_point.inner.accumulated_ticks = current_time_point.inner.accumulated_ticks + diff; + } while (!Common::AtomicCompareAndSwap(time_point.pack.data(), new_time_point.pack, + current_time_point.pack, current_time_point.pack)); /// The clock cannot be more precise than the guest timer, remove the lower bits - return new_time_point.accumulated_ticks; + return new_time_point.inner.accumulated_ticks; } void NativeClock::Pause(bool is_paused) { if (!is_paused) { + TimePoint current_time_point{}; TimePoint new_time_point{}; - TimePoint current_time_point = time_point.load(std::memory_order_acquire); + + current_time_point.pack = Common::AtomicLoad128(time_point.pack.data()); do { - new_time_point = current_time_point; - new_time_point.last_measure = FencedRDTSC(); - } while (!time_point.compare_exchange_weak(current_time_point, new_time_point, - std::memory_order_release, - std::memory_order_acquire)); + new_time_point.pack = current_time_point.pack; + new_time_point.inner.last_measure = FencedRDTSC(); + } while (!Common::AtomicCompareAndSwap(time_point.pack.data(), new_time_point.pack, + current_time_point.pack, current_time_point.pack)); } } diff --git a/src/common/x64/native_clock.h b/src/common/x64/native_clock.h index 046cea095..38ae7a462 100644 --- a/src/common/x64/native_clock.h +++ b/src/common/x64/native_clock.h @@ -3,7 +3,6 @@ #pragma once -#include #include "common/wall_clock.h" namespace Common { @@ -29,12 +28,17 @@ public: private: u64 GetRTSC(); - struct alignas(16) TimePoint { - u64 last_measure{}; - u64 accumulated_ticks{}; + union alignas(16) TimePoint { + TimePoint() : pack{} {} + u128 pack{}; + struct Inner { + u64 last_measure{}; + u64 accumulated_ticks{}; + } inner; }; - std::atomic time_point; + TimePoint time_point; + // factors u64 clock_rtsc_factor{}; u64 cpu_rtsc_factor{}; -- cgit v1.2.3 From 3196d957b02266293b68a60c75c3db9a00faf1f6 Mon Sep 17 00:00:00 2001 From: Fernando Sahmkow Date: Wed, 29 Jun 2022 01:29:24 +0200 Subject: Adress Feedback. --- src/common/x64/native_clock.cpp | 1 - 1 file changed, 1 deletion(-) (limited to 'src/common') diff --git a/src/common/x64/native_clock.cpp b/src/common/x64/native_clock.cpp index c0d38cf6b..6aaa8cdf9 100644 --- a/src/common/x64/native_clock.cpp +++ b/src/common/x64/native_clock.cpp @@ -89,7 +89,6 @@ u64 NativeClock::GetRTSC() { new_time_point.inner.accumulated_ticks = current_time_point.inner.accumulated_ticks + diff; } while (!Common::AtomicCompareAndSwap(time_point.pack.data(), new_time_point.pack, current_time_point.pack, current_time_point.pack)); - /// The clock cannot be more precise than the guest timer, remove the lower bits return new_time_point.inner.accumulated_ticks; } -- cgit v1.2.3