summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/core/hle/kernel/k_scheduler.cpp18
-rw-r--r--src/core/hle/kernel/k_thread.h1
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) {
668 } else { 668 } else {
669 prev_thread = nullptr; 669 prev_thread = nullptr;
670 } 670 }
671 thread->context_guard.unlock();
671 } 672 }
672} 673}
673 674
@@ -700,15 +701,23 @@ void KScheduler::SwitchContextStep2() {
700 701
701void KScheduler::ScheduleImpl() { 702void KScheduler::ScheduleImpl() {
702 KThread* previous_thread = current_thread; 703 KThread* previous_thread = current_thread;
703 current_thread = state.highest_priority_thread; 704 KThread* next_thread = state.highest_priority_thread;
704 705
705 state.needs_scheduling = false; 706 state.needs_scheduling = false;
706 707
707 if (current_thread == previous_thread) { 708 // We never want to schedule a null thread, so use the idle thread if we don't have a next.
709 if (next_thread == nullptr) {
710 next_thread = idle_thread;
711 }
712
713 // If we're not actually switching thread, there's nothing to do.
714 if (next_thread == current_thread) {
708 guard.unlock(); 715 guard.unlock();
709 return; 716 return;
710 } 717 }
711 718
719 current_thread = next_thread;
720
712 Process* const previous_process = system.Kernel().CurrentProcess(); 721 Process* const previous_process = system.Kernel().CurrentProcess();
713 722
714 UpdateLastContextSwitchTime(previous_thread, previous_process); 723 UpdateLastContextSwitchTime(previous_thread, previous_process);
@@ -748,10 +757,13 @@ void KScheduler::SwitchToCurrent() {
748 }; 757 };
749 do { 758 do {
750 if (current_thread != nullptr) { 759 if (current_thread != nullptr) {
760 current_thread->context_guard.lock();
751 if (current_thread->GetRawState() != ThreadState::Runnable) { 761 if (current_thread->GetRawState() != ThreadState::Runnable) {
762 current_thread->context_guard.unlock();
752 break; 763 break;
753 } 764 }
754 if (static_cast<u32>(current_thread->GetActiveCore()) != core_id) { 765 if (current_thread->GetActiveCore() != core_id) {
766 current_thread->context_guard.unlock();
755 break; 767 break;
756 } 768 }
757 } 769 }
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:
712 s8 priority_inheritance_count{}; 712 s8 priority_inheritance_count{};
713 bool resource_limit_release_hint{}; 713 bool resource_limit_release_hint{};
714 StackParameters stack_parameters{}; 714 StackParameters stack_parameters{};
715 Common::SpinLock context_guard{};
715 716
716 // For emulation 717 // For emulation
717 std::shared_ptr<Common::Fiber> host_context{}; 718 std::shared_ptr<Common::Fiber> host_context{};