From 3a6f205e6f36aed71c187040ed006128cb8a1e66 Mon Sep 17 00:00:00 2001 From: PixelyIon Date: Wed, 30 Nov 2022 04:06:36 +0530 Subject: [PATCH] Clear `insertThreadOnResume` in `RemoveThread` A thread can be paused while it is in a synchronization primitive which will do `RemoveThread`, we need to update the state of `insertThreadOnResume` in this case by clearing it so it isn't incorrectly reinserted on resuming the thread. --- app/src/main/cpp/skyline/kernel/scheduler.cpp | 25 +++++++++++-------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/app/src/main/cpp/skyline/kernel/scheduler.cpp b/app/src/main/cpp/skyline/kernel/scheduler.cpp index 0f78c153..7ea3db87 100644 --- a/app/src/main/cpp/skyline/kernel/scheduler.cpp +++ b/app/src/main/cpp/skyline/kernel/scheduler.cpp @@ -257,20 +257,25 @@ namespace skyline::kernel { void Scheduler::RemoveThread() { auto &thread{state.thread}; - auto &core{cores.at(thread->coreId)}; { + auto &core{cores.at(thread->coreId)}; std::unique_lock lock(core.mutex); - auto it{std::find(core.queue.begin(), core.queue.end(), thread)}; - if (it != core.queue.end()) { - it = core.queue.erase(it); - if (it == core.queue.begin()) { - // We need to update the averageTimeslice accordingly, if we've been unscheduled by this - if (thread->timesliceStart) - thread->averageTimeslice = (thread->averageTimeslice / 4) + (3 * (util::GetTimeTicks() - thread->timesliceStart / 4)); - if (it != core.queue.end()) - (*it)->scheduleCondition.notify_one(); // We need to wake the thread at the front of the queue, if we were at the front previously + if (!thread->isPaused) { + auto it{std::find(core.queue.begin(), core.queue.end(), thread)}; + if (it != core.queue.end()) { + it = core.queue.erase(it); + if (it == core.queue.begin()) { + // We need to update the averageTimeslice accordingly, if we've been unscheduled by this + if (thread->timesliceStart) + thread->averageTimeslice = (thread->averageTimeslice / 4) + (3 * (util::GetTimeTicks() - thread->timesliceStart / 4)); + + if (it != core.queue.end()) + (*it)->scheduleCondition.notify_one(); // We need to wake the thread at the front of the queue, if we were at the front previously + } } + } else { + thread->insertThreadOnResume = false; } }