diff options
-rw-r--r-- | src/common/fiber.cpp | 2 | ||||
-rw-r--r-- | src/common/wall_clock.cpp | 9 | ||||
-rw-r--r-- | src/core/host_timing.cpp | 61 | ||||
-rw-r--r-- | src/core/host_timing.h | 6 |
4 files changed, 47 insertions, 31 deletions
diff --git a/src/common/fiber.cpp b/src/common/fiber.cpp index 1220eddf0..e9c0946b6 100644 --- a/src/common/fiber.cpp +++ b/src/common/fiber.cpp @@ -110,7 +110,7 @@ Fiber::Fiber(std::function<void(void*)>&& entry_point_func, void* start_paramete FiberStartFunc); } -Fiber::Fiber() : guard{}, entry_point{}, start_parameter{}, previous_fiber{} { +Fiber::Fiber() { impl = std::make_unique<FiberImpl>(); } diff --git a/src/common/wall_clock.cpp b/src/common/wall_clock.cpp index e6161c72c..d4d35f4e7 100644 --- a/src/common/wall_clock.cpp +++ b/src/common/wall_clock.cpp @@ -42,14 +42,15 @@ public: u64 GetClockCycles() override { std::chrono::nanoseconds time_now = GetTimeNS(); - const u128 temporal = Common::Multiply64Into128(time_now.count(), emulated_clock_frequency); - return Common::Divide128On32(temporal, 1000000000).first; + const u128 temporary = + Common::Multiply64Into128(time_now.count(), emulated_clock_frequency); + return Common::Divide128On32(temporary, 1000000000).first; } u64 GetCPUCycles() override { std::chrono::nanoseconds time_now = GetTimeNS(); - const u128 temporal = Common::Multiply64Into128(time_now.count(), emulated_cpu_frequency); - return Common::Divide128On32(temporal, 1000000000).first; + const u128 temporary = Common::Multiply64Into128(time_now.count(), emulated_cpu_frequency); + return Common::Divide128On32(temporary, 1000000000).first; } private: diff --git a/src/core/host_timing.cpp b/src/core/host_timing.cpp index be80d9f8e..5d35a96b1 100644 --- a/src/core/host_timing.cpp +++ b/src/core/host_timing.cpp @@ -42,7 +42,7 @@ CoreTiming::CoreTiming() { CoreTiming::~CoreTiming() = default; void CoreTiming::ThreadEntry(CoreTiming& instance) { - instance.Advance(); + instance.ThreadLoop(); } void CoreTiming::Initialize() { @@ -137,38 +137,49 @@ void CoreTiming::RemoveEvent(const std::shared_ptr<EventType>& event_type) { basic_lock.unlock(); } -void CoreTiming::Advance() { - has_started = true; - while (!shutting_down) { - while (!paused) { - paused_set = false; - basic_lock.lock(); - global_timer = GetGlobalTimeNs().count(); +std::optional<u64> CoreTiming::Advance() { + advance_lock.lock(); + basic_lock.lock(); + global_timer = GetGlobalTimeNs().count(); - while (!event_queue.empty() && event_queue.front().time <= global_timer) { - Event evt = std::move(event_queue.front()); - std::pop_heap(event_queue.begin(), event_queue.end(), std::greater<>()); - event_queue.pop_back(); - basic_lock.unlock(); + while (!event_queue.empty() && event_queue.front().time <= global_timer) { + Event evt = std::move(event_queue.front()); + std::pop_heap(event_queue.begin(), event_queue.end(), std::greater<>()); + event_queue.pop_back(); + basic_lock.unlock(); - if (auto event_type{evt.type.lock()}) { - event_type->callback(evt.userdata, global_timer - evt.time); - } + if (auto event_type{evt.type.lock()}) { + event_type->callback(evt.userdata, global_timer - evt.time); + } - basic_lock.lock(); - } + basic_lock.lock(); + } - if (!event_queue.empty()) { - std::chrono::nanoseconds next_time = - std::chrono::nanoseconds(event_queue.front().time - global_timer); - basic_lock.unlock(); - event.WaitFor(next_time); + if (!event_queue.empty()) { + const u64 next_time = event_queue.front().time - global_timer; + basic_lock.unlock(); + advance_lock.unlock(); + return next_time; + } else { + basic_lock.unlock(); + advance_lock.unlock(); + return std::nullopt; + } +} + +void CoreTiming::ThreadLoop() { + has_started = true; + while (!shutting_down) { + while (!paused) { + paused_set = false; + const auto next_time = Advance(); + if (next_time) { + std::chrono::nanoseconds next_time_ns = std::chrono::nanoseconds(*next_time); + event.WaitFor(next_time_ns); } else { - basic_lock.unlock(); wait_set = true; event.Wait(); } - wait_set = false; } paused_set = true; diff --git a/src/core/host_timing.h b/src/core/host_timing.h index 679fcf491..cd44b308c 100644 --- a/src/core/host_timing.h +++ b/src/core/host_timing.h @@ -103,6 +103,9 @@ public: /// Returns current time in nanoseconds. std::chrono::nanoseconds GetGlobalTimeNs() const; + /// Checks for events manually and returns time in nanoseconds for next event, threadsafe. + std::optional<u64> Advance(); + private: struct Event; @@ -110,7 +113,7 @@ private: void ClearPendingEvents(); static void ThreadEntry(CoreTiming& instance); - void Advance(); + void ThreadLoop(); std::unique_ptr<Common::WallClock> clock; @@ -128,6 +131,7 @@ private: std::shared_ptr<EventType> ev_lost; Common::Event event{}; Common::SpinLock basic_lock{}; + Common::SpinLock advance_lock{}; std::unique_ptr<std::thread> timer_thread; std::atomic<bool> paused{}; std::atomic<bool> paused_set{}; |