kernel: avoid racy behavior in global suspension
This commit is contained in:
parent
9fc1bcc7b2
commit
85527cc7c7
|
@ -1109,16 +1109,28 @@ void KernelCore::Suspend(bool suspended) {
|
||||||
const bool should_suspend{exception_exited || suspended};
|
const bool should_suspend{exception_exited || suspended};
|
||||||
const auto activity = should_suspend ? ProcessActivity::Paused : ProcessActivity::Runnable;
|
const auto activity = should_suspend ? ProcessActivity::Paused : ProcessActivity::Runnable;
|
||||||
|
|
||||||
for (auto* process : GetProcessList()) {
|
std::vector<KScopedAutoObject<KThread>> process_threads;
|
||||||
process->SetActivity(activity);
|
{
|
||||||
|
KScopedSchedulerLock sl{*this};
|
||||||
|
|
||||||
|
if (auto* process = CurrentProcess(); process != nullptr) {
|
||||||
|
process->SetActivity(activity);
|
||||||
|
|
||||||
|
if (!should_suspend) {
|
||||||
|
// Runnable now; no need to wait.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (should_suspend) {
|
|
||||||
// Wait for execution to stop
|
|
||||||
for (auto* thread : process->GetThreadList()) {
|
for (auto* thread : process->GetThreadList()) {
|
||||||
thread->WaitUntilSuspended();
|
process_threads.emplace_back(thread);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Wait for execution to stop.
|
||||||
|
for (auto& thread : process_threads) {
|
||||||
|
thread->WaitUntilSuspended();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void KernelCore::ShutdownCores() {
|
void KernelCore::ShutdownCores() {
|
||||||
|
|
Reference in New Issue