diff options
| author | 2020-12-03 15:32:45 -0800 | |
|---|---|---|
| committer | 2020-12-03 15:32:45 -0800 | |
| commit | 69aaad9b9684570284efcdb5921e54d0f5983838 (patch) | |
| tree | 364256228dfcdfc989a597aca2a6c753b173f93a /src/core/hle/kernel/scheduler.cpp | |
| parent | Merge pull request #5059 from lioncash/mouse (diff) | |
| parent | kernel: scheduler: Minor cleanup to remove duplicated code. (diff) | |
| download | yuzu-69aaad9b9684570284efcdb5921e54d0f5983838.tar.gz yuzu-69aaad9b9684570284efcdb5921e54d0f5983838.tar.xz yuzu-69aaad9b9684570284efcdb5921e54d0f5983838.zip | |
Merge pull request #4996 from bunnei/use-4jits
Kernel: Refactor to use 4-instances of Dynarmic & various cleanups and improvements
Diffstat (limited to 'src/core/hle/kernel/scheduler.cpp')
| -rw-r--r-- | src/core/hle/kernel/scheduler.cpp | 66 |
1 files changed, 18 insertions, 48 deletions
diff --git a/src/core/hle/kernel/scheduler.cpp b/src/core/hle/kernel/scheduler.cpp index 6b7db5372..5c63b0b4a 100644 --- a/src/core/hle/kernel/scheduler.cpp +++ b/src/core/hle/kernel/scheduler.cpp | |||
| @@ -618,14 +618,16 @@ 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->SetContinuousOnSVC(false); | ||
| 625 | thread->last_running_ticks = system.CoreTiming().GetCPUTicks(); | 623 | thread->last_running_ticks = system.CoreTiming().GetCPUTicks(); |
| 626 | thread->SetIsRunning(false); | 624 | thread->SetIsRunning(false); |
| 625 | if (thread->IsContinuousOnSVC() && !thread->IsHLEThread()) { | ||
| 626 | system.ArmInterface(core_id).ExceptionalExit(); | ||
| 627 | thread->SetContinuousOnSVC(false); | ||
| 628 | } | ||
| 627 | if (!thread->IsHLEThread() && !thread->HasExited()) { | 629 | if (!thread->IsHLEThread() && !thread->HasExited()) { |
| 628 | Core::ARM_Interface& cpu_core = thread->ArmInterface(); | 630 | Core::ARM_Interface& cpu_core = system.ArmInterface(core_id); |
| 629 | cpu_core.SaveContext(thread->GetContext32()); | 631 | cpu_core.SaveContext(thread->GetContext32()); |
| 630 | cpu_core.SaveContext(thread->GetContext64()); | 632 | cpu_core.SaveContext(thread->GetContext64()); |
| 631 | // Save the TPIDR_EL0 system register in case it was modified. | 633 | // Save the TPIDR_EL0 system register in case it was modified. |
| @@ -636,8 +638,11 @@ void Scheduler::Unload() { | |||
| 636 | } | 638 | } |
| 637 | } | 639 | } |
| 638 | 640 | ||
| 639 | void Scheduler::Reload() { | 641 | void Scheduler::Unload() { |
| 640 | Thread* thread = current_thread.get(); | 642 | Unload(current_thread.get()); |
| 643 | } | ||
| 644 | |||
| 645 | void Scheduler::Reload(Thread* thread) { | ||
| 641 | if (thread) { | 646 | if (thread) { |
| 642 | ASSERT_MSG(thread->GetSchedulingStatus() == ThreadSchedStatus::Runnable, | 647 | ASSERT_MSG(thread->GetSchedulingStatus() == ThreadSchedStatus::Runnable, |
| 643 | "Thread must be runnable."); | 648 | "Thread must be runnable."); |
| @@ -652,42 +657,23 @@ void Scheduler::Reload() { | |||
| 652 | system.Kernel().MakeCurrentProcess(thread_owner_process); | 657 | system.Kernel().MakeCurrentProcess(thread_owner_process); |
| 653 | } | 658 | } |
| 654 | if (!thread->IsHLEThread()) { | 659 | if (!thread->IsHLEThread()) { |
| 655 | Core::ARM_Interface& cpu_core = thread->ArmInterface(); | 660 | Core::ARM_Interface& cpu_core = system.ArmInterface(core_id); |
| 656 | cpu_core.LoadContext(thread->GetContext32()); | 661 | cpu_core.LoadContext(thread->GetContext32()); |
| 657 | cpu_core.LoadContext(thread->GetContext64()); | 662 | cpu_core.LoadContext(thread->GetContext64()); |
| 658 | cpu_core.SetTlsAddress(thread->GetTLSAddress()); | 663 | cpu_core.SetTlsAddress(thread->GetTLSAddress()); |
| 659 | cpu_core.SetTPIDR_EL0(thread->GetTPIDR_EL0()); | 664 | cpu_core.SetTPIDR_EL0(thread->GetTPIDR_EL0()); |
| 660 | cpu_core.ChangeProcessorID(this->core_id); | ||
| 661 | cpu_core.ClearExclusiveState(); | 665 | cpu_core.ClearExclusiveState(); |
| 662 | } | 666 | } |
| 663 | } | 667 | } |
| 664 | } | 668 | } |
| 665 | 669 | ||
| 670 | void Scheduler::Reload() { | ||
| 671 | Reload(current_thread.get()); | ||
| 672 | } | ||
| 673 | |||
| 666 | void Scheduler::SwitchContextStep2() { | 674 | void Scheduler::SwitchContextStep2() { |
| 667 | // Load context of new thread | 675 | // Load context of new thread |
| 668 | if (selected_thread) { | 676 | Reload(selected_thread.get()); |
| 669 | ASSERT_MSG(selected_thread->GetSchedulingStatus() == ThreadSchedStatus::Runnable, | ||
| 670 | "Thread must be runnable."); | ||
| 671 | |||
| 672 | // Cancel any outstanding wakeup events for this thread | ||
| 673 | selected_thread->SetIsRunning(true); | ||
| 674 | selected_thread->last_running_ticks = system.CoreTiming().GetCPUTicks(); | ||
| 675 | selected_thread->SetWasRunning(false); | ||
| 676 | |||
| 677 | auto* const thread_owner_process = current_thread->GetOwnerProcess(); | ||
| 678 | if (thread_owner_process != nullptr) { | ||
| 679 | system.Kernel().MakeCurrentProcess(thread_owner_process); | ||
| 680 | } | ||
| 681 | if (!selected_thread->IsHLEThread()) { | ||
| 682 | Core::ARM_Interface& cpu_core = selected_thread->ArmInterface(); | ||
| 683 | cpu_core.LoadContext(selected_thread->GetContext32()); | ||
| 684 | cpu_core.LoadContext(selected_thread->GetContext64()); | ||
| 685 | cpu_core.SetTlsAddress(selected_thread->GetTLSAddress()); | ||
| 686 | cpu_core.SetTPIDR_EL0(selected_thread->GetTPIDR_EL0()); | ||
| 687 | cpu_core.ChangeProcessorID(this->core_id); | ||
| 688 | cpu_core.ClearExclusiveState(); | ||
| 689 | } | ||
| 690 | } | ||
| 691 | 677 | ||
| 692 | TryDoContextSwitch(); | 678 | TryDoContextSwitch(); |
| 693 | } | 679 | } |
| @@ -711,23 +697,7 @@ void Scheduler::SwitchContext() { | |||
| 711 | UpdateLastContextSwitchTime(previous_thread, previous_process); | 697 | UpdateLastContextSwitchTime(previous_thread, previous_process); |
| 712 | 698 | ||
| 713 | // Save context for previous thread | 699 | // Save context for previous thread |
| 714 | if (previous_thread) { | 700 | Unload(previous_thread); |
| 715 | if (new_thread != nullptr && new_thread->IsSuspendThread()) { | ||
| 716 | previous_thread->SetWasRunning(true); | ||
| 717 | } | ||
| 718 | previous_thread->SetContinuousOnSVC(false); | ||
| 719 | previous_thread->last_running_ticks = system.CoreTiming().GetCPUTicks(); | ||
| 720 | previous_thread->SetIsRunning(false); | ||
| 721 | if (!previous_thread->IsHLEThread() && !previous_thread->HasExited()) { | ||
| 722 | Core::ARM_Interface& cpu_core = previous_thread->ArmInterface(); | ||
| 723 | cpu_core.SaveContext(previous_thread->GetContext32()); | ||
| 724 | cpu_core.SaveContext(previous_thread->GetContext64()); | ||
| 725 | // Save the TPIDR_EL0 system register in case it was modified. | ||
| 726 | previous_thread->SetTPIDR_EL0(cpu_core.GetTPIDR_EL0()); | ||
| 727 | cpu_core.ClearExclusiveState(); | ||
| 728 | } | ||
| 729 | previous_thread->context_guard.unlock(); | ||
| 730 | } | ||
| 731 | 701 | ||
| 732 | std::shared_ptr<Common::Fiber>* old_context; | 702 | std::shared_ptr<Common::Fiber>* old_context; |
| 733 | if (previous_thread != nullptr) { | 703 | if (previous_thread != nullptr) { |