kern: update pinning semantics for terminating threads

This commit is contained in:
Michael Scire
2021-04-07 15:30:13 -07:00
committed by SciresM
parent afb1d68d06
commit 6faa3534bf
4 changed files with 48 additions and 15 deletions

View File

@@ -34,6 +34,13 @@ namespace ams::kern {
KScopedLightLock proc_lk(process->GetListLock());
KScopedSchedulerLock sl;
if (thread_to_not_terminate != nullptr && process->GetPinnedThread(GetCurrentCoreId()) == thread_to_not_terminate) {
/* NOTE: Here Nintendo unpins the current thread instead of the thread_to_not_terminate. */
/* This is valid because the only caller which uses non-nullptr as argument uses GetCurrentThreadPointer(), */
/* but it's still notable because it seems incorrect at first glance. */
process->UnpinCurrentThread();
}
auto &thread_list = process->GetThreadList();
for (auto it = thread_list.begin(); it != thread_list.end(); ++it) {
if (KThread *thread = std::addressof(*it); thread != thread_to_not_terminate) {
@@ -1020,12 +1027,15 @@ namespace ams::kern {
const s32 core_id = GetCurrentCoreId();
KThread *cur_thread = GetCurrentThreadPointer();
/* Pin it. */
this->PinThread(core_id, cur_thread);
cur_thread->Pin();
/* If the thread isn't terminated, pin it. */
if (!cur_thread->IsTerminationRequested()) {
/* Pin it. */
this->PinThread(core_id, cur_thread);
cur_thread->Pin();
/* An update is needed. */
KScheduler::SetSchedulerUpdateNeeded();
/* An update is needed. */
KScheduler::SetSchedulerUpdateNeeded();
}
}
void KProcess::UnpinCurrentThread() {
@@ -1043,6 +1053,20 @@ namespace ams::kern {
KScheduler::SetSchedulerUpdateNeeded();
}
void KProcess::UnpinThread(KThread *thread) {
MESOSPHERE_ASSERT(KScheduler::IsSchedulerLockedByCurrentThread());
/* Get the thread's core id. */
const auto core_id = thread->GetActiveCore();
/* Unpin it. */
this->UnpinThread(core_id, thread);
thread->Unpin();
/* An update is needed. */
KScheduler::SetSchedulerUpdateNeeded();
}
Result KProcess::GetThreadList(s32 *out_num_threads, ams::kern::svc::KUserPointer<u64 *> out_thread_ids, s32 max_out_count) {
/* Lock the list. */
KScopedLightLock lk(m_list_lock);