diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/core/arm/arm_interface.cpp | 2 | ||||
| -rw-r--r-- | src/core/cpu_manager.cpp | 17 | ||||
| -rw-r--r-- | src/core/hle/kernel/k_address_arbiter.cpp | 4 | ||||
| -rw-r--r-- | src/core/hle/kernel/k_condition_variable.cpp | 4 | ||||
| -rw-r--r-- | src/core/hle/kernel/k_interrupt_manager.cpp | 5 | ||||
| -rw-r--r-- | src/core/hle/kernel/k_process.cpp | 10 | ||||
| -rw-r--r-- | src/core/hle/kernel/k_scheduler.cpp | 25 | ||||
| -rw-r--r-- | src/core/hle/kernel/k_scheduler.h | 12 | ||||
| -rw-r--r-- | src/core/hle/kernel/k_thread.cpp | 12 | ||||
| -rw-r--r-- | src/core/hle/kernel/k_thread.h | 1 | ||||
| -rw-r--r-- | src/core/hle/kernel/kernel.cpp | 13 | ||||
| -rw-r--r-- | src/core/hle/kernel/kernel.h | 3 | ||||
| -rw-r--r-- | src/core/hle/kernel/svc.cpp | 13 |
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() { | |||
| 95 | void CpuManager::MultiCoreRunGuestThread() { | 95 | void 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() { | |||
| 132 | void CpuManager::SingleCoreRunGuestThread() { | 132 | void 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 | ||
| 235 | ResultCode KAddressArbiter::WaitIfLessThan(VAddr addr, s32 value, bool decrement, s64 timeout) { | 235 | ResultCode 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 | ||
| 288 | ResultCode KAddressArbiter::WaitIfEqual(VAddr addr, s32 value, s64 timeout) { | 288 | ResultCode 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_) | |||
| 106 | KConditionVariable::~KConditionVariable() = default; | 106 | KConditionVariable::~KConditionVariable() = default; |
| 107 | 107 | ||
| 108 | ResultCode KConditionVariable::SignalToAddress(VAddr addr) { | 108 | ResultCode 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 | ||
| 149 | ResultCode KConditionVariable::WaitForAddress(Handle handle, VAddr addr, u32 value) { | 149 | ResultCode 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 | ||
| 645 | KThread* KScheduler::GetCurrentThread() const { | 645 | KThread* 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 | ||
| 656 | void KScheduler::RescheduleCurrentCore() { | 656 | void 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 | ||
| 719 | void KScheduler::SwitchContextStep2() { | 719 | void 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 | ||
| 726 | void KScheduler::Schedule() { | ||
| 727 | ASSERT(GetCurrentThread(system.Kernel()).GetDisableDispatchCount() == 1); | ||
| 728 | this->ScheduleImpl(); | ||
| 729 | } | ||
| 730 | |||
| 726 | void KScheduler::ScheduleImpl() { | 731 | void 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 | ||
| 1178 | void SetCurrentThread(KernelCore& kernel, KThread* thread) { | ||
| 1179 | kernel.SetCurrentEmuThread(thread); | ||
| 1180 | } | ||
| 1181 | |||
| 1178 | KThread* GetCurrentThreadPointer(KernelCore& kernel) { | 1182 | KThread* 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 | ||
| 109 | void 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 | ||
| 1034 | void KernelCore::SetCurrentEmuThread(KThread* thread) { | ||
| 1035 | impl->SetCurrentEmuThread(thread); | ||
| 1036 | } | ||
| 1037 | |||
| 1027 | KMemoryManager& KernelCore::MemoryManager() { | 1038 | KMemoryManager& 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 | ||
| 343 | static ResultCode SendSyncRequest32(Core::System& system, Handle handle) { | 342 | static 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) { | |||
| 1851 | static void ExitThread(Core::System& system) { | 1850 | static 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) |