diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/core/hle/kernel/scheduler.cpp | 58 | ||||
| -rw-r--r-- | src/core/hle/kernel/scheduler.h | 2 |
2 files changed, 14 insertions, 46 deletions
diff --git a/src/core/hle/kernel/scheduler.cpp b/src/core/hle/kernel/scheduler.cpp index 0805e9914..5c63b0b4a 100644 --- a/src/core/hle/kernel/scheduler.cpp +++ b/src/core/hle/kernel/scheduler.cpp | |||
| @@ -618,8 +618,7 @@ void Scheduler::OnThreadStart() { | |||
| 618 | SwitchContextStep2(); | 618 | SwitchContextStep2(); |
| 619 | } | 619 | } |
| 620 | 620 | ||
| 621 | void Scheduler::Unload() { | 621 | void Scheduler::Unload(Thread* thread) { |
| 622 | Thread* thread = current_thread.get(); | ||
| 623 | if (thread) { | 622 | if (thread) { |
| 624 | thread->last_running_ticks = system.CoreTiming().GetCPUTicks(); | 623 | thread->last_running_ticks = system.CoreTiming().GetCPUTicks(); |
| 625 | thread->SetIsRunning(false); | 624 | thread->SetIsRunning(false); |
| @@ -639,8 +638,11 @@ void Scheduler::Unload() { | |||
| 639 | } | 638 | } |
| 640 | } | 639 | } |
| 641 | 640 | ||
| 642 | void Scheduler::Reload() { | 641 | void Scheduler::Unload() { |
| 643 | Thread* thread = current_thread.get(); | 642 | Unload(current_thread.get()); |
| 643 | } | ||
| 644 | |||
| 645 | void Scheduler::Reload(Thread* thread) { | ||
| 644 | if (thread) { | 646 | if (thread) { |
| 645 | ASSERT_MSG(thread->GetSchedulingStatus() == ThreadSchedStatus::Runnable, | 647 | ASSERT_MSG(thread->GetSchedulingStatus() == ThreadSchedStatus::Runnable, |
| 646 | "Thread must be runnable."); | 648 | "Thread must be runnable."); |
| @@ -665,30 +667,13 @@ void Scheduler::Reload() { | |||
| 665 | } | 667 | } |
| 666 | } | 668 | } |
| 667 | 669 | ||
| 670 | void Scheduler::Reload() { | ||
| 671 | Reload(current_thread.get()); | ||
| 672 | } | ||
| 673 | |||
| 668 | void Scheduler::SwitchContextStep2() { | 674 | void Scheduler::SwitchContextStep2() { |
| 669 | // Load context of new thread | 675 | // Load context of new thread |
| 670 | if (selected_thread) { | 676 | Reload(selected_thread.get()); |
| 671 | ASSERT_MSG(selected_thread->GetSchedulingStatus() == ThreadSchedStatus::Runnable, | ||
| 672 | "Thread must be runnable."); | ||
| 673 | |||
| 674 | // Cancel any outstanding wakeup events for this thread | ||
| 675 | selected_thread->SetIsRunning(true); | ||
| 676 | selected_thread->last_running_ticks = system.CoreTiming().GetCPUTicks(); | ||
| 677 | selected_thread->SetWasRunning(false); | ||
| 678 | |||
| 679 | auto* const thread_owner_process = current_thread->GetOwnerProcess(); | ||
| 680 | if (thread_owner_process != nullptr) { | ||
| 681 | system.Kernel().MakeCurrentProcess(thread_owner_process); | ||
| 682 | } | ||
| 683 | if (!selected_thread->IsHLEThread()) { | ||
| 684 | Core::ARM_Interface& cpu_core = system.ArmInterface(core_id); | ||
| 685 | cpu_core.LoadContext(selected_thread->GetContext32()); | ||
| 686 | cpu_core.LoadContext(selected_thread->GetContext64()); | ||
| 687 | cpu_core.SetTlsAddress(selected_thread->GetTLSAddress()); | ||
| 688 | cpu_core.SetTPIDR_EL0(selected_thread->GetTPIDR_EL0()); | ||
| 689 | cpu_core.ClearExclusiveState(); | ||
| 690 | } | ||
| 691 | } | ||
| 692 | 677 | ||
| 693 | TryDoContextSwitch(); | 678 | TryDoContextSwitch(); |
| 694 | } | 679 | } |
| @@ -712,26 +697,7 @@ void Scheduler::SwitchContext() { | |||
| 712 | UpdateLastContextSwitchTime(previous_thread, previous_process); | 697 | UpdateLastContextSwitchTime(previous_thread, previous_process); |
| 713 | 698 | ||
| 714 | // Save context for previous thread | 699 | // Save context for previous thread |
| 715 | if (previous_thread) { | 700 | Unload(previous_thread); |
| 716 | if (new_thread != nullptr && new_thread->IsSuspendThread()) { | ||
| 717 | previous_thread->SetWasRunning(true); | ||
| 718 | } | ||
| 719 | previous_thread->last_running_ticks = system.CoreTiming().GetCPUTicks(); | ||
| 720 | previous_thread->SetIsRunning(false); | ||
| 721 | if (previous_thread->IsContinuousOnSVC() && !previous_thread->IsHLEThread()) { | ||
| 722 | system.ArmInterface(core_id).ExceptionalExit(); | ||
| 723 | previous_thread->SetContinuousOnSVC(false); | ||
| 724 | } | ||
| 725 | if (!previous_thread->IsHLEThread() && !previous_thread->HasExited()) { | ||
| 726 | Core::ARM_Interface& cpu_core = system.ArmInterface(core_id); | ||
| 727 | cpu_core.SaveContext(previous_thread->GetContext32()); | ||
| 728 | cpu_core.SaveContext(previous_thread->GetContext64()); | ||
| 729 | // Save the TPIDR_EL0 system register in case it was modified. | ||
| 730 | previous_thread->SetTPIDR_EL0(cpu_core.GetTPIDR_EL0()); | ||
| 731 | cpu_core.ClearExclusiveState(); | ||
| 732 | } | ||
| 733 | previous_thread->context_guard.unlock(); | ||
| 734 | } | ||
| 735 | 701 | ||
| 736 | std::shared_ptr<Common::Fiber>* old_context; | 702 | std::shared_ptr<Common::Fiber>* old_context; |
| 737 | if (previous_thread != nullptr) { | 703 | if (previous_thread != nullptr) { |
diff --git a/src/core/hle/kernel/scheduler.h b/src/core/hle/kernel/scheduler.h index b6f04dcea..68db4a5ef 100644 --- a/src/core/hle/kernel/scheduler.h +++ b/src/core/hle/kernel/scheduler.h | |||
| @@ -212,8 +212,10 @@ public: | |||
| 212 | 212 | ||
| 213 | /// The next two are for SingleCore Only. | 213 | /// The next two are for SingleCore Only. |
| 214 | /// Unload current thread before preempting core. | 214 | /// Unload current thread before preempting core. |
| 215 | void Unload(Thread* thread); | ||
| 215 | void Unload(); | 216 | void Unload(); |
| 216 | /// Reload current thread after core preemption. | 217 | /// Reload current thread after core preemption. |
| 218 | void Reload(Thread* thread); | ||
| 217 | void Reload(); | 219 | void Reload(); |
| 218 | 220 | ||
| 219 | /// Gets the current running thread | 221 | /// Gets the current running thread |