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) { | |||
| 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 | ||
| 701 | void KScheduler::ScheduleImpl() { | 702 | void 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{}; |