diff options
| author | 2024-02-14 16:57:20 -0500 | |
|---|---|---|
| committer | 2024-02-14 17:03:50 -0500 | |
| commit | af42482565daf646d89a0a3cd8001a527ab76621 (patch) | |
| tree | 3e28818b929f30d13cc190a9203697960bb6db7b /src/core/hle/kernel/kernel.cpp | |
| parent | Merge pull request #12996 from german77/settings-ipc (diff) | |
| download | yuzu-af42482565daf646d89a0a3cd8001a527ab76621.tar.gz yuzu-af42482565daf646d89a0a3cd8001a527ab76621.tar.xz yuzu-af42482565daf646d89a0a3cd8001a527ab76621.zip | |
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 { | |||
| 1204 | return *impl->hidbus_shared_mem; | 1204 | return *impl->hidbus_shared_mem; |
| 1205 | } | 1205 | } |
| 1206 | 1206 | ||
| 1207 | void KernelCore::SuspendApplication(bool suspended) { | 1207 | void KernelCore::SuspendEmulation(bool suspended) { |
| 1208 | const bool should_suspend{exception_exited || suspended}; | 1208 | const bool should_suspend{exception_exited || suspended}; |
| 1209 | const auto activity = | 1209 | auto processes = GetProcessList(); |
| 1210 | should_suspend ? Svc::ProcessActivity::Paused : Svc::ProcessActivity::Runnable; | ||
| 1211 | 1210 | ||
| 1212 | // Get the application process. | 1211 | for (auto& process : processes) { |
| 1213 | KScopedAutoObject<KProcess> process = ApplicationProcess(); | 1212 | KScopedLightLock ll{process->GetListLock()}; |
| 1214 | if (process.IsNull()) { | 1213 | |
| 1215 | return; | 1214 | for (auto& thread : process->GetThreadList()) { |
| 1215 | if (should_suspend) { | ||
| 1216 | thread.RequestSuspend(SuspendType::System); | ||
| 1217 | } else { | ||
| 1218 | thread.Resume(SuspendType::System); | ||
| 1219 | } | ||
| 1220 | } | ||
| 1216 | } | 1221 | } |
| 1217 | 1222 | ||
| 1218 | // Set the new activity. | 1223 | if (!should_suspend) { |
| 1219 | process->SetActivity(activity); | 1224 | return; |
| 1225 | } | ||
| 1220 | 1226 | ||
| 1221 | // Wait for process execution to stop. | 1227 | // Wait for process execution to stop. |
| 1222 | bool must_wait{should_suspend}; | 1228 | // KernelCore::SuspendEmulation must be called from locked context, |
| 1223 | 1229 | // or we could race another call, interfering with waiting. | |
| 1224 | // KernelCore::SuspendApplication must be called from locked context, | 1230 | const auto TryWait = [&]() { |
| 1225 | // or we could race another call to SetActivity, interfering with waiting. | ||
| 1226 | while (must_wait) { | ||
| 1227 | KScopedSchedulerLock sl{*this}; | 1231 | KScopedSchedulerLock sl{*this}; |
| 1228 | 1232 | ||
| 1229 | // Assume that all threads have finished running. | 1233 | for (auto& process : processes) { |
| 1230 | must_wait = false; | 1234 | for (auto i = 0; i < static_cast<s32>(Core::Hardware::NUM_CPU_CORES); ++i) { |
| 1231 | 1235 | if (Scheduler(i).GetSchedulerCurrentThread()->GetOwnerProcess() == | |
| 1232 | for (auto i = 0; i < static_cast<s32>(Core::Hardware::NUM_CPU_CORES); ++i) { | 1236 | process.GetPointerUnsafe()) { |
| 1233 | if (Scheduler(i).GetSchedulerCurrentThread()->GetOwnerProcess() == | 1237 | // A thread has not finished running yet. |
| 1234 | process.GetPointerUnsafe()) { | 1238 | // Continue waiting. |
| 1235 | // A thread has not finished running yet. | 1239 | return false; |
| 1236 | // Continue waiting. | 1240 | } |
| 1237 | must_wait = true; | ||
| 1238 | } | 1241 | } |
| 1239 | } | 1242 | } |
| 1243 | |||
| 1244 | return true; | ||
| 1245 | }; | ||
| 1246 | |||
| 1247 | while (!TryWait()) { | ||
| 1248 | // ... | ||
| 1240 | } | 1249 | } |
| 1241 | } | 1250 | } |
| 1242 | 1251 | ||
| @@ -1260,7 +1269,7 @@ bool KernelCore::IsShuttingDown() const { | |||
| 1260 | 1269 | ||
| 1261 | void KernelCore::ExceptionalExitApplication() { | 1270 | void KernelCore::ExceptionalExitApplication() { |
| 1262 | exception_exited = true; | 1271 | exception_exited = true; |
| 1263 | SuspendApplication(true); | 1272 | SuspendEmulation(true); |
| 1264 | } | 1273 | } |
| 1265 | 1274 | ||
| 1266 | void KernelCore::EnterSVCProfile() { | 1275 | void KernelCore::EnterSVCProfile() { |