From a1ac0c6cb47e10863b0bfbb1a6aadc71ccc513ab Mon Sep 17 00:00:00 2001 From: Fernando Sahmkow Date: Fri, 29 Mar 2019 17:01:46 -0400 Subject: Addapt thread class to the new Scheduler --- src/core/hle/kernel/thread.cpp | 242 +++++++++++++++++++++++++++++++---------- 1 file changed, 183 insertions(+), 59 deletions(-) (limited to 'src/core/hle/kernel/thread.cpp') diff --git a/src/core/hle/kernel/thread.cpp b/src/core/hle/kernel/thread.cpp index ec529e7f2..d0fa7b370 100644 --- a/src/core/hle/kernel/thread.cpp +++ b/src/core/hle/kernel/thread.cpp @@ -45,15 +45,7 @@ void Thread::Stop() { callback_handle); kernel.ThreadWakeupCallbackHandleTable().Close(callback_handle); callback_handle = 0; - - // Clean up thread from ready queue - // This is only needed when the thread is terminated forcefully (SVC TerminateProcess) - if (status == ThreadStatus::Ready || status == ThreadStatus::Paused) { - scheduler->UnscheduleThread(this, current_priority); - } - - status = ThreadStatus::Dead; - + SetStatus(ThreadStatus::Dead); WakeupAllWaitingThreads(); // Clean up any dangling references in objects that this thread was waiting for @@ -132,13 +124,11 @@ void Thread::ResumeFromWait() { wakeup_callback = nullptr; if (activity == ThreadActivity::Paused) { - status = ThreadStatus::Paused; + SetStatus(ThreadStatus::Paused); return; } - status = ThreadStatus::Ready; - - ChangeScheduler(); + SetStatus(ThreadStatus::Ready); } void Thread::CancelWait() { @@ -205,9 +195,9 @@ ResultVal> Thread::Create(KernelCore& kernel, std::string name thread->name = std::move(name); thread->callback_handle = kernel.ThreadWakeupCallbackHandleTable().Create(thread).Unwrap(); thread->owner_process = &owner_process; + auto& scheduler = kernel.GlobalScheduler(); + scheduler.AddThread(thread); thread->tls_address = thread->owner_process->CreateTLSRegion(); - thread->scheduler = &system.Scheduler(processor_id); - thread->scheduler->AddThread(thread); thread->owner_process->RegisterThread(thread.get()); @@ -250,6 +240,22 @@ void Thread::SetStatus(ThreadStatus new_status) { return; } + switch (new_status) { + case ThreadStatus::Ready: + case ThreadStatus::Running: + SetSchedulingStatus(ThreadSchedStatus::Runnable); + break; + case ThreadStatus::Dormant: + SetSchedulingStatus(ThreadSchedStatus::None); + break; + case ThreadStatus::Dead: + SetSchedulingStatus(ThreadSchedStatus::Exited); + break; + default: + SetSchedulingStatus(ThreadSchedStatus::Paused); + break; + } + if (status == ThreadStatus::Running) { last_running_ticks = Core::System::GetInstance().CoreTiming().GetTicks(); } @@ -311,8 +317,7 @@ void Thread::UpdatePriority() { return; } - scheduler->SetThreadPriority(this, new_priority); - current_priority = new_priority; + SetCurrentPriority(new_priority); if (!lock_owner) { return; @@ -328,47 +333,7 @@ void Thread::UpdatePriority() { } void Thread::ChangeCore(u32 core, u64 mask) { - ideal_core = core; - affinity_mask = mask; - ChangeScheduler(); -} - -void Thread::ChangeScheduler() { - if (status != ThreadStatus::Ready) { - return; - } - - auto& system = Core::System::GetInstance(); - std::optional new_processor_id{GetNextProcessorId(affinity_mask)}; - - if (!new_processor_id) { - new_processor_id = processor_id; - } - if (ideal_core != -1 && system.Scheduler(ideal_core).GetCurrentThread() == nullptr) { - new_processor_id = ideal_core; - } - - ASSERT(*new_processor_id < 4); - - // Add thread to new core's scheduler - auto& next_scheduler = system.Scheduler(*new_processor_id); - - if (*new_processor_id != processor_id) { - // Remove thread from previous core's scheduler - scheduler->RemoveThread(this); - next_scheduler.AddThread(this); - } - - processor_id = *new_processor_id; - - // If the thread was ready, unschedule from the previous core and schedule on the new core - scheduler->UnscheduleThread(this, current_priority); - next_scheduler.ScheduleThread(this, current_priority); - - // Change thread's scheduler - scheduler = &next_scheduler; - - system.CpuCore(processor_id).PrepareReschedule(); + SetCoreAndAffinityMask(core, mask); } bool Thread::AllWaitObjectsReady() const { @@ -391,7 +356,7 @@ void Thread::SetActivity(ThreadActivity value) { if (status == ThreadStatus::Ready) { status = ThreadStatus::Paused; } else if (status == ThreadStatus::Running) { - status = ThreadStatus::Paused; + SetStatus(ThreadStatus::Paused); Core::System::GetInstance().CpuCore(processor_id).PrepareReschedule(); } } else if (status == ThreadStatus::Paused) { @@ -408,6 +373,165 @@ void Thread::Sleep(s64 nanoseconds) { WakeAfterDelay(nanoseconds); } +void Thread::YieldType0() { + auto& scheduler = kernel.GlobalScheduler(); + scheduler.YieldThread(this); +} + +void Thread::YieldType1() { + auto& scheduler = kernel.GlobalScheduler(); + scheduler.YieldThreadAndBalanceLoad(this); +} + +void Thread::YieldType2() { + auto& scheduler = kernel.GlobalScheduler(); + scheduler.YieldThreadAndWaitForLoadBalancing(this); +} + +void Thread::SetSchedulingStatus(ThreadSchedStatus new_status) { + u32 old_flags = scheduling_state; + scheduling_state = + (scheduling_state & ThreadSchedMasks::HighMask) | static_cast(new_status); + AdjustSchedulingOnStatus(old_flags); +} + +void Thread::SetCurrentPriority(u32 new_priority) { + u32 old_priority = current_priority; + current_priority = new_priority; + AdjustSchedulingOnPriority(old_priority); +} + +ResultCode Thread::SetCoreAndAffinityMask(s32 new_core, u64 new_affinity_mask) { + auto HighestSetCore = [](u64 mask, u32 max_cores) { + for (s32 core = max_cores - 1; core >= 0; core--) { + if (((mask >> core) & 1) != 0) + return core; + } + return -1; + }; + bool use_override = affinity_override_count != 0; + // The value -3 is "do not change the ideal core". + if (new_core == -3) { + new_core = use_override ? ideal_core_override : ideal_core; + if ((new_affinity_mask & (1 << new_core)) == 0) { + return ERR_INVALID_COMBINATION; + } + } + if (use_override) { + ideal_core_override = new_core; + affinity_mask_override = new_affinity_mask; + } else { + u64 old_affinity_mask = affinity_mask; + ideal_core = new_core; + affinity_mask = new_affinity_mask; + if (old_affinity_mask != new_affinity_mask) { + s32 old_core = processor_id; + if (processor_id >= 0 && ((affinity_mask >> processor_id) & 1) == 0) { + if (ideal_core < 0) { + processor_id = HighestSetCore(affinity_mask, GlobalScheduler::NUM_CPU_CORES); + } else { + processor_id = ideal_core; + } + } + AdjustSchedulingOnAffinity(old_affinity_mask, old_core); + } + } + return RESULT_SUCCESS; +} + +void Thread::AdjustSchedulingOnStatus(u32 old_flags) { + if (old_flags == scheduling_state) + return; + + auto& scheduler = kernel.GlobalScheduler(); + if (static_cast(old_flags & ThreadSchedMasks::LowMask) == + ThreadSchedStatus::Runnable) { + // In this case the thread was running, now it's pausing/exitting + if (processor_id >= 0) + scheduler.Unschedule(current_priority, processor_id, this); + + for (s32 core = 0; core < GlobalScheduler::NUM_CPU_CORES; core++) { + if (core != processor_id && ((affinity_mask >> core) & 1) != 0) + scheduler.Unsuggest(current_priority, core, this); + } + } else if (GetSchedulingStatus() == ThreadSchedStatus::Runnable) { + // The thread is now set to running from being stopped + if (processor_id >= 0) + scheduler.Schedule(current_priority, processor_id, this); + + for (s32 core = 0; core < GlobalScheduler::NUM_CPU_CORES; core++) { + if (core != processor_id && ((affinity_mask >> core) & 1) != 0) + scheduler.Suggest(current_priority, core, this); + } + } + + scheduler.SetReselectionPending(); +} + +void Thread::AdjustSchedulingOnPriority(u32 old_priority) { + if (GetSchedulingStatus() != ThreadSchedStatus::Runnable) { + return; + } + auto& scheduler = Core::System::GetInstance().GlobalScheduler(); + if (processor_id >= 0) { + scheduler.Unschedule(old_priority, processor_id, this); + } + + for (s32 core = 0; core < GlobalScheduler::NUM_CPU_CORES; core++) { + if (core != processor_id && ((affinity_mask >> core) & 1) != 0) { + scheduler.Unsuggest(old_priority, core, this); + } + } + + // Add thread to the new priority queues. + Thread* current_thread = GetCurrentThread(); + + if (processor_id >= 0) { + if (current_thread == this) { + scheduler.SchedulePrepend(current_priority, processor_id, this); + } else { + scheduler.Schedule(current_priority, processor_id, this); + } + } + + for (s32 core = 0; core < GlobalScheduler::NUM_CPU_CORES; core++) { + if (core != processor_id && ((affinity_mask >> core) & 1) != 0) { + scheduler.Suggest(current_priority, core, this); + } + } + + scheduler.SetReselectionPending(); +} + +void Thread::AdjustSchedulingOnAffinity(u64 old_affinity_mask, s32 old_core) { + auto& scheduler = Core::System::GetInstance().GlobalScheduler(); + if (GetSchedulingStatus() != ThreadSchedStatus::Runnable || + current_priority >= THREADPRIO_COUNT) + return; + + for (s32 core = 0; core < GlobalScheduler::NUM_CPU_CORES; core++) { + if (((old_affinity_mask >> core) & 1) != 0) { + if (core == old_core) { + scheduler.Unschedule(current_priority, core, this); + } else { + scheduler.Unsuggest(current_priority, core, this); + } + } + } + + for (s32 core = 0; core < GlobalScheduler::NUM_CPU_CORES; core++) { + if (((affinity_mask >> core) & 1) != 0) { + if (core == processor_id) { + scheduler.Schedule(current_priority, core, this); + } else { + scheduler.Suggest(current_priority, core, this); + } + } + } + + scheduler.SetReselectionPending(); +} + //////////////////////////////////////////////////////////////////////////////////////////////////// /** -- cgit v1.2.3 From 82218c925af8bcbaa05ae9f39af2d2393de7681f Mon Sep 17 00:00:00 2001 From: Fernando Sahmkow Date: Wed, 19 Jun 2019 09:11:18 -0400 Subject: Kernel: Style and Corrections --- src/core/hle/kernel/thread.cpp | 54 +++++++++++++++++++++++------------------- 1 file changed, 30 insertions(+), 24 deletions(-) (limited to 'src/core/hle/kernel/thread.cpp') diff --git a/src/core/hle/kernel/thread.cpp b/src/core/hle/kernel/thread.cpp index d0fa7b370..8cf0a7ec7 100644 --- a/src/core/hle/kernel/thread.cpp +++ b/src/core/hle/kernel/thread.cpp @@ -373,43 +373,44 @@ void Thread::Sleep(s64 nanoseconds) { WakeAfterDelay(nanoseconds); } -void Thread::YieldType0() { +void Thread::YieldSimple() { auto& scheduler = kernel.GlobalScheduler(); scheduler.YieldThread(this); } -void Thread::YieldType1() { +void Thread::YieldAndBalanceLoad() { auto& scheduler = kernel.GlobalScheduler(); scheduler.YieldThreadAndBalanceLoad(this); } -void Thread::YieldType2() { +void Thread::YieldAndWaitForLoadBalancing() { auto& scheduler = kernel.GlobalScheduler(); scheduler.YieldThreadAndWaitForLoadBalancing(this); } void Thread::SetSchedulingStatus(ThreadSchedStatus new_status) { - u32 old_flags = scheduling_state; + const u32 old_flags = scheduling_state; scheduling_state = (scheduling_state & ThreadSchedMasks::HighMask) | static_cast(new_status); AdjustSchedulingOnStatus(old_flags); } void Thread::SetCurrentPriority(u32 new_priority) { - u32 old_priority = current_priority; - current_priority = new_priority; + u32 old_priority = std::exchange(current_priority, new_priority); AdjustSchedulingOnPriority(old_priority); } ResultCode Thread::SetCoreAndAffinityMask(s32 new_core, u64 new_affinity_mask) { - auto HighestSetCore = [](u64 mask, u32 max_cores) { + const auto HighestSetCore = [](u64 mask, u32 max_cores) { for (s32 core = max_cores - 1; core >= 0; core--) { - if (((mask >> core) & 1) != 0) + if (((mask >> core) & 1) != 0) { return core; + } } return -1; }; - bool use_override = affinity_override_count != 0; + + const bool use_override = affinity_override_count != 0; // The value -3 is "do not change the ideal core". if (new_core == -3) { new_core = use_override ? ideal_core_override : ideal_core; @@ -421,11 +422,10 @@ ResultCode Thread::SetCoreAndAffinityMask(s32 new_core, u64 new_affinity_mask) { ideal_core_override = new_core; affinity_mask_override = new_affinity_mask; } else { - u64 old_affinity_mask = affinity_mask; + const u64 old_affinity_mask = std::exchange(affinity_mask, new_affinity_mask); ideal_core = new_core; - affinity_mask = new_affinity_mask; if (old_affinity_mask != new_affinity_mask) { - s32 old_core = processor_id; + const s32 old_core = processor_id; if (processor_id >= 0 && ((affinity_mask >> processor_id) & 1) == 0) { if (ideal_core < 0) { processor_id = HighestSetCore(affinity_mask, GlobalScheduler::NUM_CPU_CORES); @@ -440,28 +440,33 @@ ResultCode Thread::SetCoreAndAffinityMask(s32 new_core, u64 new_affinity_mask) { } void Thread::AdjustSchedulingOnStatus(u32 old_flags) { - if (old_flags == scheduling_state) + if (old_flags == scheduling_state) { return; + } auto& scheduler = kernel.GlobalScheduler(); if (static_cast(old_flags & ThreadSchedMasks::LowMask) == ThreadSchedStatus::Runnable) { // In this case the thread was running, now it's pausing/exitting - if (processor_id >= 0) + if (processor_id >= 0) { scheduler.Unschedule(current_priority, processor_id, this); + } - for (s32 core = 0; core < GlobalScheduler::NUM_CPU_CORES; core++) { - if (core != processor_id && ((affinity_mask >> core) & 1) != 0) + for (u32 core = 0; core < GlobalScheduler::NUM_CPU_CORES; core++) { + if (core != processor_id && ((affinity_mask >> core) & 1) != 0) { scheduler.Unsuggest(current_priority, core, this); + } } } else if (GetSchedulingStatus() == ThreadSchedStatus::Runnable) { // The thread is now set to running from being stopped - if (processor_id >= 0) + if (processor_id >= 0) { scheduler.Schedule(current_priority, processor_id, this); + } - for (s32 core = 0; core < GlobalScheduler::NUM_CPU_CORES; core++) { - if (core != processor_id && ((affinity_mask >> core) & 1) != 0) + for (u32 core = 0; core < GlobalScheduler::NUM_CPU_CORES; core++) { + if (core != processor_id && ((affinity_mask >> core) & 1) != 0) { scheduler.Suggest(current_priority, core, this); + } } } @@ -477,7 +482,7 @@ void Thread::AdjustSchedulingOnPriority(u32 old_priority) { scheduler.Unschedule(old_priority, processor_id, this); } - for (s32 core = 0; core < GlobalScheduler::NUM_CPU_CORES; core++) { + for (u32 core = 0; core < GlobalScheduler::NUM_CPU_CORES; core++) { if (core != processor_id && ((affinity_mask >> core) & 1) != 0) { scheduler.Unsuggest(old_priority, core, this); } @@ -494,7 +499,7 @@ void Thread::AdjustSchedulingOnPriority(u32 old_priority) { } } - for (s32 core = 0; core < GlobalScheduler::NUM_CPU_CORES; core++) { + for (u32 core = 0; core < GlobalScheduler::NUM_CPU_CORES; core++) { if (core != processor_id && ((affinity_mask >> core) & 1) != 0) { scheduler.Suggest(current_priority, core, this); } @@ -506,10 +511,11 @@ void Thread::AdjustSchedulingOnPriority(u32 old_priority) { void Thread::AdjustSchedulingOnAffinity(u64 old_affinity_mask, s32 old_core) { auto& scheduler = Core::System::GetInstance().GlobalScheduler(); if (GetSchedulingStatus() != ThreadSchedStatus::Runnable || - current_priority >= THREADPRIO_COUNT) + current_priority >= THREADPRIO_COUNT) { return; + } - for (s32 core = 0; core < GlobalScheduler::NUM_CPU_CORES; core++) { + for (u32 core = 0; core < GlobalScheduler::NUM_CPU_CORES; core++) { if (((old_affinity_mask >> core) & 1) != 0) { if (core == old_core) { scheduler.Unschedule(current_priority, core, this); @@ -519,7 +525,7 @@ void Thread::AdjustSchedulingOnAffinity(u64 old_affinity_mask, s32 old_core) { } } - for (s32 core = 0; core < GlobalScheduler::NUM_CPU_CORES; core++) { + for (u32 core = 0; core < GlobalScheduler::NUM_CPU_CORES; core++) { if (((affinity_mask >> core) & 1) != 0) { if (core == processor_id) { scheduler.Schedule(current_priority, core, this); -- cgit v1.2.3 From 103f3a2fe51a09caf3f478226b6957b23c6eff79 Mon Sep 17 00:00:00 2001 From: Fernando Sahmkow Date: Tue, 10 Sep 2019 10:23:43 -0400 Subject: Scheduler: Add protections for Yield bombing In case of redundant yields, the scheduler will now idle the core for it's timeslice, in order to avoid continuously yielding the same thing over and over. --- src/core/hle/kernel/thread.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'src/core/hle/kernel/thread.cpp') diff --git a/src/core/hle/kernel/thread.cpp b/src/core/hle/kernel/thread.cpp index 8cf0a7ec7..ae62609e3 100644 --- a/src/core/hle/kernel/thread.cpp +++ b/src/core/hle/kernel/thread.cpp @@ -373,19 +373,19 @@ void Thread::Sleep(s64 nanoseconds) { WakeAfterDelay(nanoseconds); } -void Thread::YieldSimple() { +bool Thread::YieldSimple() { auto& scheduler = kernel.GlobalScheduler(); - scheduler.YieldThread(this); + return scheduler.YieldThread(this); } -void Thread::YieldAndBalanceLoad() { +bool Thread::YieldAndBalanceLoad() { auto& scheduler = kernel.GlobalScheduler(); - scheduler.YieldThreadAndBalanceLoad(this); + return scheduler.YieldThreadAndBalanceLoad(this); } -void Thread::YieldAndWaitForLoadBalancing() { +bool Thread::YieldAndWaitForLoadBalancing() { auto& scheduler = kernel.GlobalScheduler(); - scheduler.YieldThreadAndWaitForLoadBalancing(this); + return scheduler.YieldThreadAndWaitForLoadBalancing(this); } void Thread::SetSchedulingStatus(ThreadSchedStatus new_status) { -- cgit v1.2.3 From 1c6a11ab142d18c3444629940f183b7c1865a5e2 Mon Sep 17 00:00:00 2001 From: Fernando Sahmkow Date: Thu, 10 Oct 2019 08:04:14 -0400 Subject: Kernel: Corrections to Wait Objects clearing in which a thread could still be signalled after a timeout or a cancel. --- src/core/hle/kernel/thread.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'src/core/hle/kernel/thread.cpp') diff --git a/src/core/hle/kernel/thread.cpp b/src/core/hle/kernel/thread.cpp index ae62609e3..563a99bfc 100644 --- a/src/core/hle/kernel/thread.cpp +++ b/src/core/hle/kernel/thread.cpp @@ -133,6 +133,7 @@ void Thread::ResumeFromWait() { void Thread::CancelWait() { ASSERT(GetStatus() == ThreadStatus::WaitSynch); + ClearWaitObjects(); SetWaitSynchronizationResult(ERR_SYNCHRONIZATION_CANCELED); ResumeFromWait(); } -- cgit v1.2.3 From 96b1b144afff4ae4dd2d33547b8a62c46c920a84 Mon Sep 17 00:00:00 2001 From: Fernando Sahmkow Date: Thu, 10 Oct 2019 08:50:41 -0400 Subject: Kernel: Correct Paused scheduling --- src/core/hle/kernel/thread.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'src/core/hle/kernel/thread.cpp') diff --git a/src/core/hle/kernel/thread.cpp b/src/core/hle/kernel/thread.cpp index 563a99bfc..0871a2f00 100644 --- a/src/core/hle/kernel/thread.cpp +++ b/src/core/hle/kernel/thread.cpp @@ -354,9 +354,7 @@ void Thread::SetActivity(ThreadActivity value) { if (value == ThreadActivity::Paused) { // Set status if not waiting - if (status == ThreadStatus::Ready) { - status = ThreadStatus::Paused; - } else if (status == ThreadStatus::Running) { + if (status == ThreadStatus::Ready || status == ThreadStatus::Running) { SetStatus(ThreadStatus::Paused); Core::System::GetInstance().CpuCore(processor_id).PrepareReschedule(); } -- cgit v1.2.3 From b3c1deba494d78158ea6764802880b249fe64416 Mon Sep 17 00:00:00 2001 From: Fernando Sahmkow Date: Sat, 12 Oct 2019 08:02:34 -0400 Subject: Kernel_Thread: Eliminate most global accessors. --- src/core/hle/kernel/thread.cpp | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) (limited to 'src/core/hle/kernel/thread.cpp') diff --git a/src/core/hle/kernel/thread.cpp b/src/core/hle/kernel/thread.cpp index 0871a2f00..7208bbb11 100644 --- a/src/core/hle/kernel/thread.cpp +++ b/src/core/hle/kernel/thread.cpp @@ -41,8 +41,8 @@ Thread::~Thread() = default; void Thread::Stop() { // Cancel any outstanding wakeup events for this thread - Core::System::GetInstance().CoreTiming().UnscheduleEvent(kernel.ThreadWakeupCallbackEventType(), - callback_handle); + kernel.System().CoreTiming().UnscheduleEvent(kernel.ThreadWakeupCallbackEventType(), + callback_handle); kernel.ThreadWakeupCallbackHandleTable().Close(callback_handle); callback_handle = 0; SetStatus(ThreadStatus::Dead); @@ -68,13 +68,13 @@ void Thread::WakeAfterDelay(s64 nanoseconds) { // This function might be called from any thread so we have to be cautious and use the // thread-safe version of ScheduleEvent. const s64 cycles = Core::Timing::nsToCycles(std::chrono::nanoseconds{nanoseconds}); - Core::System::GetInstance().CoreTiming().ScheduleEvent( - cycles, kernel.ThreadWakeupCallbackEventType(), callback_handle); + kernel.System().CoreTiming().ScheduleEvent(cycles, kernel.ThreadWakeupCallbackEventType(), + callback_handle); } void Thread::CancelWakeupTimer() { - Core::System::GetInstance().CoreTiming().UnscheduleEvent(kernel.ThreadWakeupCallbackEventType(), - callback_handle); + kernel.System().CoreTiming().UnscheduleEvent(kernel.ThreadWakeupCallbackEventType(), + callback_handle); } static std::optional GetNextProcessorId(u64 mask) { @@ -176,7 +176,7 @@ ResultVal> Thread::Create(KernelCore& kernel, std::string name return ResultCode(-1); } - auto& system = Core::System::GetInstance(); + auto& system = kernel.System(); SharedPtr thread(new Thread(kernel)); thread->thread_id = kernel.CreateNewThreadID(); @@ -258,7 +258,7 @@ void Thread::SetStatus(ThreadStatus new_status) { } if (status == ThreadStatus::Running) { - last_running_ticks = Core::System::GetInstance().CoreTiming().GetTicks(); + last_running_ticks = kernel.System().CoreTiming().GetTicks(); } status = new_status; @@ -356,7 +356,7 @@ void Thread::SetActivity(ThreadActivity value) { // Set status if not waiting if (status == ThreadStatus::Ready || status == ThreadStatus::Running) { SetStatus(ThreadStatus::Paused); - Core::System::GetInstance().CpuCore(processor_id).PrepareReschedule(); + kernel.System().CpuCore(processor_id).PrepareReschedule(); } } else if (status == ThreadStatus::Paused) { // Ready to reschedule @@ -476,7 +476,7 @@ void Thread::AdjustSchedulingOnPriority(u32 old_priority) { if (GetSchedulingStatus() != ThreadSchedStatus::Runnable) { return; } - auto& scheduler = Core::System::GetInstance().GlobalScheduler(); + auto& scheduler = kernel.System().GlobalScheduler(); if (processor_id >= 0) { scheduler.Unschedule(old_priority, processor_id, this); } @@ -508,7 +508,7 @@ void Thread::AdjustSchedulingOnPriority(u32 old_priority) { } void Thread::AdjustSchedulingOnAffinity(u64 old_affinity_mask, s32 old_core) { - auto& scheduler = Core::System::GetInstance().GlobalScheduler(); + auto& scheduler = kernel.System().GlobalScheduler(); if (GetSchedulingStatus() != ThreadSchedStatus::Runnable || current_priority >= THREADPRIO_COUNT) { return; -- cgit v1.2.3 From 3073615dbc214a53badc88da68eecbaaa73898de Mon Sep 17 00:00:00 2001 From: Fernando Sahmkow Date: Sat, 12 Oct 2019 10:13:25 -0400 Subject: Kernel: Address Feedback. --- src/core/hle/kernel/thread.cpp | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) (limited to 'src/core/hle/kernel/thread.cpp') diff --git a/src/core/hle/kernel/thread.cpp b/src/core/hle/kernel/thread.cpp index 7208bbb11..8663fe5ee 100644 --- a/src/core/hle/kernel/thread.cpp +++ b/src/core/hle/kernel/thread.cpp @@ -389,13 +389,13 @@ bool Thread::YieldAndWaitForLoadBalancing() { void Thread::SetSchedulingStatus(ThreadSchedStatus new_status) { const u32 old_flags = scheduling_state; - scheduling_state = - (scheduling_state & ThreadSchedMasks::HighMask) | static_cast(new_status); + scheduling_state = (scheduling_state & static_cast(ThreadSchedMasks::HighMask)) | + static_cast(new_status); AdjustSchedulingOnStatus(old_flags); } void Thread::SetCurrentPriority(u32 new_priority) { - u32 old_priority = std::exchange(current_priority, new_priority); + const u32 old_priority = std::exchange(current_priority, new_priority); AdjustSchedulingOnPriority(old_priority); } @@ -410,10 +410,9 @@ ResultCode Thread::SetCoreAndAffinityMask(s32 new_core, u64 new_affinity_mask) { }; const bool use_override = affinity_override_count != 0; - // The value -3 is "do not change the ideal core". - if (new_core == -3) { + if (new_core == static_cast(CoreFlags::DontChangeIdealCore)) { new_core = use_override ? ideal_core_override : ideal_core; - if ((new_affinity_mask & (1 << new_core)) == 0) { + if ((new_affinity_mask & (1ULL << new_core)) == 0) { return ERR_INVALID_COMBINATION; } } @@ -444,14 +443,14 @@ void Thread::AdjustSchedulingOnStatus(u32 old_flags) { } auto& scheduler = kernel.GlobalScheduler(); - if (static_cast(old_flags & ThreadSchedMasks::LowMask) == + if (static_cast(old_flags & static_cast(ThreadSchedMasks::LowMask)) == ThreadSchedStatus::Runnable) { // In this case the thread was running, now it's pausing/exitting if (processor_id >= 0) { scheduler.Unschedule(current_priority, processor_id, this); } - for (u32 core = 0; core < GlobalScheduler::NUM_CPU_CORES; core++) { + for (s32 core = 0; core < GlobalScheduler::NUM_CPU_CORES; core++) { if (core != processor_id && ((affinity_mask >> core) & 1) != 0) { scheduler.Unsuggest(current_priority, core, this); } @@ -462,7 +461,7 @@ void Thread::AdjustSchedulingOnStatus(u32 old_flags) { scheduler.Schedule(current_priority, processor_id, this); } - for (u32 core = 0; core < GlobalScheduler::NUM_CPU_CORES; core++) { + for (s32 core = 0; core < GlobalScheduler::NUM_CPU_CORES; core++) { if (core != processor_id && ((affinity_mask >> core) & 1) != 0) { scheduler.Suggest(current_priority, core, this); } -- cgit v1.2.3 From c32520ceb7cf2180fbbed11e9bd5f9df03409e1d Mon Sep 17 00:00:00 2001 From: Fernando Sahmkow Date: Sat, 12 Oct 2019 10:21:33 -0400 Subject: Kernel: Reverse global accessor removal. --- src/core/hle/kernel/thread.cpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'src/core/hle/kernel/thread.cpp') diff --git a/src/core/hle/kernel/thread.cpp b/src/core/hle/kernel/thread.cpp index 8663fe5ee..0c11da1e0 100644 --- a/src/core/hle/kernel/thread.cpp +++ b/src/core/hle/kernel/thread.cpp @@ -41,7 +41,7 @@ Thread::~Thread() = default; void Thread::Stop() { // Cancel any outstanding wakeup events for this thread - kernel.System().CoreTiming().UnscheduleEvent(kernel.ThreadWakeupCallbackEventType(), + Core::System::GetInstance().CoreTiming().UnscheduleEvent(kernel.ThreadWakeupCallbackEventType(), callback_handle); kernel.ThreadWakeupCallbackHandleTable().Close(callback_handle); callback_handle = 0; @@ -68,12 +68,12 @@ void Thread::WakeAfterDelay(s64 nanoseconds) { // This function might be called from any thread so we have to be cautious and use the // thread-safe version of ScheduleEvent. const s64 cycles = Core::Timing::nsToCycles(std::chrono::nanoseconds{nanoseconds}); - kernel.System().CoreTiming().ScheduleEvent(cycles, kernel.ThreadWakeupCallbackEventType(), + Core::System::GetInstance().CoreTiming().ScheduleEvent(cycles, kernel.ThreadWakeupCallbackEventType(), callback_handle); } void Thread::CancelWakeupTimer() { - kernel.System().CoreTiming().UnscheduleEvent(kernel.ThreadWakeupCallbackEventType(), + Core::System::GetInstance().CoreTiming().UnscheduleEvent(kernel.ThreadWakeupCallbackEventType(), callback_handle); } @@ -176,7 +176,7 @@ ResultVal> Thread::Create(KernelCore& kernel, std::string name return ResultCode(-1); } - auto& system = kernel.System(); + auto& system = Core::System::GetInstance(); SharedPtr thread(new Thread(kernel)); thread->thread_id = kernel.CreateNewThreadID(); @@ -258,7 +258,7 @@ void Thread::SetStatus(ThreadStatus new_status) { } if (status == ThreadStatus::Running) { - last_running_ticks = kernel.System().CoreTiming().GetTicks(); + last_running_ticks = Core::System::GetInstance().CoreTiming().GetTicks(); } status = new_status; @@ -356,7 +356,7 @@ void Thread::SetActivity(ThreadActivity value) { // Set status if not waiting if (status == ThreadStatus::Ready || status == ThreadStatus::Running) { SetStatus(ThreadStatus::Paused); - kernel.System().CpuCore(processor_id).PrepareReschedule(); + Core::System::GetInstance().CpuCore(processor_id).PrepareReschedule(); } } else if (status == ThreadStatus::Paused) { // Ready to reschedule @@ -475,7 +475,7 @@ void Thread::AdjustSchedulingOnPriority(u32 old_priority) { if (GetSchedulingStatus() != ThreadSchedStatus::Runnable) { return; } - auto& scheduler = kernel.System().GlobalScheduler(); + auto& scheduler = Core::System::GetInstance().GlobalScheduler(); if (processor_id >= 0) { scheduler.Unschedule(old_priority, processor_id, this); } @@ -507,7 +507,7 @@ void Thread::AdjustSchedulingOnPriority(u32 old_priority) { } void Thread::AdjustSchedulingOnAffinity(u64 old_affinity_mask, s32 old_core) { - auto& scheduler = kernel.System().GlobalScheduler(); + auto& scheduler = Core::System::GetInstance().GlobalScheduler(); if (GetSchedulingStatus() != ThreadSchedStatus::Runnable || current_priority >= THREADPRIO_COUNT) { return; -- cgit v1.2.3 From a3524879be351f3726a622217d5c2d928ae92b42 Mon Sep 17 00:00:00 2001 From: Fernando Sahmkow Date: Sat, 12 Oct 2019 10:28:44 -0400 Subject: Kernel: Clang Format --- src/core/hle/kernel/thread.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src/core/hle/kernel/thread.cpp') diff --git a/src/core/hle/kernel/thread.cpp b/src/core/hle/kernel/thread.cpp index 0c11da1e0..3408658e5 100644 --- a/src/core/hle/kernel/thread.cpp +++ b/src/core/hle/kernel/thread.cpp @@ -42,7 +42,7 @@ Thread::~Thread() = default; void Thread::Stop() { // Cancel any outstanding wakeup events for this thread Core::System::GetInstance().CoreTiming().UnscheduleEvent(kernel.ThreadWakeupCallbackEventType(), - callback_handle); + callback_handle); kernel.ThreadWakeupCallbackHandleTable().Close(callback_handle); callback_handle = 0; SetStatus(ThreadStatus::Dead); @@ -68,13 +68,13 @@ void Thread::WakeAfterDelay(s64 nanoseconds) { // This function might be called from any thread so we have to be cautious and use the // thread-safe version of ScheduleEvent. const s64 cycles = Core::Timing::nsToCycles(std::chrono::nanoseconds{nanoseconds}); - Core::System::GetInstance().CoreTiming().ScheduleEvent(cycles, kernel.ThreadWakeupCallbackEventType(), - callback_handle); + Core::System::GetInstance().CoreTiming().ScheduleEvent( + cycles, kernel.ThreadWakeupCallbackEventType(), callback_handle); } void Thread::CancelWakeupTimer() { Core::System::GetInstance().CoreTiming().UnscheduleEvent(kernel.ThreadWakeupCallbackEventType(), - callback_handle); + callback_handle); } static std::optional GetNextProcessorId(u64 mask) { -- cgit v1.2.3 From e28c7f521765a85e27259539f0873b15c18a98f8 Mon Sep 17 00:00:00 2001 From: Fernando Sahmkow Date: Sat, 12 Oct 2019 10:38:55 -0400 Subject: Kernel: Address Feedback 2 --- src/core/hle/kernel/thread.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/core/hle/kernel/thread.cpp') diff --git a/src/core/hle/kernel/thread.cpp b/src/core/hle/kernel/thread.cpp index 3408658e5..aeb20b24b 100644 --- a/src/core/hle/kernel/thread.cpp +++ b/src/core/hle/kernel/thread.cpp @@ -410,7 +410,7 @@ ResultCode Thread::SetCoreAndAffinityMask(s32 new_core, u64 new_affinity_mask) { }; const bool use_override = affinity_override_count != 0; - if (new_core == static_cast(CoreFlags::DontChangeIdealCore)) { + if (new_core == THREADDONTCHANGE_IDEAL) { new_core = use_override ? ideal_core_override : ideal_core; if ((new_affinity_mask & (1ULL << new_core)) == 0) { return ERR_INVALID_COMBINATION; @@ -452,7 +452,7 @@ void Thread::AdjustSchedulingOnStatus(u32 old_flags) { for (s32 core = 0; core < GlobalScheduler::NUM_CPU_CORES; core++) { if (core != processor_id && ((affinity_mask >> core) & 1) != 0) { - scheduler.Unsuggest(current_priority, core, this); + scheduler.Unsuggest(current_priority, static_cast(core), this); } } } else if (GetSchedulingStatus() == ThreadSchedStatus::Runnable) { @@ -463,7 +463,7 @@ void Thread::AdjustSchedulingOnStatus(u32 old_flags) { for (s32 core = 0; core < GlobalScheduler::NUM_CPU_CORES; core++) { if (core != processor_id && ((affinity_mask >> core) & 1) != 0) { - scheduler.Suggest(current_priority, core, this); + scheduler.Suggest(current_priority, static_cast(core), this); } } } -- cgit v1.2.3 From 64e652d8cbcc4cc67442879ab7e379d62b72703c Mon Sep 17 00:00:00 2001 From: Fernando Sahmkow Date: Sat, 12 Oct 2019 10:55:34 -0400 Subject: Kernel Thread: Cleanup THREADPROCESSORID_DONT_UPDATE. --- src/core/hle/kernel/thread.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/core/hle/kernel/thread.cpp') diff --git a/src/core/hle/kernel/thread.cpp b/src/core/hle/kernel/thread.cpp index aeb20b24b..962530d2d 100644 --- a/src/core/hle/kernel/thread.cpp +++ b/src/core/hle/kernel/thread.cpp @@ -410,7 +410,7 @@ ResultCode Thread::SetCoreAndAffinityMask(s32 new_core, u64 new_affinity_mask) { }; const bool use_override = affinity_override_count != 0; - if (new_core == THREADDONTCHANGE_IDEAL) { + if (new_core == THREADPROCESSORID_DONT_UPDATE) { new_core = use_override ? ideal_core_override : ideal_core; if ((new_affinity_mask & (1ULL << new_core)) == 0) { return ERR_INVALID_COMBINATION; -- cgit v1.2.3