summaryrefslogtreecommitdiff
path: root/src/core/hle/kernel/scheduler.cpp
diff options
context:
space:
mode:
authorGravatar Fernando Sahmkow2020-03-10 11:50:33 -0400
committerGravatar Fernando Sahmkow2020-06-27 11:35:43 -0400
commita439cdf22ea50f0e39cb51f6dff15fee3b495d16 (patch)
tree2c88310d7cca08ef451107d9ae6bd5191e7d72e5 /src/core/hle/kernel/scheduler.cpp
parentSynchronization: Correct wide Assertion. (diff)
downloadyuzu-a439cdf22ea50f0e39cb51f6dff15fee3b495d16.tar.gz
yuzu-a439cdf22ea50f0e39cb51f6dff15fee3b495d16.tar.xz
yuzu-a439cdf22ea50f0e39cb51f6dff15fee3b495d16.zip
CPU_Manager: Unload/Reload threads on preemption on SingleCore
Diffstat (limited to 'src/core/hle/kernel/scheduler.cpp')
-rw-r--r--src/core/hle/kernel/scheduler.cpp42
1 files changed, 42 insertions, 0 deletions
diff --git a/src/core/hle/kernel/scheduler.cpp b/src/core/hle/kernel/scheduler.cpp
index d68d86cdf..00322d997 100644
--- a/src/core/hle/kernel/scheduler.cpp
+++ b/src/core/hle/kernel/scheduler.cpp
@@ -602,6 +602,48 @@ void Scheduler::OnThreadStart() {
602 SwitchContextStep2(); 602 SwitchContextStep2();
603} 603}
604 604
605void Scheduler::Unload() {
606 Thread* thread = current_thread.get();
607 if (thread) {
608 thread->last_running_ticks = system.CoreTiming().GetCPUTicks();
609 thread->SetIsRunning(false);
610 if (!thread->IsHLEThread()) {
611 auto& cpu_core = system.ArmInterface(core_id);
612 cpu_core.SaveContext(thread->GetContext32());
613 cpu_core.SaveContext(thread->GetContext64());
614 // Save the TPIDR_EL0 system register in case it was modified.
615 thread->SetTPIDR_EL0(cpu_core.GetTPIDR_EL0());
616 cpu_core.ClearExclusiveState();
617 }
618 thread->context_guard.unlock();
619 }
620}
621
622void Scheduler::Reload() {
623 Thread* thread = current_thread.get();
624 if (thread) {
625 ASSERT_MSG(thread->GetSchedulingStatus() == ThreadSchedStatus::Runnable,
626 "Thread must be runnable.");
627
628 // Cancel any outstanding wakeup events for this thread
629 thread->SetIsRunning(true);
630 thread->last_running_ticks = system.CoreTiming().GetCPUTicks();
631
632 auto* const thread_owner_process = thread->GetOwnerProcess();
633 if (thread_owner_process != nullptr) {
634 system.Kernel().MakeCurrentProcess(thread_owner_process);
635 }
636 if (!thread->IsHLEThread()) {
637 auto& cpu_core = system.ArmInterface(core_id);
638 cpu_core.LoadContext(thread->GetContext32());
639 cpu_core.LoadContext(thread->GetContext64());
640 cpu_core.SetTlsAddress(thread->GetTLSAddress());
641 cpu_core.SetTPIDR_EL0(thread->GetTPIDR_EL0());
642 cpu_core.ClearExclusiveState();
643 }
644 }
645}
646
605void Scheduler::SwitchContextStep2() { 647void Scheduler::SwitchContextStep2() {
606 Thread* previous_thread = current_thread_prev.get(); 648 Thread* previous_thread = current_thread_prev.get();
607 Thread* new_thread = selected_thread.get(); 649 Thread* new_thread = selected_thread.get();