diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/core/hle/kernel/k_scheduler.cpp | 18 | ||||
-rw-r--r-- | src/core/hle/kernel/k_thread.h | 1 |
2 files changed, 16 insertions, 3 deletions
diff --git a/src/core/hle/kernel/k_scheduler.cpp b/src/core/hle/kernel/k_scheduler.cpp index 5bdbd9a9b..e99122f4c 100644 --- a/src/core/hle/kernel/k_scheduler.cpp +++ b/src/core/hle/kernel/k_scheduler.cpp @@ -668,6 +668,7 @@ void KScheduler::Unload(KThread* thread) { } else { prev_thread = nullptr; } + thread->context_guard.unlock(); } } @@ -700,15 +701,23 @@ void KScheduler::SwitchContextStep2() { void KScheduler::ScheduleImpl() { KThread* previous_thread = current_thread; - current_thread = state.highest_priority_thread; + KThread* next_thread = state.highest_priority_thread; state.needs_scheduling = false; - if (current_thread == previous_thread) { + // We never want to schedule a null thread, so use the idle thread if we don't have a next. + if (next_thread == nullptr) { + next_thread = idle_thread; + } + + // If we're not actually switching thread, there's nothing to do. + if (next_thread == current_thread) { guard.unlock(); return; } + current_thread = next_thread; + Process* const previous_process = system.Kernel().CurrentProcess(); UpdateLastContextSwitchTime(previous_thread, previous_process); @@ -748,10 +757,13 @@ void KScheduler::SwitchToCurrent() { }; do { if (current_thread != nullptr) { + current_thread->context_guard.lock(); if (current_thread->GetRawState() != ThreadState::Runnable) { + current_thread->context_guard.unlock(); break; } - if (static_cast<u32>(current_thread->GetActiveCore()) != core_id) { + if (current_thread->GetActiveCore() != core_id) { + current_thread->context_guard.unlock(); break; } } diff --git a/src/core/hle/kernel/k_thread.h b/src/core/hle/kernel/k_thread.h index 7845821ba..eeddf5a65 100644 --- a/src/core/hle/kernel/k_thread.h +++ b/src/core/hle/kernel/k_thread.h @@ -712,6 +712,7 @@ private: s8 priority_inheritance_count{}; bool resource_limit_release_hint{}; StackParameters stack_parameters{}; + Common::SpinLock context_guard{}; // For emulation std::shared_ptr<Common::Fiber> host_context{}; |