summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/core/arm/arm_interface.cpp2
-rw-r--r--src/core/cpu_manager.cpp17
-rw-r--r--src/core/hle/kernel/k_address_arbiter.cpp4
-rw-r--r--src/core/hle/kernel/k_condition_variable.cpp4
-rw-r--r--src/core/hle/kernel/k_interrupt_manager.cpp5
-rw-r--r--src/core/hle/kernel/k_process.cpp10
-rw-r--r--src/core/hle/kernel/k_scheduler.cpp25
-rw-r--r--src/core/hle/kernel/k_scheduler.h12
-rw-r--r--src/core/hle/kernel/k_thread.cpp12
-rw-r--r--src/core/hle/kernel/k_thread.h1
-rw-r--r--src/core/hle/kernel/kernel.cpp13
-rw-r--r--src/core/hle/kernel/kernel.h3
-rw-r--r--src/core/hle/kernel/svc.cpp13
13 files changed, 69 insertions, 52 deletions
diff --git a/src/core/arm/arm_interface.cpp b/src/core/arm/arm_interface.cpp
index 6425e131f..8e095cdcd 100644
--- a/src/core/arm/arm_interface.cpp
+++ b/src/core/arm/arm_interface.cpp
@@ -95,7 +95,7 @@ void ARM_Interface::Run() {
95 using Kernel::SuspendType; 95 using Kernel::SuspendType;
96 96
97 while (true) { 97 while (true) {
98 Kernel::KThread* current_thread{system.Kernel().CurrentScheduler()->GetCurrentThread()}; 98 Kernel::KThread* current_thread{Kernel::GetCurrentThreadPointer(system.Kernel())};
99 Dynarmic::HaltReason hr{}; 99 Dynarmic::HaltReason hr{};
100 100
101 // Notify the debugger and go to sleep if a step was performed 101 // Notify the debugger and go to sleep if a step was performed
diff --git a/src/core/cpu_manager.cpp b/src/core/cpu_manager.cpp
index d69b2602a..fd6928105 100644
--- a/src/core/cpu_manager.cpp
+++ b/src/core/cpu_manager.cpp
@@ -95,7 +95,7 @@ void* CpuManager::GetStartFuncParameter() {
95void CpuManager::MultiCoreRunGuestThread() { 95void CpuManager::MultiCoreRunGuestThread() {
96 auto& kernel = system.Kernel(); 96 auto& kernel = system.Kernel();
97 kernel.CurrentScheduler()->OnThreadStart(); 97 kernel.CurrentScheduler()->OnThreadStart();
98 auto* thread = kernel.CurrentScheduler()->GetCurrentThread(); 98 auto* thread = kernel.CurrentScheduler()->GetSchedulerCurrentThread();
99 auto& host_context = thread->GetHostContext(); 99 auto& host_context = thread->GetHostContext();
100 host_context->SetRewindPoint(GuestRewindFunction, this); 100 host_context->SetRewindPoint(GuestRewindFunction, this);
101 MultiCoreRunGuestLoop(); 101 MultiCoreRunGuestLoop();
@@ -132,7 +132,7 @@ void CpuManager::MultiCoreRunIdleThread() {
132void CpuManager::SingleCoreRunGuestThread() { 132void CpuManager::SingleCoreRunGuestThread() {
133 auto& kernel = system.Kernel(); 133 auto& kernel = system.Kernel();
134 kernel.CurrentScheduler()->OnThreadStart(); 134 kernel.CurrentScheduler()->OnThreadStart();
135 auto* thread = kernel.CurrentScheduler()->GetCurrentThread(); 135 auto* thread = kernel.CurrentScheduler()->GetSchedulerCurrentThread();
136 auto& host_context = thread->GetHostContext(); 136 auto& host_context = thread->GetHostContext();
137 host_context->SetRewindPoint(GuestRewindFunction, this); 137 host_context->SetRewindPoint(GuestRewindFunction, this);
138 SingleCoreRunGuestLoop(); 138 SingleCoreRunGuestLoop();
@@ -172,7 +172,7 @@ void CpuManager::PreemptSingleCore(bool from_running_enviroment) {
172 { 172 {
173 auto& kernel = system.Kernel(); 173 auto& kernel = system.Kernel();
174 auto& scheduler = kernel.Scheduler(current_core); 174 auto& scheduler = kernel.Scheduler(current_core);
175 Kernel::KThread* current_thread = scheduler.GetCurrentThread(); 175 Kernel::KThread* current_thread = scheduler.GetSchedulerCurrentThread();
176 if (idle_count >= 4 || from_running_enviroment) { 176 if (idle_count >= 4 || from_running_enviroment) {
177 if (!from_running_enviroment) { 177 if (!from_running_enviroment) {
178 system.CoreTiming().Idle(); 178 system.CoreTiming().Idle();
@@ -184,7 +184,7 @@ void CpuManager::PreemptSingleCore(bool from_running_enviroment) {
184 } 184 }
185 current_core.store((current_core + 1) % Core::Hardware::NUM_CPU_CORES); 185 current_core.store((current_core + 1) % Core::Hardware::NUM_CPU_CORES);
186 system.CoreTiming().ResetTicks(); 186 system.CoreTiming().ResetTicks();
187 scheduler.Unload(scheduler.GetCurrentThread()); 187 scheduler.Unload(scheduler.GetSchedulerCurrentThread());
188 188
189 auto& next_scheduler = kernel.Scheduler(current_core); 189 auto& next_scheduler = kernel.Scheduler(current_core);
190 Common::Fiber::YieldTo(current_thread->GetHostContext(), *next_scheduler.ControlContext()); 190 Common::Fiber::YieldTo(current_thread->GetHostContext(), *next_scheduler.ControlContext());
@@ -193,10 +193,8 @@ void CpuManager::PreemptSingleCore(bool from_running_enviroment) {
193 // May have changed scheduler 193 // May have changed scheduler
194 { 194 {
195 auto& scheduler = system.Kernel().Scheduler(current_core); 195 auto& scheduler = system.Kernel().Scheduler(current_core);
196 scheduler.Reload(scheduler.GetCurrentThread()); 196 scheduler.Reload(scheduler.GetSchedulerCurrentThread());
197 if (!scheduler.IsIdle()) { 197 idle_count = 0;
198 idle_count = 0;
199 }
200 } 198 }
201} 199}
202 200
@@ -237,7 +235,8 @@ void CpuManager::RunThread(std::size_t core) {
237 system.GPU().ObtainContext(); 235 system.GPU().ObtainContext();
238 } 236 }
239 237
240 auto current_thread = system.Kernel().CurrentScheduler()->GetCurrentThread(); 238 auto* current_thread = system.Kernel().CurrentScheduler()->GetIdleThread();
239 Kernel::SetCurrentThread(system.Kernel(), current_thread);
241 Common::Fiber::YieldTo(data.host_context, *current_thread->GetHostContext()); 240 Common::Fiber::YieldTo(data.host_context, *current_thread->GetHostContext());
242} 241}
243 242
diff --git a/src/core/hle/kernel/k_address_arbiter.cpp b/src/core/hle/kernel/k_address_arbiter.cpp
index 04cf86d52..5fa67bae1 100644
--- a/src/core/hle/kernel/k_address_arbiter.cpp
+++ b/src/core/hle/kernel/k_address_arbiter.cpp
@@ -234,7 +234,7 @@ ResultCode KAddressArbiter::SignalAndModifyByWaitingCountIfEqual(VAddr addr, s32
234 234
235ResultCode KAddressArbiter::WaitIfLessThan(VAddr addr, s32 value, bool decrement, s64 timeout) { 235ResultCode KAddressArbiter::WaitIfLessThan(VAddr addr, s32 value, bool decrement, s64 timeout) {
236 // Prepare to wait. 236 // Prepare to wait.
237 KThread* cur_thread = kernel.CurrentScheduler()->GetCurrentThread(); 237 KThread* cur_thread = GetCurrentThreadPointer(kernel);
238 ThreadQueueImplForKAddressArbiter wait_queue(kernel, std::addressof(thread_tree)); 238 ThreadQueueImplForKAddressArbiter wait_queue(kernel, std::addressof(thread_tree));
239 239
240 { 240 {
@@ -287,7 +287,7 @@ ResultCode KAddressArbiter::WaitIfLessThan(VAddr addr, s32 value, bool decrement
287 287
288ResultCode KAddressArbiter::WaitIfEqual(VAddr addr, s32 value, s64 timeout) { 288ResultCode KAddressArbiter::WaitIfEqual(VAddr addr, s32 value, s64 timeout) {
289 // Prepare to wait. 289 // Prepare to wait.
290 KThread* cur_thread = kernel.CurrentScheduler()->GetCurrentThread(); 290 KThread* cur_thread = GetCurrentThreadPointer(kernel);
291 ThreadQueueImplForKAddressArbiter wait_queue(kernel, std::addressof(thread_tree)); 291 ThreadQueueImplForKAddressArbiter wait_queue(kernel, std::addressof(thread_tree));
292 292
293 { 293 {
diff --git a/src/core/hle/kernel/k_condition_variable.cpp b/src/core/hle/kernel/k_condition_variable.cpp
index 43bcd253d..a8b5411e3 100644
--- a/src/core/hle/kernel/k_condition_variable.cpp
+++ b/src/core/hle/kernel/k_condition_variable.cpp
@@ -106,7 +106,7 @@ KConditionVariable::KConditionVariable(Core::System& system_)
106KConditionVariable::~KConditionVariable() = default; 106KConditionVariable::~KConditionVariable() = default;
107 107
108ResultCode KConditionVariable::SignalToAddress(VAddr addr) { 108ResultCode KConditionVariable::SignalToAddress(VAddr addr) {
109 KThread* owner_thread = kernel.CurrentScheduler()->GetCurrentThread(); 109 KThread* owner_thread = GetCurrentThreadPointer(kernel);
110 110
111 // Signal the address. 111 // Signal the address.
112 { 112 {
@@ -147,7 +147,7 @@ ResultCode KConditionVariable::SignalToAddress(VAddr addr) {
147} 147}
148 148
149ResultCode KConditionVariable::WaitForAddress(Handle handle, VAddr addr, u32 value) { 149ResultCode KConditionVariable::WaitForAddress(Handle handle, VAddr addr, u32 value) {
150 KThread* cur_thread = kernel.CurrentScheduler()->GetCurrentThread(); 150 KThread* cur_thread = GetCurrentThreadPointer(kernel);
151 ThreadQueueImplForKConditionVariableWaitForAddress wait_queue(kernel); 151 ThreadQueueImplForKConditionVariableWaitForAddress wait_queue(kernel);
152 152
153 // Wait for the address. 153 // Wait for the address.
diff --git a/src/core/hle/kernel/k_interrupt_manager.cpp b/src/core/hle/kernel/k_interrupt_manager.cpp
index cf9ed80d0..d606a7f86 100644
--- a/src/core/hle/kernel/k_interrupt_manager.cpp
+++ b/src/core/hle/kernel/k_interrupt_manager.cpp
@@ -15,8 +15,7 @@ void HandleInterrupt(KernelCore& kernel, s32 core_id) {
15 return; 15 return;
16 } 16 }
17 17
18 auto& scheduler = kernel.Scheduler(core_id); 18 auto& current_thread = GetCurrentThread(kernel);
19 auto& current_thread = *scheduler.GetCurrentThread();
20 19
21 // If the user disable count is set, we may need to pin the current thread. 20 // If the user disable count is set, we may need to pin the current thread.
22 if (current_thread.GetUserDisableCount() && !process->GetPinnedThread(core_id)) { 21 if (current_thread.GetUserDisableCount() && !process->GetPinnedThread(core_id)) {
@@ -26,7 +25,7 @@ void HandleInterrupt(KernelCore& kernel, s32 core_id) {
26 process->PinCurrentThread(core_id); 25 process->PinCurrentThread(core_id);
27 26
28 // Set the interrupt flag for the thread. 27 // Set the interrupt flag for the thread.
29 scheduler.GetCurrentThread()->SetInterruptFlag(); 28 GetCurrentThread(kernel).SetInterruptFlag();
30 } 29 }
31} 30}
32 31
diff --git a/src/core/hle/kernel/k_process.cpp b/src/core/hle/kernel/k_process.cpp
index cb84c20e3..b477c6e55 100644
--- a/src/core/hle/kernel/k_process.cpp
+++ b/src/core/hle/kernel/k_process.cpp
@@ -176,7 +176,8 @@ void KProcess::PinCurrentThread(s32 core_id) {
176 ASSERT(kernel.GlobalSchedulerContext().IsLocked()); 176 ASSERT(kernel.GlobalSchedulerContext().IsLocked());
177 177
178 // Get the current thread. 178 // Get the current thread.
179 KThread* cur_thread = kernel.Scheduler(static_cast<std::size_t>(core_id)).GetCurrentThread(); 179 KThread* cur_thread =
180 kernel.Scheduler(static_cast<std::size_t>(core_id)).GetSchedulerCurrentThread();
180 181
181 // If the thread isn't terminated, pin it. 182 // If the thread isn't terminated, pin it.
182 if (!cur_thread->IsTerminationRequested()) { 183 if (!cur_thread->IsTerminationRequested()) {
@@ -193,7 +194,8 @@ void KProcess::UnpinCurrentThread(s32 core_id) {
193 ASSERT(kernel.GlobalSchedulerContext().IsLocked()); 194 ASSERT(kernel.GlobalSchedulerContext().IsLocked());
194 195
195 // Get the current thread. 196 // Get the current thread.
196 KThread* cur_thread = kernel.Scheduler(static_cast<std::size_t>(core_id)).GetCurrentThread(); 197 KThread* cur_thread =
198 kernel.Scheduler(static_cast<std::size_t>(core_id)).GetSchedulerCurrentThread();
197 199
198 // Unpin it. 200 // Unpin it.
199 cur_thread->Unpin(); 201 cur_thread->Unpin();
@@ -420,11 +422,11 @@ void KProcess::PrepareForTermination() {
420 ChangeStatus(ProcessStatus::Exiting); 422 ChangeStatus(ProcessStatus::Exiting);
421 423
422 const auto stop_threads = [this](const std::vector<KThread*>& in_thread_list) { 424 const auto stop_threads = [this](const std::vector<KThread*>& in_thread_list) {
423 for (auto& thread : in_thread_list) { 425 for (auto* thread : in_thread_list) {
424 if (thread->GetOwnerProcess() != this) 426 if (thread->GetOwnerProcess() != this)
425 continue; 427 continue;
426 428
427 if (thread == kernel.CurrentScheduler()->GetCurrentThread()) 429 if (thread == GetCurrentThreadPointer(kernel))
428 continue; 430 continue;
429 431
430 // TODO(Subv): When are the other running/ready threads terminated? 432 // TODO(Subv): When are the other running/ready threads terminated?
diff --git a/src/core/hle/kernel/k_scheduler.cpp b/src/core/hle/kernel/k_scheduler.cpp
index fb3b84f3d..d586b3f5c 100644
--- a/src/core/hle/kernel/k_scheduler.cpp
+++ b/src/core/hle/kernel/k_scheduler.cpp
@@ -317,7 +317,7 @@ void KScheduler::RotateScheduledQueue(s32 cpu_core_id, s32 priority) {
317 317
318 { 318 {
319 KThread* best_thread = priority_queue.GetScheduledFront(cpu_core_id); 319 KThread* best_thread = priority_queue.GetScheduledFront(cpu_core_id);
320 if (best_thread == GetCurrentThread()) { 320 if (best_thread == GetCurrentThreadPointer(kernel)) {
321 best_thread = priority_queue.GetScheduledNext(cpu_core_id, best_thread); 321 best_thread = priority_queue.GetScheduledNext(cpu_core_id, best_thread);
322 } 322 }
323 323
@@ -424,7 +424,7 @@ void KScheduler::YieldWithoutCoreMigration(KernelCore& kernel) {
424 ASSERT(kernel.CurrentProcess() != nullptr); 424 ASSERT(kernel.CurrentProcess() != nullptr);
425 425
426 // Get the current thread and process. 426 // Get the current thread and process.
427 KThread& cur_thread = Kernel::GetCurrentThread(kernel); 427 KThread& cur_thread = GetCurrentThread(kernel);
428 KProcess& cur_process = *kernel.CurrentProcess(); 428 KProcess& cur_process = *kernel.CurrentProcess();
429 429
430 // If the thread's yield count matches, there's nothing for us to do. 430 // If the thread's yield count matches, there's nothing for us to do.
@@ -463,7 +463,7 @@ void KScheduler::YieldWithCoreMigration(KernelCore& kernel) {
463 ASSERT(kernel.CurrentProcess() != nullptr); 463 ASSERT(kernel.CurrentProcess() != nullptr);
464 464
465 // Get the current thread and process. 465 // Get the current thread and process.
466 KThread& cur_thread = Kernel::GetCurrentThread(kernel); 466 KThread& cur_thread = GetCurrentThread(kernel);
467 KProcess& cur_process = *kernel.CurrentProcess(); 467 KProcess& cur_process = *kernel.CurrentProcess();
468 468
469 // If the thread's yield count matches, there's nothing for us to do. 469 // If the thread's yield count matches, there's nothing for us to do.
@@ -551,7 +551,7 @@ void KScheduler::YieldToAnyThread(KernelCore& kernel) {
551 ASSERT(kernel.CurrentProcess() != nullptr); 551 ASSERT(kernel.CurrentProcess() != nullptr);
552 552
553 // Get the current thread and process. 553 // Get the current thread and process.
554 KThread& cur_thread = Kernel::GetCurrentThread(kernel); 554 KThread& cur_thread = GetCurrentThread(kernel);
555 KProcess& cur_process = *kernel.CurrentProcess(); 555 KProcess& cur_process = *kernel.CurrentProcess();
556 556
557 // If the thread's yield count matches, there's nothing for us to do. 557 // If the thread's yield count matches, there's nothing for us to do.
@@ -642,7 +642,7 @@ KScheduler::~KScheduler() {
642 ASSERT(!idle_thread); 642 ASSERT(!idle_thread);
643} 643}
644 644
645KThread* KScheduler::GetCurrentThread() const { 645KThread* KScheduler::GetSchedulerCurrentThread() const {
646 if (auto result = current_thread.load(); result) { 646 if (auto result = current_thread.load(); result) {
647 return result; 647 return result;
648 } 648 }
@@ -654,7 +654,7 @@ u64 KScheduler::GetLastContextSwitchTicks() const {
654} 654}
655 655
656void KScheduler::RescheduleCurrentCore() { 656void KScheduler::RescheduleCurrentCore() {
657 ASSERT(GetCurrentThread()->GetDisableDispatchCount() == 1); 657 ASSERT(GetCurrentThread(system.Kernel()).GetDisableDispatchCount() == 1);
658 658
659 auto& phys_core = system.Kernel().PhysicalCore(core_id); 659 auto& phys_core = system.Kernel().PhysicalCore(core_id);
660 if (phys_core.IsInterrupted()) { 660 if (phys_core.IsInterrupted()) {
@@ -665,7 +665,7 @@ void KScheduler::RescheduleCurrentCore() {
665 if (state.needs_scheduling.load()) { 665 if (state.needs_scheduling.load()) {
666 Schedule(); 666 Schedule();
667 } else { 667 } else {
668 GetCurrentThread()->EnableDispatch(); 668 GetCurrentThread(system.Kernel()).EnableDispatch();
669 guard.Unlock(); 669 guard.Unlock();
670 } 670 }
671} 671}
@@ -718,13 +718,18 @@ void KScheduler::Reload(KThread* thread) {
718 718
719void KScheduler::SwitchContextStep2() { 719void KScheduler::SwitchContextStep2() {
720 // Load context of new thread 720 // Load context of new thread
721 Reload(GetCurrentThread()); 721 Reload(GetCurrentThreadPointer(system.Kernel()));
722 722
723 RescheduleCurrentCore(); 723 RescheduleCurrentCore();
724} 724}
725 725
726void KScheduler::Schedule() {
727 ASSERT(GetCurrentThread(system.Kernel()).GetDisableDispatchCount() == 1);
728 this->ScheduleImpl();
729}
730
726void KScheduler::ScheduleImpl() { 731void KScheduler::ScheduleImpl() {
727 KThread* previous_thread = GetCurrentThread(); 732 KThread* previous_thread = GetCurrentThreadPointer(system.Kernel());
728 KThread* next_thread = state.highest_priority_thread; 733 KThread* next_thread = state.highest_priority_thread;
729 734
730 state.needs_scheduling.store(false); 735 state.needs_scheduling.store(false);
@@ -762,6 +767,7 @@ void KScheduler::ScheduleImpl() {
762 old_context = &previous_thread->GetHostContext(); 767 old_context = &previous_thread->GetHostContext();
763 768
764 // Set the new thread. 769 // Set the new thread.
770 SetCurrentThread(system.Kernel(), next_thread);
765 current_thread.store(next_thread); 771 current_thread.store(next_thread);
766 772
767 guard.Unlock(); 773 guard.Unlock();
@@ -805,6 +811,7 @@ void KScheduler::SwitchToCurrent() {
805 } 811 }
806 } 812 }
807 auto thread = next_thread ? next_thread : idle_thread; 813 auto thread = next_thread ? next_thread : idle_thread;
814 SetCurrentThread(system.Kernel(), thread);
808 Common::Fiber::YieldTo(switch_fiber, *thread->GetHostContext()); 815 Common::Fiber::YieldTo(switch_fiber, *thread->GetHostContext());
809 } while (!is_switch_pending()); 816 } while (!is_switch_pending());
810 } 817 }
diff --git a/src/core/hle/kernel/k_scheduler.h b/src/core/hle/kernel/k_scheduler.h
index 729e006f2..3f90656ee 100644
--- a/src/core/hle/kernel/k_scheduler.h
+++ b/src/core/hle/kernel/k_scheduler.h
@@ -48,18 +48,13 @@ public:
48 void Reload(KThread* thread); 48 void Reload(KThread* thread);
49 49
50 /// Gets the current running thread 50 /// Gets the current running thread
51 [[nodiscard]] KThread* GetCurrentThread() const; 51 [[nodiscard]] KThread* GetSchedulerCurrentThread() const;
52 52
53 /// Gets the idle thread 53 /// Gets the idle thread
54 [[nodiscard]] KThread* GetIdleThread() const { 54 [[nodiscard]] KThread* GetIdleThread() const {
55 return idle_thread; 55 return idle_thread;
56 } 56 }
57 57
58 /// Returns true if the scheduler is idle
59 [[nodiscard]] bool IsIdle() const {
60 return GetCurrentThread() == idle_thread;
61 }
62
63 /// Gets the timestamp for the last context switch in ticks. 58 /// Gets the timestamp for the last context switch in ticks.
64 [[nodiscard]] u64 GetLastContextSwitchTicks() const; 59 [[nodiscard]] u64 GetLastContextSwitchTicks() const;
65 60
@@ -149,10 +144,7 @@ private:
149 144
150 void RotateScheduledQueue(s32 cpu_core_id, s32 priority); 145 void RotateScheduledQueue(s32 cpu_core_id, s32 priority);
151 146
152 void Schedule() { 147 void Schedule();
153 ASSERT(GetCurrentThread()->GetDisableDispatchCount() == 1);
154 this->ScheduleImpl();
155 }
156 148
157 /// Switches the CPU's active thread context to that of the specified thread 149 /// Switches the CPU's active thread context to that of the specified thread
158 void ScheduleImpl(); 150 void ScheduleImpl();
diff --git a/src/core/hle/kernel/k_thread.cpp b/src/core/hle/kernel/k_thread.cpp
index c0a091bb6..fa5352847 100644
--- a/src/core/hle/kernel/k_thread.cpp
+++ b/src/core/hle/kernel/k_thread.cpp
@@ -382,7 +382,7 @@ void KThread::FinishTermination() {
382 for (std::size_t i = 0; i < static_cast<std::size_t>(Core::Hardware::NUM_CPU_CORES); ++i) { 382 for (std::size_t i = 0; i < static_cast<std::size_t>(Core::Hardware::NUM_CPU_CORES); ++i) {
383 KThread* core_thread{}; 383 KThread* core_thread{};
384 do { 384 do {
385 core_thread = kernel.Scheduler(i).GetCurrentThread(); 385 core_thread = kernel.Scheduler(i).GetSchedulerCurrentThread();
386 } while (core_thread == this); 386 } while (core_thread == this);
387 } 387 }
388 } 388 }
@@ -631,7 +631,7 @@ ResultCode KThread::SetCoreMask(s32 core_id_, u64 v_affinity_mask) {
631 s32 thread_core; 631 s32 thread_core;
632 for (thread_core = 0; thread_core < static_cast<s32>(Core::Hardware::NUM_CPU_CORES); 632 for (thread_core = 0; thread_core < static_cast<s32>(Core::Hardware::NUM_CPU_CORES);
633 ++thread_core) { 633 ++thread_core) {
634 if (kernel.Scheduler(thread_core).GetCurrentThread() == this) { 634 if (kernel.Scheduler(thread_core).GetSchedulerCurrentThread() == this) {
635 thread_is_current = true; 635 thread_is_current = true;
636 break; 636 break;
637 } 637 }
@@ -756,7 +756,7 @@ void KThread::WaitUntilSuspended() {
756 for (std::size_t i = 0; i < static_cast<std::size_t>(Core::Hardware::NUM_CPU_CORES); ++i) { 756 for (std::size_t i = 0; i < static_cast<std::size_t>(Core::Hardware::NUM_CPU_CORES); ++i) {
757 KThread* core_thread{}; 757 KThread* core_thread{};
758 do { 758 do {
759 core_thread = kernel.Scheduler(i).GetCurrentThread(); 759 core_thread = kernel.Scheduler(i).GetSchedulerCurrentThread();
760 } while (core_thread == this); 760 } while (core_thread == this);
761 } 761 }
762} 762}
@@ -822,7 +822,7 @@ ResultCode KThread::SetActivity(Svc::ThreadActivity activity) {
822 // Check if the thread is currently running. 822 // Check if the thread is currently running.
823 // If it is, we'll need to retry. 823 // If it is, we'll need to retry.
824 for (auto i = 0; i < static_cast<s32>(Core::Hardware::NUM_CPU_CORES); ++i) { 824 for (auto i = 0; i < static_cast<s32>(Core::Hardware::NUM_CPU_CORES); ++i) {
825 if (kernel.Scheduler(i).GetCurrentThread() == this) { 825 if (kernel.Scheduler(i).GetSchedulerCurrentThread() == this) {
826 thread_is_current = true; 826 thread_is_current = true;
827 break; 827 break;
828 } 828 }
@@ -1175,6 +1175,10 @@ std::shared_ptr<Common::Fiber>& KThread::GetHostContext() {
1175 return host_context; 1175 return host_context;
1176} 1176}
1177 1177
1178void SetCurrentThread(KernelCore& kernel, KThread* thread) {
1179 kernel.SetCurrentEmuThread(thread);
1180}
1181
1178KThread* GetCurrentThreadPointer(KernelCore& kernel) { 1182KThread* GetCurrentThreadPointer(KernelCore& kernel) {
1179 return kernel.GetCurrentEmuThread(); 1183 return kernel.GetCurrentEmuThread();
1180} 1184}
diff --git a/src/core/hle/kernel/k_thread.h b/src/core/hle/kernel/k_thread.h
index 8c1f8a344..c6ca37f56 100644
--- a/src/core/hle/kernel/k_thread.h
+++ b/src/core/hle/kernel/k_thread.h
@@ -106,6 +106,7 @@ enum class StepState : u32 {
106 StepPerformed, ///< Thread has stepped, waiting to be scheduled again 106 StepPerformed, ///< Thread has stepped, waiting to be scheduled again
107}; 107};
108 108
109void SetCurrentThread(KernelCore& kernel, KThread* thread);
109[[nodiscard]] KThread* GetCurrentThreadPointer(KernelCore& kernel); 110[[nodiscard]] KThread* GetCurrentThreadPointer(KernelCore& kernel);
110[[nodiscard]] KThread& GetCurrentThread(KernelCore& kernel); 111[[nodiscard]] KThread& GetCurrentThread(KernelCore& kernel);
111[[nodiscard]] s32 GetCurrentCoreId(KernelCore& kernel); 112[[nodiscard]] s32 GetCurrentCoreId(KernelCore& kernel);
diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp
index 94953e257..0009193be 100644
--- a/src/core/hle/kernel/kernel.cpp
+++ b/src/core/hle/kernel/kernel.cpp
@@ -331,6 +331,8 @@ struct KernelCore::Impl {
331 return is_shutting_down.load(std::memory_order_relaxed); 331 return is_shutting_down.load(std::memory_order_relaxed);
332 } 332 }
333 333
334 static inline thread_local KThread* current_thread{nullptr};
335
334 KThread* GetCurrentEmuThread() { 336 KThread* GetCurrentEmuThread() {
335 // If we are shutting down the kernel, none of this is relevant anymore. 337 // If we are shutting down the kernel, none of this is relevant anymore.
336 if (IsShuttingDown()) { 338 if (IsShuttingDown()) {
@@ -341,7 +343,12 @@ struct KernelCore::Impl {
341 if (thread_id >= Core::Hardware::NUM_CPU_CORES) { 343 if (thread_id >= Core::Hardware::NUM_CPU_CORES) {
342 return GetHostDummyThread(); 344 return GetHostDummyThread();
343 } 345 }
344 return schedulers[thread_id]->GetCurrentThread(); 346
347 return current_thread;
348 }
349
350 void SetCurrentEmuThread(KThread* thread) {
351 current_thread = thread;
345 } 352 }
346 353
347 void DeriveInitialMemoryLayout() { 354 void DeriveInitialMemoryLayout() {
@@ -1024,6 +1031,10 @@ KThread* KernelCore::GetCurrentEmuThread() const {
1024 return impl->GetCurrentEmuThread(); 1031 return impl->GetCurrentEmuThread();
1025} 1032}
1026 1033
1034void KernelCore::SetCurrentEmuThread(KThread* thread) {
1035 impl->SetCurrentEmuThread(thread);
1036}
1037
1027KMemoryManager& KernelCore::MemoryManager() { 1038KMemoryManager& KernelCore::MemoryManager() {
1028 return *impl->memory_manager; 1039 return *impl->memory_manager;
1029} 1040}
diff --git a/src/core/hle/kernel/kernel.h b/src/core/hle/kernel/kernel.h
index 4e7beab0e..aa0ebaa02 100644
--- a/src/core/hle/kernel/kernel.h
+++ b/src/core/hle/kernel/kernel.h
@@ -226,6 +226,9 @@ public:
226 /// Gets the current host_thread/guest_thread pointer. 226 /// Gets the current host_thread/guest_thread pointer.
227 KThread* GetCurrentEmuThread() const; 227 KThread* GetCurrentEmuThread() const;
228 228
229 /// Sets the current guest_thread pointer.
230 void SetCurrentEmuThread(KThread* thread);
231
229 /// Gets the current host_thread handle. 232 /// Gets the current host_thread handle.
230 u32 GetCurrentHostThreadID() const; 233 u32 GetCurrentHostThreadID() const;
231 234
diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp
index 2ff6d5fa6..2b34fc19d 100644
--- a/src/core/hle/kernel/svc.cpp
+++ b/src/core/hle/kernel/svc.cpp
@@ -327,7 +327,6 @@ static ResultCode SendSyncRequest(Core::System& system, Handle handle) {
327 327
328 LOG_TRACE(Kernel_SVC, "called handle=0x{:08X}({})", handle, session->GetName()); 328 LOG_TRACE(Kernel_SVC, "called handle=0x{:08X}({})", handle, session->GetName());
329 329
330 auto thread = kernel.CurrentScheduler()->GetCurrentThread();
331 { 330 {
332 KScopedSchedulerLock lock(kernel); 331 KScopedSchedulerLock lock(kernel);
333 332
@@ -337,7 +336,7 @@ static ResultCode SendSyncRequest(Core::System& system, Handle handle) {
337 session->SendSyncRequest(&GetCurrentThread(kernel), system.Memory(), system.CoreTiming()); 336 session->SendSyncRequest(&GetCurrentThread(kernel), system.Memory(), system.CoreTiming());
338 } 337 }
339 338
340 return thread->GetWaitResult(); 339 return GetCurrentThread(kernel).GetWaitResult();
341} 340}
342 341
343static ResultCode SendSyncRequest32(Core::System& system, Handle handle) { 342static ResultCode SendSyncRequest32(Core::System& system, Handle handle) {
@@ -624,7 +623,7 @@ static void Break(Core::System& system, u32 reason, u64 info1, u64 info2) {
624 623
625 handle_debug_buffer(info1, info2); 624 handle_debug_buffer(info1, info2);
626 625
627 auto* const current_thread = system.Kernel().CurrentScheduler()->GetCurrentThread(); 626 auto* const current_thread = GetCurrentThreadPointer(system.Kernel());
628 const auto thread_processor_id = current_thread->GetActiveCore(); 627 const auto thread_processor_id = current_thread->GetActiveCore();
629 system.ArmInterface(static_cast<std::size_t>(thread_processor_id)).LogBacktrace(); 628 system.ArmInterface(static_cast<std::size_t>(thread_processor_id)).LogBacktrace();
630 } 629 }
@@ -884,7 +883,7 @@ static ResultCode GetInfo(Core::System& system, u64* result, u64 info_id, Handle
884 883
885 const auto& core_timing = system.CoreTiming(); 884 const auto& core_timing = system.CoreTiming();
886 const auto& scheduler = *system.Kernel().CurrentScheduler(); 885 const auto& scheduler = *system.Kernel().CurrentScheduler();
887 const auto* const current_thread = scheduler.GetCurrentThread(); 886 const auto* const current_thread = GetCurrentThreadPointer(system.Kernel());
888 const bool same_thread = current_thread == thread.GetPointerUnsafe(); 887 const bool same_thread = current_thread == thread.GetPointerUnsafe();
889 888
890 const u64 prev_ctx_ticks = scheduler.GetLastContextSwitchTicks(); 889 const u64 prev_ctx_ticks = scheduler.GetLastContextSwitchTicks();
@@ -1103,7 +1102,7 @@ static ResultCode GetThreadContext(Core::System& system, VAddr out_context, Hand
1103 if (thread->GetRawState() != ThreadState::Runnable) { 1102 if (thread->GetRawState() != ThreadState::Runnable) {
1104 bool current = false; 1103 bool current = false;
1105 for (auto i = 0; i < static_cast<s32>(Core::Hardware::NUM_CPU_CORES); ++i) { 1104 for (auto i = 0; i < static_cast<s32>(Core::Hardware::NUM_CPU_CORES); ++i) {
1106 if (thread.GetPointerUnsafe() == kernel.Scheduler(i).GetCurrentThread()) { 1105 if (thread.GetPointerUnsafe() == kernel.Scheduler(i).GetSchedulerCurrentThread()) {
1107 current = true; 1106 current = true;
1108 break; 1107 break;
1109 } 1108 }
@@ -1851,7 +1850,7 @@ static ResultCode StartThread32(Core::System& system, Handle thread_handle) {
1851static void ExitThread(Core::System& system) { 1850static void ExitThread(Core::System& system) {
1852 LOG_DEBUG(Kernel_SVC, "called, pc=0x{:08X}", system.CurrentArmInterface().GetPC()); 1851 LOG_DEBUG(Kernel_SVC, "called, pc=0x{:08X}", system.CurrentArmInterface().GetPC());
1853 1852
1854 auto* const current_thread = system.Kernel().CurrentScheduler()->GetCurrentThread(); 1853 auto* const current_thread = GetCurrentThreadPointer(system.Kernel());
1855 system.GlobalSchedulerContext().RemoveThread(current_thread); 1854 system.GlobalSchedulerContext().RemoveThread(current_thread);
1856 current_thread->Exit(); 1855 current_thread->Exit();
1857 system.Kernel().UnregisterInUseObject(current_thread); 1856 system.Kernel().UnregisterInUseObject(current_thread);
@@ -2993,7 +2992,7 @@ void Call(Core::System& system, u32 immediate) {
2993 auto& kernel = system.Kernel(); 2992 auto& kernel = system.Kernel();
2994 kernel.EnterSVCProfile(); 2993 kernel.EnterSVCProfile();
2995 2994
2996 auto* thread = kernel.CurrentScheduler()->GetCurrentThread(); 2995 auto* thread = GetCurrentThreadPointer(kernel);
2997 thread->SetIsCallingSvc(); 2996 thread->SetIsCallingSvc();
2998 2997
2999 const FunctionDef* info = system.CurrentProcess()->Is64BitProcess() ? GetSVCInfo64(immediate) 2998 const FunctionDef* info = system.CurrentProcess()->Is64BitProcess() ? GetSVCInfo64(immediate)