Просмотр исходного кода

core: core_timing: Re-initialize if single/multicore state changes.

bunnei 3 лет назад
Родитель
Сommit
638fa6170a
3 измененных файлов с 36 добавлено и 14 удалено
  1. 20 5
      src/core/core.cpp
  2. 14 9
      src/core/core_timing.cpp
  3. 2 0
      src/core/core_timing.h

+ 20 - 5
src/core/core.cpp

@@ -155,6 +155,24 @@ struct System::Impl {
 
 
         // Create default implementations of applets if one is not provided.
         // Create default implementations of applets if one is not provided.
         applet_manager.SetDefaultAppletsIfMissing();
         applet_manager.SetDefaultAppletsIfMissing();
+
+        is_async_gpu = Settings::values.use_asynchronous_gpu_emulation.GetValue();
+
+        kernel.SetMulticore(is_multicore);
+        cpu_manager.SetMulticore(is_multicore);
+        cpu_manager.SetAsyncGpu(is_async_gpu);
+    }
+
+    void ReinitializeIfNecessary(System& system) {
+        if (is_multicore == Settings::values.use_multi_core.GetValue()) {
+            return;
+        }
+
+        LOG_DEBUG(Kernel, "Re-initializing");
+
+        is_multicore = Settings::values.use_multi_core.GetValue();
+
+        Initialize(system);
     }
     }
 
 
     SystemResultStatus Run() {
     SystemResultStatus Run() {
@@ -205,11 +223,8 @@ struct System::Impl {
     SystemResultStatus SetupForMainProcess(System& system, Frontend::EmuWindow& emu_window) {
     SystemResultStatus SetupForMainProcess(System& system, Frontend::EmuWindow& emu_window) {
         LOG_DEBUG(Core, "initialized OK");
         LOG_DEBUG(Core, "initialized OK");
 
 
-        is_async_gpu = Settings::values.use_asynchronous_gpu_emulation.GetValue();
-
-        kernel.SetMulticore(is_multicore);
-        cpu_manager.SetMulticore(is_multicore);
-        cpu_manager.SetAsyncGpu(is_async_gpu);
+        // Setting changes may require a full system reinitialization (e.g., disabling multicore).
+        ReinitializeIfNecessary(system);
 
 
         kernel.Initialize();
         kernel.Initialize();
         cpu_manager.Initialize();
         cpu_manager.Initialize();

+ 14 - 9
src/core/core_timing.cpp

@@ -41,15 +41,7 @@ CoreTiming::CoreTiming()
     : clock{Common::CreateBestMatchingClock(Hardware::BASE_CLOCK_RATE, Hardware::CNTFREQ)} {}
     : clock{Common::CreateBestMatchingClock(Hardware::BASE_CLOCK_RATE, Hardware::CNTFREQ)} {}
 
 
 CoreTiming::~CoreTiming() {
 CoreTiming::~CoreTiming() {
-    paused = true;
-    shutting_down = true;
-    pause_event.Set();
-    event.Set();
-    if (timer_thread) {
-        timer_thread->join();
-    }
-    timer_thread.reset();
-    has_started = false;
+    Reset();
 }
 }
 
 
 void CoreTiming::ThreadEntry(CoreTiming& instance) {
 void CoreTiming::ThreadEntry(CoreTiming& instance) {
@@ -63,6 +55,7 @@ void CoreTiming::ThreadEntry(CoreTiming& instance) {
 }
 }
 
 
 void CoreTiming::Initialize(std::function<void()>&& on_thread_init_) {
 void CoreTiming::Initialize(std::function<void()>&& on_thread_init_) {
+    Reset();
     on_thread_init = std::move(on_thread_init_);
     on_thread_init = std::move(on_thread_init_);
     event_fifo_id = 0;
     event_fifo_id = 0;
     shutting_down = false;
     shutting_down = false;
@@ -304,6 +297,18 @@ void CoreTiming::ThreadLoop() {
     }
     }
 }
 }
 
 
+void CoreTiming::Reset() {
+    paused = true;
+    shutting_down = true;
+    pause_event.Set();
+    event.Set();
+    if (timer_thread) {
+        timer_thread->join();
+    }
+    timer_thread.reset();
+    has_started = false;
+}
+
 std::chrono::nanoseconds CoreTiming::GetGlobalTimeNs() const {
 std::chrono::nanoseconds CoreTiming::GetGlobalTimeNs() const {
     if (is_multicore) {
     if (is_multicore) {
         return clock->GetTimeNS();
         return clock->GetTimeNS();

+ 2 - 0
src/core/core_timing.h

@@ -134,6 +134,8 @@ private:
     static void ThreadEntry(CoreTiming& instance);
     static void ThreadEntry(CoreTiming& instance);
     void ThreadLoop();
     void ThreadLoop();
 
 
+    void Reset();
+
     std::unique_ptr<Common::WallClock> clock;
     std::unique_ptr<Common::WallClock> clock;
 
 
     s64 global_timer = 0;
     s64 global_timer = 0;