summaryrefslogtreecommitdiffstats
path: root/src/common
diff options
context:
space:
mode:
Diffstat (limited to '')
-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:
* @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