diff options
Diffstat (limited to 'src/core/hle/kernel/scheduler.cpp')
-rw-r--r-- | src/core/hle/kernel/scheduler.cpp | 39 |
1 files changed, 19 insertions, 20 deletions
diff --git a/src/core/hle/kernel/scheduler.cpp b/src/core/hle/kernel/scheduler.cpp index f93e5e4b0..5cbd3b912 100644 --- a/src/core/hle/kernel/scheduler.cpp +++ b/src/core/hle/kernel/scheduler.cpp @@ -131,7 +131,8 @@ u32 GlobalScheduler::SelectThreads() { u32 cores_needing_context_switch{}; for (u32 core = 0; core < Core::Hardware::NUM_CPU_CORES; core++) { Scheduler& sched = kernel.Scheduler(core); - ASSERT(top_threads[core] == nullptr || top_threads[core]->GetProcessorID() == core); + ASSERT(top_threads[core] == nullptr || + static_cast<u32>(top_threads[core]->GetProcessorID()) == core); if (update_thread(top_threads[core], sched)) { cores_needing_context_switch |= (1ul << core); } @@ -663,32 +664,26 @@ void Scheduler::Reload() { } void Scheduler::SwitchContextStep2() { - Thread* previous_thread = current_thread_prev.get(); - Thread* new_thread = selected_thread.get(); - // Load context of new thread - Process* const previous_process = - previous_thread != nullptr ? previous_thread->GetOwnerProcess() : nullptr; - - if (new_thread) { - ASSERT_MSG(new_thread->GetSchedulingStatus() == ThreadSchedStatus::Runnable, + if (selected_thread) { + ASSERT_MSG(selected_thread->GetSchedulingStatus() == ThreadSchedStatus::Runnable, "Thread must be runnable."); // Cancel any outstanding wakeup events for this thread - new_thread->SetIsRunning(true); - new_thread->last_running_ticks = system.CoreTiming().GetCPUTicks(); - new_thread->SetWasRunning(false); + selected_thread->SetIsRunning(true); + selected_thread->last_running_ticks = system.CoreTiming().GetCPUTicks(); + selected_thread->SetWasRunning(false); auto* const thread_owner_process = current_thread->GetOwnerProcess(); if (thread_owner_process != nullptr) { system.Kernel().MakeCurrentProcess(thread_owner_process); } - if (!new_thread->IsHLEThread()) { - Core::ARM_Interface& cpu_core = new_thread->ArmInterface(); - cpu_core.LoadContext(new_thread->GetContext32()); - cpu_core.LoadContext(new_thread->GetContext64()); - cpu_core.SetTlsAddress(new_thread->GetTLSAddress()); - cpu_core.SetTPIDR_EL0(new_thread->GetTPIDR_EL0()); + if (!selected_thread->IsHLEThread()) { + Core::ARM_Interface& cpu_core = selected_thread->ArmInterface(); + cpu_core.LoadContext(selected_thread->GetContext32()); + cpu_core.LoadContext(selected_thread->GetContext64()); + cpu_core.SetTlsAddress(selected_thread->GetTLSAddress()); + cpu_core.SetTPIDR_EL0(selected_thread->GetTPIDR_EL0()); cpu_core.ChangeProcessorID(this->core_id); cpu_core.ClearExclusiveState(); } @@ -761,7 +756,11 @@ void Scheduler::SwitchToCurrent() { current_thread = selected_thread; is_context_switch_pending = false; } - while (!is_context_switch_pending) { + const auto is_switch_pending = [this] { + std::scoped_lock lock{guard}; + return is_context_switch_pending; + }; + do { if (current_thread != nullptr && !current_thread->IsHLEThread()) { current_thread->context_guard.lock(); if (!current_thread->IsRunnable()) { @@ -780,7 +779,7 @@ void Scheduler::SwitchToCurrent() { next_context = &idle_thread->GetHostContext(); } Common::Fiber::YieldTo(switch_fiber, *next_context); - } + } while (!is_switch_pending()); } } |