diff options
Diffstat (limited to 'src/core/cpu_manager.cpp')
| -rw-r--r-- | src/core/cpu_manager.cpp | 85 |
1 files changed, 35 insertions, 50 deletions
diff --git a/src/core/cpu_manager.cpp b/src/core/cpu_manager.cpp index 10fdcdf8a2..7194fa5022 100644 --- a/src/core/cpu_manager.cpp +++ b/src/core/cpu_manager.cpp @@ -25,9 +25,11 @@ CpuManager::~CpuManager() = default; void CpuManager::Initialize() { num_cores = is_multicore ? Core::Hardware::NUM_CPU_CORES : 1; - gpu_barrier = std::make_unique<Common::Barrier>(num_cores + 1); + gpu_barrier.emplace(num_cores + 1); for (std::size_t core = 0; core < num_cores; core++) - core_data[core].host_thread = std::jthread([this, core](std::stop_token token) { RunThread(token, core); }); + core_data[core].host_thread = std::jthread([this, core](std::stop_token token) { + RunThread(token, core); + }); } void CpuManager::Shutdown() { @@ -39,69 +41,61 @@ void CpuManager::Shutdown() { } } -void CpuManager::GuestThreadFunction() { +void CpuManager::GuestThreadFunction(Kernel::KernelCore& kernel) { if (is_multicore) { - MultiCoreRunGuestThread(); + MultiCoreRunGuestThread(kernel); } else { - SingleCoreRunGuestThread(); + SingleCoreRunGuestThread(kernel); } } -void CpuManager::IdleThreadFunction() { +void CpuManager::IdleThreadFunction(Kernel::KernelCore& kernel) { if (is_multicore) { - MultiCoreRunIdleThread(); + MultiCoreRunIdleThread(kernel); } else { - SingleCoreRunIdleThread(); + SingleCoreRunIdleThread(kernel); } } -void CpuManager::ShutdownThreadFunction() { - ShutdownThread(); +void CpuManager::ShutdownThreadFunction(Kernel::KernelCore& kernel) { + ShutdownThread(kernel); } -void CpuManager::HandleInterrupt() { - auto& kernel = system.Kernel(); +void CpuManager::HandleInterrupt(Kernel::KernelCore& kernel) { auto core_index = kernel.CurrentPhysicalCoreIndex(); - - Kernel::KInterruptManager::HandleInterrupt(kernel, static_cast<s32>(core_index)); + Kernel::KInterruptManager::HandleInterrupt(kernel, s32(core_index)); } /////////////////////////////////////////////////////////////////////////////// /// MultiCore /// /////////////////////////////////////////////////////////////////////////////// -void CpuManager::MultiCoreRunGuestThread() { +void CpuManager::MultiCoreRunGuestThread(Kernel::KernelCore& kernel) { // Similar to UserModeThreadStarter in HOS - auto& kernel = system.Kernel(); auto* thread = Kernel::GetCurrentThreadPointer(kernel); - kernel.CurrentScheduler()->OnThreadStart(); + kernel.CurrentScheduler()->OnThreadStart(kernel); while (true) { auto* physical_core = &kernel.CurrentPhysicalCore(); while (!physical_core->IsInterrupted()) { - physical_core->RunThread(thread); + physical_core->RunThread(kernel, thread); physical_core = &kernel.CurrentPhysicalCore(); } - - HandleInterrupt(); + HandleInterrupt(kernel); } } -void CpuManager::MultiCoreRunIdleThread() { +void CpuManager::MultiCoreRunIdleThread(Kernel::KernelCore& kernel) { // Not accurate to HOS. Remove this entire method when singlecore is removed. // See notes in KScheduler::ScheduleImpl for more information about why this // is inaccurate. - - auto& kernel = system.Kernel(); - kernel.CurrentScheduler()->OnThreadStart(); - + kernel.CurrentScheduler()->OnThreadStart(kernel); while (true) { auto& physical_core = kernel.CurrentPhysicalCore(); if (!physical_core.IsInterrupted()) { physical_core.Idle(); } - - HandleInterrupt(); + HandleInterrupt(kernel); } } @@ -109,15 +103,14 @@ void CpuManager::MultiCoreRunIdleThread() { /// SingleCore /// /////////////////////////////////////////////////////////////////////////////// -void CpuManager::SingleCoreRunGuestThread() { - auto& kernel = system.Kernel(); +void CpuManager::SingleCoreRunGuestThread(Kernel::KernelCore& kernel) { auto* thread = Kernel::GetCurrentThreadPointer(kernel); - kernel.CurrentScheduler()->OnThreadStart(); + kernel.CurrentScheduler()->OnThreadStart(kernel); while (true) { auto* physical_core = &kernel.CurrentPhysicalCore(); if (!physical_core->IsInterrupted()) { - physical_core->RunThread(thread); + physical_core->RunThread(kernel, thread); physical_core = &kernel.CurrentPhysicalCore(); } @@ -125,26 +118,22 @@ void CpuManager::SingleCoreRunGuestThread() { system.CoreTiming().Advance(); kernel.SetIsPhantomModeForSingleCore(false); - PreemptSingleCore(); - HandleInterrupt(); + PreemptSingleCore(kernel); + HandleInterrupt(kernel); } } -void CpuManager::SingleCoreRunIdleThread() { - auto& kernel = system.Kernel(); - kernel.CurrentScheduler()->OnThreadStart(); - +void CpuManager::SingleCoreRunIdleThread(Kernel::KernelCore& kernel) { + kernel.CurrentScheduler()->OnThreadStart(kernel); while (true) { - PreemptSingleCore(false); + PreemptSingleCore(kernel, false); system.CoreTiming().AddTicks(1000U); idle_count++; - HandleInterrupt(); + HandleInterrupt(kernel); } } -void CpuManager::PreemptSingleCore(bool from_running_environment) { - auto& kernel = system.Kernel(); - +void CpuManager::PreemptSingleCore(Kernel::KernelCore& kernel, bool from_running_environment) { if (idle_count >= 4 || from_running_environment) { if (!from_running_environment) { system.CoreTiming().Idle(); @@ -156,7 +145,7 @@ void CpuManager::PreemptSingleCore(bool from_running_environment) { } current_core.store((current_core + 1) % Core::Hardware::NUM_CPU_CORES); system.CoreTiming().ResetTicks(); - kernel.Scheduler(current_core).PreemptSingleCore(); + kernel.Scheduler(current_core).PreemptSingleCore(kernel); // We've now been scheduled again, and we may have exchanged schedulers. // Reload the scheduler in case it's different. @@ -165,20 +154,16 @@ void CpuManager::PreemptSingleCore(bool from_running_environment) { } } -void CpuManager::GuestActivate() { +void CpuManager::GuestActivate(Kernel::KernelCore& kernel) { // Similar to the HorizonKernelMain callback in HOS - auto& kernel = system.Kernel(); auto* scheduler = kernel.CurrentScheduler(); - - scheduler->Activate(); + scheduler->Activate(kernel); UNREACHABLE(); } -void CpuManager::ShutdownThread() { - auto& kernel = system.Kernel(); +void CpuManager::ShutdownThread(Kernel::KernelCore& kernel) { auto* thread = kernel.GetCurrentEmuThread(); auto core = is_multicore ? kernel.CurrentPhysicalCoreIndex() : 0; - Common::Fiber::YieldTo(thread->GetHostContext(), *core_data[core].host_context); UNREACHABLE(); } |
