From 9776ff91797423a9cf19571faafe4648fb5a1d1d Mon Sep 17 00:00:00 2001 From: bunnei Date: Wed, 2 May 2018 21:26:14 -0400 Subject: core: Create a thread for each CPU core, keep in lock-step with a barrier. --- src/core/core.cpp | 30 +++++++++++++++++++++++++----- 1 file changed, 25 insertions(+), 5 deletions(-) (limited to 'src/core/core.cpp') diff --git a/src/core/core.cpp b/src/core/core.cpp index 0af78c18c..066423f23 100644 --- a/src/core/core.cpp +++ b/src/core/core.cpp @@ -27,6 +27,13 @@ namespace Core { System::~System() = default; +/// Runs a CPU core while the system is powered on +static void RunCpuCore(std::shared_ptr cpu_state) { + while (Core::System().GetInstance().IsPoweredOn()) { + cpu_state->RunLoop(true); + } +} + System::ResultStatus System::RunLoop(bool tight_loop) { status = ResultStatus::Success; @@ -109,7 +116,7 @@ System::ResultStatus System::Load(EmuWindow* emu_window, const std::string& file } void System::PrepareReschedule() { - cpu_cores[0]->PrepareReschedule(); + CurrentCpuCore().PrepareReschedule(); } PerfStats::Results System::GetAndResetPerfStats() { @@ -123,14 +130,13 @@ System::ResultStatus System::Init(EmuWindow* emu_window, u32 system_mode) { current_process = Kernel::Process::Create("main"); - for (auto& cpu_core : cpu_cores) { - cpu_core = std::make_unique(); + cpu_barrier = std::make_shared(); + for (size_t index = 0; index < cpu_cores.size(); ++index) { + cpu_cores[index] = std::make_shared(cpu_barrier, index); } gpu_core = std::make_unique(); - telemetry_session = std::make_unique(); - service_manager = std::make_shared(); HW::Init(); @@ -142,6 +148,14 @@ System::ResultStatus System::Init(EmuWindow* emu_window, u32 system_mode) { return ResultStatus::ErrorVideoCore; } + // Create threads for CPU cores 1-3, and build thread_to_cpu map + // CPU core 0 is run on the main thread + thread_to_cpu[std::this_thread::get_id()] = cpu_cores[0]; + for (size_t index = 0; index < cpu_core_threads.size(); ++index) { + cpu_core_threads[index] = std::make_unique(RunCpuCore, cpu_cores[index + 1]); + thread_to_cpu[cpu_core_threads[index]->get_id()] = cpu_cores[index + 1]; + } + NGLOG_DEBUG(Core, "Initialized OK"); // Reset counters and set time origin to current frame @@ -171,9 +185,15 @@ void System::Shutdown() { telemetry_session.reset(); gpu_core.reset(); + // Close all CPU/threading state + thread_to_cpu.clear(); for (auto& cpu_core : cpu_cores) { cpu_core.reset(); } + for (auto& thread : cpu_core_threads) { + thread->join(); + thread.reset(); + } CoreTiming::Shutdown(); -- cgit v1.2.3