SingleCore: Move Host Timing from a sepparate thread to main cpu thread.
This commit is contained in:
		| @@ -158,6 +158,8 @@ struct System::Impl { | ||||
|         kernel.SetMulticore(is_multicore); | ||||
|         cpu_manager.SetMulticore(is_multicore); | ||||
|         cpu_manager.SetAsyncGpu(is_async_gpu); | ||||
|         core_timing.SetMulticore(is_multicore); | ||||
|         cpu_manager.SetRenderWindow(emu_window); | ||||
|  | ||||
|         core_timing.Initialize([&system]() { system.RegisterHostThread(); }); | ||||
|         kernel.Initialize(); | ||||
|   | ||||
| @@ -55,7 +55,9 @@ void CoreTiming::Initialize(std::function<void(void)>&& on_thread_init_) { | ||||
|     event_fifo_id = 0; | ||||
|     const auto empty_timed_callback = [](u64, s64) {}; | ||||
|     ev_lost = CreateEvent("_lost_event", empty_timed_callback); | ||||
|     timer_thread = std::make_unique<std::thread>(ThreadEntry, std::ref(*this)); | ||||
|     if (is_multicore) { | ||||
|         timer_thread = std::make_unique<std::thread>(ThreadEntry, std::ref(*this)); | ||||
|     } | ||||
| } | ||||
|  | ||||
| void CoreTiming::Shutdown() { | ||||
| @@ -63,7 +65,9 @@ void CoreTiming::Shutdown() { | ||||
|     shutting_down = true; | ||||
|     pause_event.Set(); | ||||
|     event.Set(); | ||||
|     timer_thread->join(); | ||||
|     if (timer_thread) { | ||||
|         timer_thread->join(); | ||||
|     } | ||||
|     ClearPendingEvents(); | ||||
|     timer_thread.reset(); | ||||
|     has_started = false; | ||||
| @@ -78,12 +82,14 @@ void CoreTiming::SyncPause(bool is_paused) { | ||||
|         return; | ||||
|     } | ||||
|     Pause(is_paused); | ||||
|     if (!is_paused) { | ||||
|         pause_event.Set(); | ||||
|     if (timer_thread) { | ||||
|         if (!is_paused) { | ||||
|             pause_event.Set(); | ||||
|         } | ||||
|         event.Set(); | ||||
|         while (paused_set != is_paused) | ||||
|             ; | ||||
|     } | ||||
|     event.Set(); | ||||
|     while (paused_set != is_paused) | ||||
|         ; | ||||
| } | ||||
|  | ||||
| bool CoreTiming::IsRunning() const { | ||||
|   | ||||
| @@ -67,6 +67,11 @@ public: | ||||
|     /// Tears down all timing related functionality. | ||||
|     void Shutdown(); | ||||
|  | ||||
|     /// Sets if emulation is multicore or single core, must be set before Initialize | ||||
|     void SetMulticore(bool is_multicore) { | ||||
|         this->is_multicore = is_multicore; | ||||
|     } | ||||
|  | ||||
|     /// Pauses/Unpauses the execution of the timer thread. | ||||
|     void Pause(bool is_paused); | ||||
|  | ||||
| @@ -147,6 +152,8 @@ private: | ||||
|     std::atomic<bool> has_started{}; | ||||
|     std::function<void(void)> on_thread_init{}; | ||||
|  | ||||
|     bool is_multicore{}; | ||||
|  | ||||
|     std::array<std::atomic<u64>, Core::Hardware::NUM_CPU_CORES> ticks_count{}; | ||||
| }; | ||||
|  | ||||
|   | ||||
| @@ -242,8 +242,11 @@ void CpuManager::SingleCoreRunGuestLoop() { | ||||
|                 break; | ||||
|             } | ||||
|         } | ||||
|         physical_core.ClearExclusive(); | ||||
|         system.ExitDynarmicProfile(); | ||||
|         thread->SetPhantomMode(true); | ||||
|         system.CoreTiming().Advance(); | ||||
|         thread->SetPhantomMode(false); | ||||
|         physical_core.ClearExclusive(); | ||||
|         PreemptSingleCore(); | ||||
|         auto& scheduler = kernel.Scheduler(current_core); | ||||
|         scheduler.TryDoContextSwitch(); | ||||
| @@ -255,6 +258,7 @@ void CpuManager::SingleCoreRunIdleThread() { | ||||
|     while (true) { | ||||
|         auto& physical_core = kernel.CurrentPhysicalCore(); | ||||
|         PreemptSingleCore(); | ||||
|         idle_count++; | ||||
|         auto& scheduler = physical_core.Scheduler(); | ||||
|         scheduler.TryDoContextSwitch(); | ||||
|     } | ||||
| @@ -280,15 +284,24 @@ void CpuManager::SingleCoreRunSuspendThread() { | ||||
| void CpuManager::PreemptSingleCore() { | ||||
|     preemption_count = 0; | ||||
|     std::size_t old_core = current_core; | ||||
|     current_core.store((current_core + 1) % Core::Hardware::NUM_CPU_CORES); | ||||
|     auto& scheduler = system.Kernel().Scheduler(old_core); | ||||
|     Kernel::Thread* current_thread = scheduler.GetCurrentThread(); | ||||
|     if (idle_count >= 4) { | ||||
|         current_thread->SetPhantomMode(true); | ||||
|         system.CoreTiming().Advance(); | ||||
|         current_thread->SetPhantomMode(false); | ||||
|     } | ||||
|     current_core.store((current_core + 1) % Core::Hardware::NUM_CPU_CORES); | ||||
|     scheduler.Unload(); | ||||
|     auto& next_scheduler = system.Kernel().Scheduler(current_core); | ||||
|     Common::Fiber::YieldTo(current_thread->GetHostContext(), next_scheduler.ControlContext()); | ||||
|     /// May have changed scheduler | ||||
|     auto& current_scheduler = system.Kernel().Scheduler(current_core); | ||||
|     current_scheduler.Reload(); | ||||
|     auto* currrent_thread2 = current_scheduler.GetCurrentThread(); | ||||
|     if (!currrent_thread2->IsIdleThread()) { | ||||
|         idle_count = 0; | ||||
|     } | ||||
| } | ||||
|  | ||||
| void CpuManager::SingleCorePause(bool paused) { | ||||
|   | ||||
| @@ -104,6 +104,7 @@ private: | ||||
|     bool is_multicore{}; | ||||
|     std::atomic<std::size_t> current_core{}; | ||||
|     std::size_t preemption_count{}; | ||||
|     std::size_t idle_count{}; | ||||
|     static constexpr std::size_t max_cycle_runs = 5; | ||||
|     Core::Frontend::EmuWindow* render_window; | ||||
|  | ||||
|   | ||||
| @@ -303,7 +303,7 @@ struct KernelCore::Impl { | ||||
|         } | ||||
|         const Kernel::Scheduler& sched = cores[result.host_handle].Scheduler(); | ||||
|         const Kernel::Thread* current = sched.GetCurrentThread(); | ||||
|         if (current != nullptr) { | ||||
|         if (current != nullptr && !current->IsPhantomMode()) { | ||||
|             result.guest_handle = current->GetGlobalHandle(); | ||||
|         } else { | ||||
|             result.guest_handle = InvalidHandle; | ||||
|   | ||||
| @@ -597,6 +597,14 @@ public: | ||||
|         is_continuous_on_svc = is_continuous; | ||||
|     } | ||||
|  | ||||
|     bool IsPhantomMode() const { | ||||
|         return is_phantom_mode; | ||||
|     } | ||||
|  | ||||
|     void SetPhantomMode(bool phantom) { | ||||
|         is_phantom_mode = phantom; | ||||
|     } | ||||
|  | ||||
| private: | ||||
|     friend class GlobalScheduler; | ||||
|     friend class Scheduler; | ||||
| @@ -699,6 +707,7 @@ private: | ||||
|     bool is_continuous_on_svc = false; | ||||
|  | ||||
|     bool will_be_terminated = false; | ||||
|     bool is_phantom_mode = false; | ||||
|  | ||||
|     bool was_running = false; | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user