From 03d13290b3946787841d94b1721dbed9639c9ff8 Mon Sep 17 00:00:00 2001 From: B3n30 Date: Wed, 15 Aug 2018 13:51:56 +0200 Subject: [PATCH] fixup! CoreTiming: Keep Cores synced by having each core it's own downcount and let the main core run an intermediate run if it's slice_length was cropped --- src/core/core_cpu.cpp | 8 ++++---- src/core/core_cpu.h | 2 +- src/core/core_timing.cpp | 7 +++---- src/core/core_timing.h | 1 + 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/core/core_cpu.cpp b/src/core/core_cpu.cpp index 19259103ff..34a369783e 100644 --- a/src/core/core_cpu.cpp +++ b/src/core/core_cpu.cpp @@ -25,7 +25,7 @@ void CpuBarrier::NotifyEnd() { condition.notify_all(); } -bool CpuBarrier::Rendezvous() { +bool CpuBarrier::Rendezvous(bool main_core) { if (!Settings::values.use_multi_core) { // Meaningless when running in single-core mode return true; @@ -36,7 +36,7 @@ bool CpuBarrier::Rendezvous() { --cores_waiting; if (!cores_waiting) { - if (CoreTiming::MainSliceWasCropped() && IsMainCore()) { + if (CoreTiming::MainSliceWasCropped() && main_core) { // This is the main thread but we were cropped, so just continue; ++cores_waiting; return true; @@ -46,7 +46,7 @@ bool CpuBarrier::Rendezvous() { return true; } - if (CoreTiming::MainSliceWasCropped() && IsMainCore()) { + if (CoreTiming::MainSliceWasCropped() && main_core) { // This is the main thread but we were cropped, so just continue; ++cores_waiting; return true; @@ -90,7 +90,7 @@ std::shared_ptr Cpu::MakeExclusiveMonitor(size_t num_cores) { void Cpu::RunLoop(bool tight_loop) { // Wait for all other CPU cores to complete the previous slice, such that they run in lock-step - if (!cpu_barrier->Rendezvous()) { + if (!cpu_barrier->Rendezvous(IsMainCore())) { // If rendezvous failed, session has been killed return; } diff --git a/src/core/core_cpu.h b/src/core/core_cpu.h index 56cdae1947..f09f642129 100644 --- a/src/core/core_cpu.h +++ b/src/core/core_cpu.h @@ -30,7 +30,7 @@ public: void NotifyEnd(); - bool Rendezvous(); + bool Rendezvous(bool main_core); private: unsigned cores_waiting{NUM_CPU_CORES}; diff --git a/src/core/core_timing.cpp b/src/core/core_timing.cpp index f46f69cfab..40d227f6e3 100644 --- a/src/core/core_timing.cpp +++ b/src/core/core_timing.cpp @@ -93,7 +93,7 @@ void UnregisterAllEvents() { void Init() { std::unique_lock lock(mutex); - std::fill(downcount.begin(), downcount.end(), MAX_SLICE_LENGTH); + downcount.fill(MAX_SLICE_LENGTH); slice_length = MAX_SLICE_LENGTH; next_slice_length = MAX_SLICE_LENGTH; global_timer = 0; @@ -183,8 +183,7 @@ void ForceExceptionCheck(s64 cycles) { if (downcount[0] > cycles) { // downcount is always (much) smaller than MAX_INT so we can safely cast cycles to an int // here. Account for cycles already executed by adjusting the g.slice_length - s64 crop_time = downcount[0] - static_cast(cycles); - slice_length -= crop_time; + slice_length -= downcount[0] - static_cast(cycles); downcount[0] = static_cast(cycles); if (next_slice_length <= 0) next_slice_length = MAX_SLICE_LENGTH; @@ -201,7 +200,7 @@ void MoveEvents() { void Advance() { std::unique_lock lock(mutex); - size_t current_core = Core::System::GetInstance().CurrentCoreIndex(); + const size_t current_core = Core::System::GetInstance().CurrentCoreIndex(); if (current_core != 0) { downcount[current_core] = MAX_SLICE_LENGTH; return; diff --git a/src/core/core_timing.h b/src/core/core_timing.h index adb70adfeb..12ac1b6309 100644 --- a/src/core/core_timing.h +++ b/src/core/core_timing.h @@ -81,6 +81,7 @@ void MoveEvents(); /// Pretend that the main CPU has executed enough cycles to reach the next event. void Idle(); +/// Checks if the Main Core executed less then MAX_SLICE_LENGTH bool MainSliceWasCropped(); /// Clear all pending events. This should ONLY be done on exit.