diff options
| author | Narr the Reg <juangerman-13@hotmail.com> | 2024-02-17 17:00:07 -0600 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-02-17 17:00:07 -0600 |
| commit | 53f8383354470d58ab7a6cb5303708d59883adfa (patch) | |
| tree | 66f830fa18e36c599315475670dfd92c5ef73b45 /src/core/hle/kernel/kernel.cpp | |
| parent | 36108ce2bee37aff0a3beb58c6a1e48193671949 (diff) | |
| parent | af42482565daf646d89a0a3cd8001a527ab76621 (diff) | |
Merge pull request #13017 from liamwhite/suspension
kernel: add and enable system suspend type
Diffstat (limited to 'src/core/hle/kernel/kernel.cpp')
| -rw-r--r-- | src/core/hle/kernel/kernel.cpp | 57 |
1 files changed, 33 insertions, 24 deletions
diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp index 34b25be66..4f4b02fac 100644 --- a/src/core/hle/kernel/kernel.cpp +++ b/src/core/hle/kernel/kernel.cpp @@ -1204,39 +1204,48 @@ const Kernel::KSharedMemory& KernelCore::GetHidBusSharedMem() const { return *impl->hidbus_shared_mem; } -void KernelCore::SuspendApplication(bool suspended) { +void KernelCore::SuspendEmulation(bool suspended) { const bool should_suspend{exception_exited || suspended}; - const auto activity = - should_suspend ? Svc::ProcessActivity::Paused : Svc::ProcessActivity::Runnable; + auto processes = GetProcessList(); - // Get the application process. - KScopedAutoObject<KProcess> process = ApplicationProcess(); - if (process.IsNull()) { - return; + for (auto& process : processes) { + KScopedLightLock ll{process->GetListLock()}; + + for (auto& thread : process->GetThreadList()) { + if (should_suspend) { + thread.RequestSuspend(SuspendType::System); + } else { + thread.Resume(SuspendType::System); + } + } } - // Set the new activity. - process->SetActivity(activity); + if (!should_suspend) { + return; + } // Wait for process execution to stop. - bool must_wait{should_suspend}; - - // KernelCore::SuspendApplication must be called from locked context, - // or we could race another call to SetActivity, interfering with waiting. - while (must_wait) { + // KernelCore::SuspendEmulation must be called from locked context, + // or we could race another call, interfering with waiting. + const auto TryWait = [&]() { KScopedSchedulerLock sl{*this}; - // Assume that all threads have finished running. - must_wait = false; - - for (auto i = 0; i < static_cast<s32>(Core::Hardware::NUM_CPU_CORES); ++i) { - if (Scheduler(i).GetSchedulerCurrentThread()->GetOwnerProcess() == - process.GetPointerUnsafe()) { - // A thread has not finished running yet. - // Continue waiting. - must_wait = true; + for (auto& process : processes) { + for (auto i = 0; i < static_cast<s32>(Core::Hardware::NUM_CPU_CORES); ++i) { + if (Scheduler(i).GetSchedulerCurrentThread()->GetOwnerProcess() == + process.GetPointerUnsafe()) { + // A thread has not finished running yet. + // Continue waiting. + return false; + } } } + + return true; + }; + + while (!TryWait()) { + // ... } } @@ -1260,7 +1269,7 @@ bool KernelCore::IsShuttingDown() const { void KernelCore::ExceptionalExitApplication() { exception_exited = true; - SuspendApplication(true); + SuspendEmulation(true); } void KernelCore::EnterSVCProfile() { |
