diff options
Diffstat (limited to 'src/core/core.cpp')
-rw-r--r-- | src/core/core.cpp | 30 |
1 files changed, 25 insertions, 5 deletions
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> 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>(); + cpu_barrier = std::make_shared<CpuBarrier>(); + for (size_t index = 0; index < cpu_cores.size(); ++index) { + cpu_cores[index] = std::make_shared<Cpu>(cpu_barrier, index); } gpu_core = std::make_unique<Tegra::GPU>(); - telemetry_session = std::make_unique<Core::TelemetrySession>(); - service_manager = std::make_shared<Service::SM::ServiceManager>(); 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<std::thread>(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(); |