diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/core/hle/kernel/k_scheduler.cpp | 46 |
1 files changed, 29 insertions, 17 deletions
diff --git a/src/core/hle/kernel/k_scheduler.cpp b/src/core/hle/kernel/k_scheduler.cpp index 4bae69f71..5ee4b8adc 100644 --- a/src/core/hle/kernel/k_scheduler.cpp +++ b/src/core/hle/kernel/k_scheduler.cpp | |||
| @@ -650,6 +650,7 @@ void KScheduler::RescheduleCurrentCore() { | |||
| 650 | if (state.needs_scheduling.load()) { | 650 | if (state.needs_scheduling.load()) { |
| 651 | Schedule(); | 651 | Schedule(); |
| 652 | } else { | 652 | } else { |
| 653 | GetCurrentThread()->EnableDispatch(); | ||
| 653 | guard.Unlock(); | 654 | guard.Unlock(); |
| 654 | } | 655 | } |
| 655 | } | 656 | } |
| @@ -659,26 +660,37 @@ void KScheduler::OnThreadStart() { | |||
| 659 | } | 660 | } |
| 660 | 661 | ||
| 661 | void KScheduler::Unload(KThread* thread) { | 662 | void KScheduler::Unload(KThread* thread) { |
| 663 | ASSERT(thread); | ||
| 664 | |||
| 665 | if (!thread) { | ||
| 666 | return; | ||
| 667 | } | ||
| 668 | |||
| 662 | LOG_TRACE(Kernel, "core {}, unload thread {}", core_id, thread ? thread->GetName() : "nullptr"); | 669 | LOG_TRACE(Kernel, "core {}, unload thread {}", core_id, thread ? thread->GetName() : "nullptr"); |
| 663 | 670 | ||
| 664 | if (thread) { | 671 | if (thread->IsCallingSvc()) { |
| 665 | if (thread->IsCallingSvc()) { | 672 | thread->ClearIsCallingSvc(); |
| 666 | thread->ClearIsCallingSvc(); | ||
| 667 | } | ||
| 668 | if (!thread->IsTerminationRequested()) { | ||
| 669 | prev_thread = thread; | ||
| 670 | |||
| 671 | Core::ARM_Interface& cpu_core = system.ArmInterface(core_id); | ||
| 672 | cpu_core.SaveContext(thread->GetContext32()); | ||
| 673 | cpu_core.SaveContext(thread->GetContext64()); | ||
| 674 | // Save the TPIDR_EL0 system register in case it was modified. | ||
| 675 | thread->SetTPIDR_EL0(cpu_core.GetTPIDR_EL0()); | ||
| 676 | cpu_core.ClearExclusiveState(); | ||
| 677 | } else { | ||
| 678 | prev_thread = nullptr; | ||
| 679 | } | ||
| 680 | thread->context_guard.Unlock(); | ||
| 681 | } | 673 | } |
| 674 | |||
| 675 | auto& physical_core = system.Kernel().PhysicalCore(core_id); | ||
| 676 | if (!physical_core.IsInitialized()) { | ||
| 677 | return; | ||
| 678 | } | ||
| 679 | |||
| 680 | Core::ARM_Interface& cpu_core = physical_core.ArmInterface(); | ||
| 681 | cpu_core.SaveContext(thread->GetContext32()); | ||
| 682 | cpu_core.SaveContext(thread->GetContext64()); | ||
| 683 | // Save the TPIDR_EL0 system register in case it was modified. | ||
| 684 | thread->SetTPIDR_EL0(cpu_core.GetTPIDR_EL0()); | ||
| 685 | cpu_core.ClearExclusiveState(); | ||
| 686 | |||
| 687 | if (!thread->IsTerminationRequested() && thread->GetActiveCore() == core_id) { | ||
| 688 | prev_thread = thread; | ||
| 689 | } else { | ||
| 690 | prev_thread = nullptr; | ||
| 691 | } | ||
| 692 | |||
| 693 | thread->context_guard.Unlock(); | ||
| 682 | } | 694 | } |
| 683 | 695 | ||
| 684 | void KScheduler::Reload(KThread* thread) { | 696 | void KScheduler::Reload(KThread* thread) { |