diff options
| author | lizzie <lizzie@eden-emu.dev> | 2026-06-23 06:31:25 +0200 |
|---|---|---|
| committer | crueter <crueter@eden-emu.dev> | 2026-06-23 06:31:25 +0200 |
| commit | 3aa0d462598beb2021308eee1d757d74fe33b312 (patch) | |
| tree | ed425c3845ba8fa61184d97b0588cb049b518bd7 /src/core/hle/kernel/k_thread.cpp | |
| parent | f8facda35fe7f17143f84bbfbdacc4cc48678946 (diff) | |
[video_core, hle] remove redundant parent references in system structs (#3908)
reworked a bit to remove references of parent objects and instead pass as arguments to methods to prevent useless reloads
Signed-off-by: lizzie <lizzie@eden-emu.dev>
Co-authored-by: maufeat <sahyno1996@gmail.com>
Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3908
Reviewed-by: Maufeat <sahyno1996@gmail.com>
Reviewed-by: crueter <crueter@eden-emu.dev>
Diffstat (limited to 'src/core/hle/kernel/k_thread.cpp')
| -rw-r--r-- | src/core/hle/kernel/k_thread.cpp | 438 |
1 files changed, 209 insertions, 229 deletions
diff --git a/src/core/hle/kernel/k_thread.cpp b/src/core/hle/kernel/k_thread.cpp index 0af315d726..b499bd4073 100644 --- a/src/core/hle/kernel/k_thread.cpp +++ b/src/core/hle/kernel/k_thread.cpp @@ -95,12 +95,12 @@ namespace Kernel { explicit ThreadQueueImplForKThreadSetProperty(KernelCore& kernel, KThread::WaiterList* wl) : KThreadQueue(kernel), m_wait_list(wl) {} - void CancelWait(KThread* waiting_thread, Result wait_result, bool cancel_timer_task) override { + void CancelWait(KernelCore& kernel, KThread* waiting_thread, Result wait_result, bool cancel_timer_task) override { // Remove the thread from the wait list. m_wait_list->erase(m_wait_list->iterator_to(*waiting_thread)); // Invoke the base cancel wait handler. - KThreadQueue::CancelWait(waiting_thread, wait_result, cancel_timer_task); + KThreadQueue::CancelWait(kernel, waiting_thread, wait_result, cancel_timer_task); } private: @@ -113,7 +113,7 @@ namespace Kernel { : KAutoObjectWithSlabHeapAndContainer{kernel}, m_activity_pause_lock{kernel} {} KThread::~KThread() = default; - Result KThread::Initialize(KThreadFunction func, uintptr_t arg, KProcessAddress user_stack_top, + Result KThread::Initialize(KernelCore& kernel, KThreadFunction func, uintptr_t arg, KProcessAddress user_stack_top, s32 prio, s32 virt_core, KProcess* owner, ThreadType type) { // Assert parameters are valid. ASSERT((type == ThreadType::Main) || (type == ThreadType::Dummy) || @@ -225,12 +225,12 @@ namespace Kernel { if (owner != nullptr) { // Setup the TLS, if needed. if (type == ThreadType::User) { - R_TRY(owner->CreateThreadLocalRegion(std::addressof(m_tls_address))); + R_TRY(owner->CreateThreadLocalRegion(kernel, std::addressof(m_tls_address))); owner->GetMemory().ZeroBlock(m_tls_address, Svc::ThreadLocalRegionSize); } m_parent = owner; - m_parent->Open(); + m_parent->Open(kernel); } // Initialize thread context. @@ -247,28 +247,28 @@ namespace Kernel { this->SetInExceptionHandler(); // Set thread ID. - m_thread_id = m_kernel.CreateNewThreadID(); + m_thread_id = kernel.CreateNewThreadID(); // We initialized! m_initialized = true; // Register ourselves with our parent process. if (m_parent != nullptr) { - m_parent->RegisterThread(this); + m_parent->RegisterThread(kernel, this); if (m_parent->IsSuspended()) { - RequestSuspend(SuspendType::Process); + RequestSuspend(kernel, SuspendType::Process); } } R_SUCCEED(); } - Result KThread::InitializeThread(KThread* thread, KThreadFunction func, uintptr_t arg, + Result KThread::InitializeThread(KernelCore& kernel, KThread* thread, KThreadFunction func, uintptr_t arg, KProcessAddress user_stack_top, s32 prio, s32 core, KProcess* owner, ThreadType type, std::function<void()>&& init_func) { // Initialize the thread. - R_TRY(thread->Initialize(func, arg, user_stack_top, prio, core, owner, type)); + R_TRY(thread->Initialize(kernel, func, arg, user_stack_top, prio, core, owner, type)); // Initialize emulation parameters. thread->m_host_context = std::make_shared<Common::Fiber>(std::move(init_func)); @@ -276,9 +276,9 @@ namespace Kernel { R_SUCCEED(); } - Result KThread::InitializeDummyThread(KThread* thread, KProcess* owner) { + Result KThread::InitializeDummyThread(Core::System& system, KThread* thread, KProcess* owner) { // Initialize the thread. - R_TRY(thread->Initialize({}, {}, {}, DummyThreadPriority, 3, owner, ThreadType::Dummy)); + R_TRY(thread->Initialize(system.Kernel(), {}, {}, {}, DummyThreadPriority, 3, owner, ThreadType::Dummy)); // Initialize emulation parameters. thread->m_stack_parameters.disable_count = 0; @@ -287,37 +287,27 @@ namespace Kernel { } Result KThread::InitializeMainThread(Core::System& system, KThread* thread, s32 virt_core) { - R_RETURN(InitializeThread(thread, {}, {}, {}, IdleThreadPriority, virt_core, {}, - ThreadType::Main, system.GetCpuManager().GetGuestActivateFunc())); + R_RETURN(InitializeThread(system.Kernel(), thread, {}, {}, {}, IdleThreadPriority, virt_core, {}, ThreadType::Main, system.GetCpuManager().GetGuestActivateFunc(system.Kernel()))); } Result KThread::InitializeIdleThread(Core::System& system, KThread* thread, s32 virt_core) { - R_RETURN(InitializeThread(thread, {}, {}, {}, IdleThreadPriority, virt_core, {}, - ThreadType::Main, system.GetCpuManager().GetIdleThreadStartFunc())); + R_RETURN(InitializeThread(system.Kernel(), thread, {}, {}, {}, IdleThreadPriority, virt_core, {}, ThreadType::Main, system.GetCpuManager().GetIdleThreadStartFunc(system.Kernel()))); } - Result KThread::InitializeHighPriorityThread(Core::System& system, KThread* thread, - KThreadFunction func, uintptr_t arg, s32 virt_core) { - R_RETURN(InitializeThread(thread, func, arg, {}, {}, virt_core, nullptr, - ThreadType::HighPriority, - system.GetCpuManager().GetShutdownThreadStartFunc())); + Result KThread::InitializeHighPriorityThread(Core::System& system, KThread* thread, KThreadFunction func, uintptr_t arg, s32 virt_core) { + R_RETURN(InitializeThread(system.Kernel(), thread, func, arg, {}, {}, virt_core, nullptr, ThreadType::HighPriority, system.GetCpuManager().GetShutdownThreadStartFunc(system.Kernel()))); } - Result KThread::InitializeUserThread(Core::System& system, KThread* thread, KThreadFunction func, - uintptr_t arg, KProcessAddress user_stack_top, s32 prio, - s32 virt_core, KProcess* owner) { + Result KThread::InitializeUserThread(Core::System& system, KThread* thread, KThreadFunction func, uintptr_t arg, KProcessAddress user_stack_top, s32 prio, s32 virt_core, KProcess* owner) { system.Kernel().GlobalSchedulerContext().AddThread(thread); - R_RETURN(InitializeThread(thread, func, arg, user_stack_top, prio, virt_core, owner, - ThreadType::User, system.GetCpuManager().GetGuestThreadFunc())); + R_RETURN(InitializeThread(system.Kernel(), thread, func, arg, user_stack_top, prio, virt_core, owner, ThreadType::User, system.GetCpuManager().GetGuestThreadFunc(system.Kernel()))); } - Result KThread::InitializeServiceThread(Core::System& system, KThread* thread, - std::function<void()>&& func, s32 prio, s32 virt_core, - KProcess* owner) { + Result KThread::InitializeServiceThread(Core::System& system, KThread* thread, std::function<void()>&& func, s32 prio, s32 virt_core, KProcess* owner) { system.Kernel().GlobalSchedulerContext().AddThread(thread); std::function<void()> func2{[&system, func_{std::move(func)}] { // Similar to UserModeThreadStarter. - system.Kernel().CurrentScheduler()->OnThreadStart(); + system.Kernel().CurrentScheduler()->OnThreadStart(system.Kernel()); // Run the guest function. func_(); @@ -326,35 +316,35 @@ namespace Kernel { Svc::ExitThread(system); }}; - R_RETURN(InitializeThread(thread, {}, {}, {}, prio, virt_core, owner, ThreadType::HighPriority, + R_RETURN(InitializeThread(system.Kernel(), thread, {}, {}, {}, prio, virt_core, owner, ThreadType::HighPriority, std::move(func2))); } - void KThread::PostDestroy(uintptr_t arg) { + void KThread::PostDestroy(KernelCore& kernel, uintptr_t arg) { KProcess* owner = reinterpret_cast<KProcess*>(arg & ~1ULL); const bool resource_limit_release_hint = (arg & 1); const s64 hint_value = (resource_limit_release_hint ? 0 : 1); if (owner != nullptr) { - owner->GetResourceLimit()->Release(LimitableResource::ThreadCountMax, 1, hint_value); - owner->Close(); + owner->GetResourceLimit()->Release(kernel, LimitableResource::ThreadCountMax, 1, hint_value); + owner->Close(kernel); } } - void KThread::Finalize() { + void KThread::Finalize(KernelCore& kernel) { // If the thread has an owner process, unregister it. if (m_parent != nullptr) { - m_parent->UnregisterThread(this); + m_parent->UnregisterThread(kernel, this); } // If the thread has a local region, delete it. if (m_tls_address != 0) { - ASSERT(m_parent->DeleteThreadLocalRegion(m_tls_address).IsSuccess()); + ASSERT(m_parent->DeleteThreadLocalRegion(kernel, m_tls_address).IsSuccess()); } // Release any waiters. { ASSERT(m_waiting_lock_info == nullptr); - KScopedSchedulerLock sl{m_kernel}; + KScopedSchedulerLock sl{kernel}; // Check that we have no kernel waiters. ASSERT(m_num_kernel_waiters == 0); @@ -378,14 +368,14 @@ namespace Kernel { } // Cancel the thread's wait. - waiter->CancelWait(ResultInvalidState, true); + waiter->CancelWait(kernel, ResultInvalidState, true); } // Remove the held lock from our list. it = m_held_lock_info_list.erase(it); // Free the lock info. - LockWithPriorityInheritanceInfo::Free(m_kernel, lock_info); + LockWithPriorityInheritanceInfo::Free(kernel, lock_info); } } @@ -393,35 +383,35 @@ namespace Kernel { m_host_context.reset(); // Perform inherited finalization. - KSynchronizationObject::Finalize(); + KSynchronizationObject::Finalize(kernel); } - bool KThread::IsSignaled() const { + bool KThread::IsSignaled(KernelCore& kernel) const { return m_signaled; } - void KThread::OnTimer() { - ASSERT(KScheduler::IsSchedulerLockedByCurrentThread(m_kernel)); + void KThread::OnTimer(KernelCore& kernel) { + ASSERT(KScheduler::IsSchedulerLockedByCurrentThread(kernel)); // If we're waiting, cancel the wait. if (this->GetState() == ThreadState::Waiting) { - m_wait_queue->CancelWait(this, ResultTimedOut, false); + m_wait_queue->CancelWait(kernel, this, ResultTimedOut, false); } } - void KThread::StartTermination() { - ASSERT(KScheduler::IsSchedulerLockedByCurrentThread(m_kernel)); + void KThread::StartTermination(KernelCore& kernel) { + ASSERT(KScheduler::IsSchedulerLockedByCurrentThread(kernel)); // Release user exception and unpin, if relevant. if (m_parent != nullptr) { - m_parent->ReleaseUserException(this); - if (m_parent->GetPinnedThread(GetCurrentCoreId(m_kernel)) == this) { - m_parent->UnpinCurrentThread(); + m_parent->ReleaseUserException(kernel, this); + if (m_parent->GetPinnedThread(GetCurrentCoreId(kernel)) == this) { + m_parent->UnpinCurrentThread(kernel); } } // Set state to terminated. - this->SetState(ThreadState::Terminated); + this->SetState(kernel, ThreadState::Terminated); // Clear the thread's status as running in parent. if (m_parent != nullptr) { @@ -429,41 +419,41 @@ namespace Kernel { } // Clear previous thread in KScheduler. - KScheduler::ClearPreviousThread(m_kernel, this); + KScheduler::ClearPreviousThread(kernel, this); // Register terminated dpc flag. this->RegisterDpc(DpcFlag::Terminated); } - void KThread::FinishTermination() { + void KThread::FinishTermination(KernelCore& kernel) { // Ensure that the thread is not executing on any core. if (m_parent != nullptr) { - for (std::size_t i = 0; i < static_cast<std::size_t>(Core::Hardware::NUM_CPU_CORES); ++i) { + for (std::size_t i = 0; i < std::size_t(Core::Hardware::NUM_CPU_CORES); ++i) { KThread* core_thread{}; do { - core_thread = m_kernel.Scheduler(i).GetSchedulerCurrentThread(); + core_thread = kernel.Scheduler(i).GetSchedulerCurrentThread(); } while (core_thread == this); } } // Acquire the scheduler lock. - KScopedSchedulerLock sl{m_kernel}; + KScopedSchedulerLock sl{kernel}; // Signal. m_signaled = true; - KSynchronizationObject::NotifyAvailable(); + KSynchronizationObject::NotifyAvailable(kernel); // Close the thread. - this->Close(); + this->Close(kernel); } - void KThread::DoWorkerTaskImpl() { + void KThread::DoWorkerTaskImpl(KernelCore& kernel) { // Finish the termination that was begun by Exit(). - this->FinishTermination(); + this->FinishTermination(kernel); } - void KThread::Pin(s32 current_core) { - ASSERT(KScheduler::IsSchedulerLockedByCurrentThread(m_kernel)); + void KThread::Pin(KernelCore& kernel, s32 current_core) { + ASSERT(KScheduler::IsSchedulerLockedByCurrentThread(kernel)); // Set ourselves as pinned. GetStackParameters().is_pinned = true; @@ -487,7 +477,7 @@ namespace Kernel { if (active_core != current_core || m_physical_affinity_mask.GetAffinityMask() != m_original_physical_affinity_mask.GetAffinityMask()) { - KScheduler::OnThreadAffinityMaskChanged(m_kernel, this, + KScheduler::OnThreadAffinityMaskChanged(kernel, this, m_original_physical_affinity_mask, active_core); } } @@ -499,15 +489,15 @@ namespace Kernel { static_cast<u32>(ThreadState::SuspendShift))); // Update our state. - this->UpdateState(); + this->UpdateState(kernel); } // TODO(bunnei): Update our SVC access permissions. ASSERT(m_parent != nullptr); } - void KThread::Unpin() { - ASSERT(KScheduler::IsSchedulerLockedByCurrentThread(m_kernel)); + void KThread::Unpin(KernelCore& kernel) { + ASSERT(KScheduler::IsSchedulerLockedByCurrentThread(kernel)); // Set ourselves as unpinned. this->GetStackParameters().is_pinned = false; @@ -535,7 +525,7 @@ namespace Kernel { std::countl_zero(m_physical_affinity_mask.GetAffinityMask()))); } } - KScheduler::OnThreadAffinityMaskChanged(m_kernel, this, old_mask, active_core); + KScheduler::OnThreadAffinityMaskChanged(kernel, this, old_mask, active_core); } } @@ -546,20 +536,19 @@ namespace Kernel { static_cast<u32>(ThreadState::SuspendShift))); // Update our state. - this->UpdateState(); + this->UpdateState(kernel); } // TODO(bunnei): Update our SVC access permissions. ASSERT(m_parent != nullptr); // Resume any threads that began waiting on us while we were pinned. - for (auto it = m_pinned_waiter_list.begin(); it != m_pinned_waiter_list.end(); - it = m_pinned_waiter_list.erase(it)) { - it->EndWait(ResultSuccess); - } + for (auto it = m_pinned_waiter_list.begin(); it != m_pinned_waiter_list.end(); it = m_pinned_waiter_list.erase(it)) { + it->EndWait(kernel, ResultSuccess); + } } - u16 KThread::GetUserDisableCount() const { + u16 KThread::GetUserDisableCount(KernelCore& kernel) const { if (!this->IsUserThread()) { // We only emulate TLS for user threads return {}; @@ -569,7 +558,7 @@ namespace Kernel { return memory.Read16(m_tls_address + offsetof(ThreadLocalRegion, disable_count)); } - void KThread::SetInterruptFlag() { + void KThread::SetInterruptFlag(KernelCore& kernel) { if (!this->IsUserThread()) { // We only emulate TLS for user threads return; @@ -579,7 +568,7 @@ namespace Kernel { memory.Write16(m_tls_address + offsetof(ThreadLocalRegion, interrupt_flag), 1); } - void KThread::ClearInterruptFlag() { + void KThread::ClearInterruptFlag(KernelCore& kernel) { if (!this->IsUserThread()) { // We only emulate TLS for user threads return; @@ -589,7 +578,7 @@ namespace Kernel { memory.Write16(m_tls_address + offsetof(ThreadLocalRegion, interrupt_flag), 0); } - void KThread::UpdateTlsThreadCpuTime(s64 switch_tick) { + void KThread::UpdateTlsThreadCpuTime(KernelCore& kernel, s64 switch_tick) { if (!this->IsUserThread()) { return; } @@ -602,8 +591,8 @@ namespace Kernel { memory.Write64(m_tls_address + offsetof(ThreadLocalRegion, thread_cpu_time), static_cast<u64>(value)); } - Result KThread::GetCoreMask(s32* out_ideal_core, u64* out_affinity_mask) { - KScopedSchedulerLock sl{m_kernel}; + Result KThread::GetCoreMask(KernelCore& kernel, s32* out_ideal_core, u64* out_affinity_mask) { + KScopedSchedulerLock sl{kernel}; // Get the virtual mask. *out_ideal_core = m_virtual_ideal_core_id; @@ -612,8 +601,8 @@ namespace Kernel { R_SUCCEED(); } - Result KThread::GetPhysicalCoreMask(s32* out_ideal_core, u64* out_affinity_mask) { - KScopedSchedulerLock sl{m_kernel}; + Result KThread::GetPhysicalCoreMask(KernelCore& kernel, s32* out_ideal_core, u64* out_affinity_mask) { + KScopedSchedulerLock sl{kernel}; ASSERT(m_num_core_migration_disables >= 0); // Select between core mask and original core mask. @@ -628,7 +617,7 @@ namespace Kernel { R_SUCCEED(); } - Result KThread::SetCoreMask(s32 core_id, u64 v_affinity_mask) { + Result KThread::SetCoreMask(KernelCore& kernel, s32 core_id, u64 v_affinity_mask) { ASSERT(m_parent != nullptr); ASSERT(v_affinity_mask != 0); KScopedLightLock lk(m_activity_pause_lock); @@ -636,7 +625,7 @@ namespace Kernel { // Set the core mask. u64 p_affinity_mask = 0; { - KScopedSchedulerLock sl(m_kernel); + KScopedSchedulerLock sl(kernel); ASSERT(m_num_core_migration_disables >= 0); // If we're updating, set our ideal virtual core. @@ -682,7 +671,7 @@ namespace Kernel { std::countl_zero(m_physical_affinity_mask.GetAffinityMask())); SetActiveCore(new_core); } - KScheduler::OnThreadAffinityMaskChanged(m_kernel, this, old_mask, active_core); + KScheduler::OnThreadAffinityMaskChanged(kernel, this, old_mask, active_core); } } else { // Otherwise, we edit the original affinity for restoration later. @@ -692,12 +681,12 @@ namespace Kernel { } // Update the pinned waiter list. - ThreadQueueImplForKThreadSetProperty wait_queue(m_kernel, std::addressof(m_pinned_waiter_list)); + ThreadQueueImplForKThreadSetProperty wait_queue(kernel, std::addressof(m_pinned_waiter_list)); { bool retry_update{}; do { // Lock the scheduler. - KScopedSchedulerLock sl(m_kernel); + KScopedSchedulerLock sl(kernel); // Don't do any further management if our termination has been requested. R_SUCCEED_IF(this->IsTerminationRequested()); @@ -710,7 +699,7 @@ namespace Kernel { s32 thread_core; for (thread_core = 0; thread_core < static_cast<s32>(Core::Hardware::NUM_CPU_CORES); ++thread_core) { - if (m_kernel.Scheduler(thread_core).GetSchedulerCurrentThread() == this) { + if (kernel.Scheduler(thread_core).GetSchedulerCurrentThread() == this) { thread_is_current = true; break; } @@ -722,12 +711,12 @@ namespace Kernel { // If the thread is pinned, we want to wait until it's not pinned. if (this->GetStackParameters().is_pinned) { // Verify that the current thread isn't terminating. - R_UNLESS(!GetCurrentThread(m_kernel).IsTerminationRequested(), + R_UNLESS(!GetCurrentThread(kernel).IsTerminationRequested(), ResultTerminationRequested); // Wait until the thread isn't pinned any more. - m_pinned_waiter_list.push_back(GetCurrentThread(m_kernel)); - GetCurrentThread(m_kernel).BeginWait(std::addressof(wait_queue)); + m_pinned_waiter_list.push_back(GetCurrentThread(kernel)); + GetCurrentThread(kernel).BeginWait(kernel, std::addressof(wait_queue)); } else { // If the thread isn't pinned, release the scheduler lock and retry until it's // not current. @@ -740,25 +729,25 @@ namespace Kernel { R_SUCCEED(); } - void KThread::SetBasePriority(s32 value) { + void KThread::SetBasePriority(KernelCore& kernel, s32 value) { ASSERT(Svc::HighestThreadPriority <= value && value <= Svc::LowestThreadPriority); - KScopedSchedulerLock sl{m_kernel}; + KScopedSchedulerLock sl{kernel}; // Change our base priority. m_base_priority = value; // Perform a priority restoration. - RestorePriority(m_kernel, this); + RestorePriority(kernel, this); } - KThread* KThread::GetLockOwner() const { + KThread* KThread::GetLockOwner(KernelCore& kernel) const { return m_waiting_lock_info != nullptr ? m_waiting_lock_info->GetOwner() : nullptr; } - void KThread::IncreaseBasePriority(s32 priority) { + void KThread::IncreaseBasePriority(KernelCore& kernel, s32 priority) { ASSERT(Svc::HighestThreadPriority <= priority && priority <= Svc::LowestThreadPriority); - ASSERT(KScheduler::IsSchedulerLockedByCurrentThread(m_kernel)); + ASSERT(KScheduler::IsSchedulerLockedByCurrentThread(kernel)); ASSERT(!this->GetStackParameters().is_pinned); // Set our base priority. @@ -766,47 +755,47 @@ namespace Kernel { m_base_priority = priority; // Perform a priority restoration. - RestorePriority(m_kernel, this); + RestorePriority(kernel, this); } } - void KThread::RequestSuspend(SuspendType type) { - KScopedSchedulerLock sl{m_kernel}; + void KThread::RequestSuspend(KernelCore& kernel, SuspendType type) { + KScopedSchedulerLock sl{kernel}; // Note the request in our flags. m_suspend_request_flags |= (1U << (static_cast<u32>(ThreadState::SuspendShift) + static_cast<u32>(type))); // Try to perform the suspend. - this->TrySuspend(); + this->TrySuspend(kernel); } - void KThread::Resume(SuspendType type) { - KScopedSchedulerLock sl{m_kernel}; + void KThread::Resume(KernelCore& kernel, SuspendType type) { + KScopedSchedulerLock sl{kernel}; // Clear the request in our flags. m_suspend_request_flags &= ~(1U << (static_cast<u32>(ThreadState::SuspendShift) + static_cast<u32>(type))); // Update our state. - this->UpdateState(); + this->UpdateState(kernel); } - void KThread::WaitCancel() { - KScopedSchedulerLock sl{m_kernel}; + void KThread::WaitCancel(KernelCore& kernel) { + KScopedSchedulerLock sl{kernel}; // Check if we're waiting and cancellable. if (this->GetState() == ThreadState::Waiting && m_cancellable) { m_wait_cancelled = false; - m_wait_queue->CancelWait(this, ResultCancelled, true); + m_wait_queue->CancelWait(kernel, this, ResultCancelled, true); } else { // Otherwise, note that we cancelled a wait. m_wait_cancelled = true; } } - void KThread::TrySuspend() { - ASSERT(KScheduler::IsSchedulerLockedByCurrentThread(m_kernel)); + void KThread::TrySuspend(KernelCore& kernel) { + ASSERT(KScheduler::IsSchedulerLockedByCurrentThread(kernel)); ASSERT(this->IsSuspendRequested()); // Ensure that we have no waiters. @@ -816,11 +805,11 @@ namespace Kernel { ASSERT(this->GetNumKernelWaiters() == 0); // Perform the suspend. - this->UpdateState(); + this->UpdateState(kernel); } - void KThread::UpdateState() { - ASSERT(KScheduler::IsSchedulerLockedByCurrentThread(m_kernel)); + void KThread::UpdateState(KernelCore& kernel) { + ASSERT(KScheduler::IsSchedulerLockedByCurrentThread(kernel)); // Set our suspend flags in state. const ThreadState old_state = m_thread_state.load(std::memory_order_relaxed); @@ -830,37 +819,37 @@ namespace Kernel { // Note the state change in scheduler. if (new_state != old_state) { - KScheduler::OnThreadStateChanged(m_kernel, this, old_state); + KScheduler::OnThreadStateChanged(kernel, this, old_state); } } - void KThread::Continue() { - ASSERT(KScheduler::IsSchedulerLockedByCurrentThread(m_kernel)); + void KThread::Continue(KernelCore& kernel) { + ASSERT(KScheduler::IsSchedulerLockedByCurrentThread(kernel)); // Clear our suspend flags in state. const ThreadState old_state = m_thread_state.load(std::memory_order_relaxed); m_thread_state.store(old_state & ThreadState::Mask, std::memory_order_relaxed); // Note the state change in scheduler. - KScheduler::OnThreadStateChanged(m_kernel, this, old_state); + KScheduler::OnThreadStateChanged(kernel, this, old_state); } - void KThread::CloneFpuStatus() { + void KThread::CloneFpuStatus(KernelCore& kernel) { // We shouldn't reach here when starting kernel threads. ASSERT(this->GetOwnerProcess() != nullptr); - ASSERT(this->GetOwnerProcess() == GetCurrentProcessPointer(m_kernel)); + ASSERT(this->GetOwnerProcess() == GetCurrentProcessPointer(kernel)); - m_kernel.CurrentPhysicalCore().CloneFpuStatus(this); + kernel.CurrentPhysicalCore().CloneFpuStatus(this); } - Result KThread::SetActivity(Svc::ThreadActivity activity) { + Result KThread::SetActivity(KernelCore& kernel, Svc::ThreadActivity activity) { // Lock ourselves. KScopedLightLock lk(m_activity_pause_lock); // Set the activity. { // Lock the scheduler. - KScopedSchedulerLock sl(m_kernel); + KScopedSchedulerLock sl(kernel); // Verify our state. const auto cur_state = this->GetState(); @@ -873,7 +862,7 @@ namespace Kernel { R_UNLESS(!this->IsSuspendRequested(SuspendType::Thread), ResultInvalidState); // Suspend. - this->RequestSuspend(SuspendType::Thread); + this->RequestSuspend(kernel, SuspendType::Thread); } else { ASSERT(activity == Svc::ThreadActivity::Runnable); @@ -881,19 +870,19 @@ namespace Kernel { R_UNLESS(this->IsSuspendRequested(SuspendType::Thread), ResultInvalidState); // Resume. - this->Resume(SuspendType::Thread); + this->Resume(kernel, SuspendType::Thread); } } // If the thread is now paused, update the pinned waiter list. if (activity == Svc::ThreadActivity::Paused) { - ThreadQueueImplForKThreadSetProperty wait_queue(m_kernel, + ThreadQueueImplForKThreadSetProperty wait_queue(kernel, std::addressof(m_pinned_waiter_list)); bool thread_is_current{}; do { // Lock the scheduler. - KScopedSchedulerLock sl(m_kernel); + KScopedSchedulerLock sl(kernel); // Don't do any further management if our termination has been requested. R_SUCCEED_IF(this->IsTerminationRequested()); @@ -904,17 +893,17 @@ namespace Kernel { // Check whether the thread is pinned. if (this->GetStackParameters().is_pinned) { // Verify that the current thread isn't terminating. - R_UNLESS(!GetCurrentThread(m_kernel).IsTerminationRequested(), + R_UNLESS(!GetCurrentThread(kernel).IsTerminationRequested(), ResultTerminationRequested); // Wait until the thread isn't pinned any more. - m_pinned_waiter_list.push_back(GetCurrentThread(m_kernel)); - GetCurrentThread(m_kernel).BeginWait(std::addressof(wait_queue)); + m_pinned_waiter_list.push_back(GetCurrentThread(kernel)); + GetCurrentThread(kernel).BeginWait(kernel, std::addressof(wait_queue)); } else { // Check if the thread is currently running. // If it is, we'll need to retry. for (auto i = 0; i < static_cast<s32>(Core::Hardware::NUM_CPU_CORES); ++i) { - if (m_kernel.Scheduler(i).GetSchedulerCurrentThread() == this) { + if (kernel.Scheduler(i).GetSchedulerCurrentThread() == this) { thread_is_current = true; break; } @@ -926,14 +915,14 @@ namespace Kernel { R_SUCCEED(); } - Result KThread::GetThreadContext3(Svc::ThreadContext* out) { + Result KThread::GetThreadContext3(KernelCore& kernel, Svc::ThreadContext* out) { // Lock ourselves. KScopedLightLock lk{m_activity_pause_lock}; // Get the context. { // Lock the scheduler. - KScopedSchedulerLock sl{m_kernel}; + KScopedSchedulerLock sl{kernel}; // Verify that we're suspended. R_UNLESS(this->IsSuspendRequested(SuspendType::Thread), ResultInvalidState); @@ -957,8 +946,8 @@ namespace Kernel { R_SUCCEED(); } - void KThread::AddHeldLock(LockWithPriorityInheritanceInfo* lock_info) { - ASSERT(KScheduler::IsSchedulerLockedByCurrentThread(m_kernel)); + void KThread::AddHeldLock(KernelCore& kernel, LockWithPriorityInheritanceInfo* lock_info) { + ASSERT(KScheduler::IsSchedulerLockedByCurrentThread(kernel)); // Set ourselves as the lock's owner. lock_info->SetOwner(this); @@ -967,23 +956,21 @@ namespace Kernel { m_held_lock_info_list.push_front(*lock_info); } - KThread::LockWithPriorityInheritanceInfo* KThread::FindHeldLock(KProcessAddress address_key, - bool is_kernel_address_key) { - ASSERT(KScheduler::IsSchedulerLockedByCurrentThread(m_kernel)); + KThread::LockWithPriorityInheritanceInfo* KThread::FindHeldLock(KernelCore& kernel, KProcessAddress address_key, bool is_kernel_address_key) { + ASSERT(KScheduler::IsSchedulerLockedByCurrentThread(kernel)); // Try to find an existing held lock. for (auto& held_lock : m_held_lock_info_list) { - if (held_lock.GetAddressKey() == address_key && - held_lock.GetIsKernelAddressKey() == is_kernel_address_key) { + if (held_lock.GetAddressKey() == address_key && held_lock.GetIsKernelAddressKey() == is_kernel_address_key) { return std::addressof(held_lock); - } + } } return nullptr; } - void KThread::AddWaiterImpl(KThread* thread) { - ASSERT(KScheduler::IsSchedulerLockedByCurrentThread(m_kernel)); + void KThread::AddWaiterImpl(KernelCore& kernel, KThread* thread) { + ASSERT(KScheduler::IsSchedulerLockedByCurrentThread(kernel)); ASSERT(thread->GetConditionVariableTree() == nullptr); // Get the thread's address key. @@ -993,31 +980,31 @@ namespace Kernel { // Keep track of how many kernel waiters we have. if (is_kernel_address_key) { ASSERT((m_num_kernel_waiters++) >= 0); - KScheduler::SetSchedulerUpdateNeeded(m_kernel); + KScheduler::SetSchedulerUpdateNeeded(kernel); } // Get the relevant lock info. - auto* lock_info = this->FindHeldLock(address_key, is_kernel_address_key); + auto* lock_info = this->FindHeldLock(kernel, address_key, is_kernel_address_key); if (lock_info == nullptr) { // Create a new lock for the address key. lock_info = - LockWithPriorityInheritanceInfo::Create(m_kernel, address_key, is_kernel_address_key); + LockWithPriorityInheritanceInfo::Create(kernel, address_key, is_kernel_address_key); // Add the new lock to our list. - this->AddHeldLock(lock_info); + this->AddHeldLock(kernel, lock_info); } // Add the thread as waiter to the lock info. lock_info->AddWaiter(thread); } - void KThread::RemoveWaiterImpl(KThread* thread) { - ASSERT(KScheduler::IsSchedulerLockedByCurrentThread(m_kernel)); + void KThread::RemoveWaiterImpl(KernelCore& kernel, KThread* thread) { + ASSERT(KScheduler::IsSchedulerLockedByCurrentThread(kernel)); // Keep track of how many kernel waiters we have. if (thread->GetIsKernelAddressKey()) { ASSERT((m_num_kernel_waiters--) > 0); - KScheduler::SetSchedulerUpdateNeeded(m_kernel); + KScheduler::SetSchedulerUpdateNeeded(kernel); } // Get the info for the lock the thread is waiting on. @@ -1027,7 +1014,7 @@ namespace Kernel { // Remove the waiter. if (lock_info->RemoveWaiter(thread)) { m_held_lock_info_list.erase(m_held_lock_info_list.iterator_to(*lock_info)); - LockWithPriorityInheritanceInfo::Free(m_kernel, lock_info); + LockWithPriorityInheritanceInfo::Free(kernel, lock_info); } } @@ -1048,12 +1035,12 @@ namespace Kernel { } // Get the owner of whatever lock this thread is waiting on. - KThread* const lock_owner = thread->GetLockOwner(); + KThread* const lock_owner = thread->GetLockOwner(kernel); // If the thread is waiting on some lock, remove it as a waiter to prevent violating red // black tree invariants. if (lock_owner != nullptr) { - lock_owner->RemoveWaiterImpl(thread); + lock_owner->RemoveWaiterImpl(kernel, thread); } // Ensure we don't violate condition variable red black tree invariants. @@ -1072,7 +1059,7 @@ namespace Kernel { // If we removed the thread from some lock's waiting list, add it back. if (lock_owner != nullptr) { - lock_owner->AddWaiterImpl(thread); + lock_owner->AddWaiterImpl(kernel, thread); } // Update the scheduler. @@ -1083,32 +1070,30 @@ namespace Kernel { } } - void KThread::AddWaiter(KThread* thread) { - this->AddWaiterImpl(thread); + void KThread::AddWaiter(KernelCore& kernel, KThread* thread) { + this->AddWaiterImpl(kernel, thread); // If the thread has a higher priority than us, we should inherit. if (thread->GetPriority() < this->GetPriority()) { - RestorePriority(m_kernel, this); + RestorePriority(kernel, this); } } - void KThread::RemoveWaiter(KThread* thread) { - this->RemoveWaiterImpl(thread); + void KThread::RemoveWaiter(KernelCore& kernel, KThread* thread) { + this->RemoveWaiterImpl(kernel, thread); // If our priority is the same as the thread's (and we've inherited), we may need to restore to // lower priority. - if (this->GetPriority() == thread->GetPriority() && - this->GetPriority() < this->GetBasePriority()) { - RestorePriority(m_kernel, this); - } + if (this->GetPriority() == thread->GetPriority() && this->GetPriority() < this->GetBasePriority()) { + RestorePriority(kernel, this); + } } - KThread* KThread::RemoveWaiterByKey(bool* out_has_waiters, KProcessAddress key, - bool is_kernel_address_key_) { - ASSERT(KScheduler::IsSchedulerLockedByCurrentThread(m_kernel)); + KThread* KThread::RemoveWaiterByKey(KernelCore& kernel, bool* out_has_waiters, KProcessAddress key, bool is_kernel_address_key_) { + ASSERT(KScheduler::IsSchedulerLockedByCurrentThread(kernel)); // Get the relevant lock info. - auto* lock_info = this->FindHeldLock(key, is_kernel_address_key_); + auto* lock_info = this->FindHeldLock(kernel, key, is_kernel_address_key_); if (lock_info == nullptr) { *out_has_waiters = false; return nullptr; @@ -1121,7 +1106,7 @@ namespace Kernel { if (lock_info->GetIsKernelAddressKey()) { m_num_kernel_waiters -= lock_info->GetWaiterCount(); ASSERT(m_num_kernel_waiters >= 0); - KScheduler::SetSchedulerUpdateNeeded(m_kernel); + KScheduler::SetSchedulerUpdateNeeded(kernel); } ASSERT(lock_info->GetWaiterCount() > 0); @@ -1133,13 +1118,13 @@ namespace Kernel { *out_has_waiters = false; // Free the lock info, since it has no waiters. - LockWithPriorityInheritanceInfo::Free(m_kernel, lock_info); + LockWithPriorityInheritanceInfo::Free(kernel, lock_info); } else { // There are additional waiters on the lock. *out_has_waiters = true; // Add the lock to the new owner's held list. - next_lock_owner->AddHeldLock(lock_info); + next_lock_owner->AddHeldLock(kernel, lock_info); // Keep track of any kernel waiters for the new owner. if (lock_info->GetIsKernelAddressKey()) { @@ -1155,7 +1140,7 @@ namespace Kernel { // to lower priority. if (this->GetPriority() == next_lock_owner->GetPriority() && this->GetPriority() < this->GetBasePriority()) { - RestorePriority(m_kernel, this); + RestorePriority(kernel, this); // NOTE: No need to restore priority on the next lock owner, because it was already the // highest priority waiter on the lock. } @@ -1164,91 +1149,91 @@ namespace Kernel { return next_lock_owner; } - Result KThread::Run() { + Result KThread::Run(KernelCore& kernel) { while (true) { - KScopedSchedulerLock lk{m_kernel}; + KScopedSchedulerLock lk{kernel}; // If either this thread or the current thread are requesting termination, note it. R_UNLESS(!this->IsTerminationRequested(), ResultTerminationRequested); - R_UNLESS(!GetCurrentThread(m_kernel).IsTerminationRequested(), ResultTerminationRequested); + R_UNLESS(!GetCurrentThread(kernel).IsTerminationRequested(), ResultTerminationRequested); // Ensure our thread state is correct. R_UNLESS(this->GetState() == ThreadState::Initialized, ResultInvalidState); // If the current thread has been asked to suspend, suspend it and retry. - if (GetCurrentThread(m_kernel).IsSuspended()) { - GetCurrentThread(m_kernel).UpdateState(); + if (GetCurrentThread(kernel).IsSuspended()) { + GetCurrentThread(kernel).UpdateState(kernel); continue; } // If we're not a kernel thread and we've been asked to suspend, suspend ourselves. if (KProcess* owner = this->GetOwnerProcess(); owner != nullptr) { if (this->IsUserThread() && this->IsSuspended()) { - this->UpdateState(); + this->UpdateState(kernel); } - owner->IncrementRunningThreadCount(); + owner->IncrementRunningThreadCount(kernel); } // Open a reference, now that we're running. - this->Open(); + this->Open(kernel); // Set our state and finish. - this->SetState(ThreadState::Runnable); + this->SetState(kernel, ThreadState::Runnable); R_SUCCEED(); } } - void KThread::Exit() { - ASSERT(this == GetCurrentThreadPointer(m_kernel)); + void KThread::Exit(KernelCore& kernel) { + ASSERT(this == GetCurrentThreadPointer(kernel)); // Release the thread resource hint, running thread count from parent. if (m_parent != nullptr) { - m_parent->GetResourceLimit()->Release(Kernel::LimitableResource::ThreadCountMax, 0, 1); + m_parent->GetResourceLimit()->Release(kernel, Kernel::LimitableResource::ThreadCountMax, 0, 1); m_resource_limit_release_hint = true; - m_parent->DecrementRunningThreadCount(); + m_parent->DecrementRunningThreadCount(kernel); } // Perform termination. { - KScopedSchedulerLock sl{m_kernel}; + KScopedSchedulerLock sl{kernel}; // Disallow all suspension. m_suspend_allowed_flags = 0; - this->UpdateState(); + this->UpdateState(kernel); // Disallow all suspension. m_suspend_allowed_flags = 0; // Start termination. - this->StartTermination(); + this->StartTermination(kernel); // Register the thread as a work task. - KWorkerTaskManager::AddTask(m_kernel, KWorkerTaskManager::WorkerType::Exit, this); + KWorkerTaskManager::AddTask(kernel, KWorkerTaskManager::WorkerType::Exit, this); } UNREACHABLE_MSG("KThread::Exit() would return"); } - Result KThread::Terminate() { - ASSERT(this != GetCurrentThreadPointer(m_kernel)); + Result KThread::Terminate(KernelCore& kernel) { + ASSERT(this != GetCurrentThreadPointer(kernel)); // Request the thread terminate if it hasn't already. - if (const auto new_state = this->RequestTerminate(); new_state != ThreadState::Terminated) { + if (const auto new_state = this->RequestTerminate(kernel); new_state != ThreadState::Terminated) { // If the thread isn't terminated, wait for it to terminate. s32 index; KSynchronizationObject* objects[] = {this}; - R_TRY(KSynchronizationObject::Wait(m_kernel, std::addressof(index), objects, 1, + R_TRY(KSynchronizationObject::Wait(kernel, std::addressof(index), objects, 1, Svc::WaitInfinite)); } R_SUCCEED(); } - ThreadState KThread::RequestTerminate() { - ASSERT(this != GetCurrentThreadPointer(m_kernel)); + ThreadState KThread::RequestTerminate(KernelCore& kernel) { + ASSERT(this != GetCurrentThreadPointer(kernel)); - KScopedSchedulerLock sl{m_kernel}; + KScopedSchedulerLock sl{kernel}; // Determine if this is the first termination request. const bool first_request = [&]() -> bool { @@ -1270,46 +1255,46 @@ namespace Kernel { // If the thread is pinned, unpin it. if (this->GetStackParameters().is_pinned) { - this->GetOwnerProcess()->UnpinThread(this); + this->GetOwnerProcess()->UnpinThread(kernel, this); } // If the thread is suspended, continue it. if (this->IsSuspended()) { m_suspend_allowed_flags = 0; - this->UpdateState(); + this->UpdateState(kernel); } // Change the thread's priority to be higher than any system thread's. - this->IncreaseBasePriority(TerminatingThreadPriority); + this->IncreaseBasePriority(kernel, TerminatingThreadPriority); // If the thread is runnable, send a termination interrupt to cores it may be running on. if (this->GetState() == ThreadState::Runnable) { // NOTE: We do not mask the "current core", because this code may not actually be // executing from the thread representing the "current core". if (const u64 core_mask = m_physical_affinity_mask.GetAffinityMask(); core_mask != 0) { - Kernel::KInterruptManager::SendInterProcessorInterrupt(m_kernel, core_mask); + Kernel::KInterruptManager::SendInterProcessorInterrupt(kernel, core_mask); } } // Wake up the thread. if (this->GetState() == ThreadState::Waiting) { - m_wait_queue->CancelWait(this, ResultTerminationRequested, true); + m_wait_queue->CancelWait(kernel, this, ResultTerminationRequested, true); } } return this->GetState(); } - Result KThread::Sleep(s64 timeout) { - ASSERT(!KScheduler::IsSchedulerLockedByCurrentThread(m_kernel)); - ASSERT(this == GetCurrentThreadPointer(m_kernel)); + Result KThread::Sleep(KernelCore& kernel, s64 timeout) { + ASSERT(!KScheduler::IsSchedulerLockedByCurrentThread(kernel)); + ASSERT(this == GetCurrentThreadPointer(kernel)); ASSERT(timeout > 0); - ThreadQueueImplForKThreadSleep wait_queue(m_kernel); + ThreadQueueImplForKThreadSleep wait_queue(kernel); KHardwareTimer* timer{}; { // Setup the scheduling lock and sleep. - KScopedSchedulerLockAndSleep slp(m_kernel, std::addressof(timer), this, timeout); + KScopedSchedulerLockAndSleep slp(kernel, std::addressof(timer), this, timeout); // Check if the thread should terminate. if (this->IsTerminationRequested()) { @@ -1319,15 +1304,15 @@ namespace Kernel { // Wait for the sleep to end. wait_queue.SetHardwareTimer(timer); - this->BeginWait(std::addressof(wait_queue)); + this->BeginWait(kernel, std::addressof(wait_queue)); this->SetWaitReasonForDebugging(ThreadWaitReasonForDebugging::Sleep); } R_SUCCEED(); } - void KThread::RequestDummyThreadWait() { - ASSERT(KScheduler::IsSchedulerLockedByCurrentThread(m_kernel)); + void KThread::RequestDummyThreadWait(KernelCore& kernel) { + ASSERT(KScheduler::IsSchedulerLockedByCurrentThread(kernel)); ASSERT(this->IsDummyThread()); // We will block when the scheduler lock is released. @@ -1335,8 +1320,8 @@ namespace Kernel { m_dummy_thread_runnable = false; } - void KThread::DummyThreadBeginWait() { - if (!this->IsDummyThread() || m_kernel.IsPhantomModeForSingleCore()) { + void KThread::DummyThreadBeginWait(KernelCore& kernel) { + if (!this->IsDummyThread() || kernel.IsPhantomModeForSingleCore()) { // Occurs in single core mode. return; } @@ -1346,8 +1331,8 @@ namespace Kernel { m_dummy_thread_cv.wait(lock, [this] { return m_dummy_thread_runnable; }); } - void KThread::DummyThreadEndWait() { - ASSERT(KScheduler::IsSchedulerLockedByCurrentThread(m_kernel)); + void KThread::DummyThreadEndWait(KernelCore& kernel) { + ASSERT(KScheduler::IsSchedulerLockedByCurrentThread(kernel)); ASSERT(this->IsDummyThread()); // Wake up the waiting thread. @@ -1358,28 +1343,26 @@ namespace Kernel { m_dummy_thread_cv.notify_one(); } - void KThread::BeginWait(KThreadQueue* queue) { + void KThread::BeginWait(KernelCore& kernel, KThreadQueue* queue) { // Set our state as waiting. - this->SetState(ThreadState::Waiting); + this->SetState(kernel, ThreadState::Waiting); // Set our wait queue. m_wait_queue = queue; } - void KThread::NotifyAvailable(KSynchronizationObject* signaled_object, Result wait_result) { + void KThread::NotifyAvailable(KernelCore& kernel, KSynchronizationObject* signaled_object, Result wait_result) { // Lock the scheduler. - KScopedSchedulerLock sl(m_kernel); - + KScopedSchedulerLock sl(kernel); // If we're waiting, notify our queue that we're available. if (this->GetState() == ThreadState::Waiting) { - m_wait_queue->NotifyAvailable(this, signaled_object, wait_result); + m_wait_queue->NotifyAvailable(kernel, this, signaled_object, wait_result); } } - void KThread::EndWait(Result wait_result) { + void KThread::EndWait(KernelCore& kernel, Result wait_result) { // Lock the scheduler. - KScopedSchedulerLock sl(m_kernel); - + KScopedSchedulerLock sl(kernel); // If we're waiting, notify our queue that we're available. if (this->GetState() == ThreadState::Waiting) { if (m_wait_queue == nullptr) { @@ -1388,32 +1371,29 @@ namespace Kernel { return; } - m_wait_queue->EndWait(this, wait_result); + m_wait_queue->EndWait(kernel, this, wait_result); } } - void KThread::CancelWait(Result wait_result, bool cancel_timer_task) { + void KThread::CancelWait(KernelCore& kernel, Result wait_result, bool cancel_timer_task) { // Lock the scheduler. - KScopedSchedulerLock sl(m_kernel); - + KScopedSchedulerLock sl(kernel); // If we're waiting, notify our queue that we're available. if (this->GetState() == ThreadState::Waiting) { - m_wait_queue->CancelWait(this, wait_result, cancel_timer_task); + m_wait_queue->CancelWait(kernel, this, wait_result, cancel_timer_task); } } - void KThread::SetState(ThreadState state) { - KScopedSchedulerLock sl{m_kernel}; - + void KThread::SetState(KernelCore& kernel, ThreadState state) { + KScopedSchedulerLock sl{kernel}; // Clear debugging state this->SetWaitReasonForDebugging({}); - const ThreadState old_state = m_thread_state.load(std::memory_order_relaxed); m_thread_state.store( static_cast<ThreadState>((old_state & ~ThreadState::Mask) | (state & ThreadState::Mask)), std::memory_order_relaxed); if (m_thread_state.load(std::memory_order_relaxed) != old_state) { - KScheduler::OnThreadStateChanged(m_kernel, this, old_state); + KScheduler::OnThreadStateChanged(kernel, this, old_state); } } @@ -1459,12 +1439,12 @@ namespace Kernel { auto* scheduler = m_kernel.CurrentScheduler(); if (scheduler && !m_kernel.IsPhantomModeForSingleCore()) { - scheduler->RescheduleCurrentCore(); + scheduler->RescheduleCurrentCore(m_kernel); } else { KScheduler::RescheduleCurrentHLEThread(m_kernel); } } else { - GetCurrentThread(m_kernel).EnableDispatch(); + GetCurrentThread(m_kernel).EnableDispatch(m_kernel); } } }
\ No newline at end of file |
