From 891babbe2081231e842749001364815f7c1f5731 Mon Sep 17 00:00:00 2001 From: Fernando Sahmkow Date: Fri, 29 Mar 2019 17:13:00 -0400 Subject: Add PrepareReschedule where required. --- src/core/hle/kernel/wait_object.cpp | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src/core/hle/kernel/wait_object.cpp') diff --git a/src/core/hle/kernel/wait_object.cpp b/src/core/hle/kernel/wait_object.cpp index 0e96ba8723..e035a67e99 100644 --- a/src/core/hle/kernel/wait_object.cpp +++ b/src/core/hle/kernel/wait_object.cpp @@ -6,6 +6,8 @@ #include "common/assert.h" #include "common/common_types.h" #include "common/logging/log.h" +#include "core/core.h" +#include "core/core_cpu.h" #include "core/hle/kernel/object.h" #include "core/hle/kernel/process.h" #include "core/hle/kernel/thread.h" @@ -95,6 +97,8 @@ void WaitObject::WakeupWaitingThread(SharedPtr thread) { } if (resume) { thread->ResumeFromWait(); + if (thread->GetProcessorID() >= 0) + Core::System::GetInstance().CpuCore(thread->GetProcessorID()).PrepareReschedule(); } } -- cgit v1.2.3 From 87334f0f169942212515f0740477010c9ad3a999 Mon Sep 17 00:00:00 2001 From: Fernando Sahmkow Date: Tue, 2 Apr 2019 09:22:53 -0400 Subject: Correct PrepareReschedule --- src/core/core.cpp | 5 ++++ src/core/core.h | 3 ++ src/core/core_cpu.h | 2 +- src/core/hle/kernel/address_arbiter.cpp | 5 ++-- src/core/hle/kernel/svc.cpp | 49 ++++++++++++--------------------- src/core/hle/kernel/wait_object.cpp | 3 +- 6 files changed, 29 insertions(+), 38 deletions(-) (limited to 'src/core/hle/kernel/wait_object.cpp') diff --git a/src/core/core.cpp b/src/core/core.cpp index 5565840fd9..4a95630bd0 100644 --- a/src/core/core.cpp +++ b/src/core/core.cpp @@ -404,6 +404,11 @@ void System::PrepareReschedule() { CurrentCpuCore().PrepareReschedule(); } +void System::PrepareReschedule(s32 core_index) { + if (core_index >= 0) + CpuCore(core_index).PrepareReschedule(); +} + PerfStatsResults System::GetAndResetPerfStats() { return impl->GetAndResetPerfStats(); } diff --git a/src/core/core.h b/src/core/core.h index 2a002f6d77..0d1008895d 100644 --- a/src/core/core.h +++ b/src/core/core.h @@ -185,6 +185,9 @@ public: /// Prepare the core emulation for a reschedule void PrepareReschedule(); + /// Prepare the core emulation for a reschedule + void PrepareReschedule(s32 core_index); + /// Gets and resets core performance statistics PerfStatsResults GetAndResetPerfStats(); diff --git a/src/core/core_cpu.h b/src/core/core_cpu.h index 5dde2994ce..0cde547878 100644 --- a/src/core/core_cpu.h +++ b/src/core/core_cpu.h @@ -14,7 +14,7 @@ namespace Kernel { class Scheduler; class GlobalScheduler; -} +} // namespace Kernel namespace Core { class System; diff --git a/src/core/hle/kernel/address_arbiter.cpp b/src/core/hle/kernel/address_arbiter.cpp index 77f7bb451a..c66cd16ef3 100644 --- a/src/core/hle/kernel/address_arbiter.cpp +++ b/src/core/hle/kernel/address_arbiter.cpp @@ -37,8 +37,7 @@ void WakeThreads(const std::vector>& waiting_threads, s32 num_ waiting_threads[i]->SetWaitSynchronizationResult(RESULT_SUCCESS); waiting_threads[i]->SetArbiterWaitAddress(0); waiting_threads[i]->ResumeFromWait(); - if (waiting_threads[i]->GetProcessorID() >= 0) - system.CpuCore(waiting_threads[i]->GetProcessorID()).PrepareReschedule(); + system.PrepareReschedule(waiting_threads[i]->GetProcessorID()); } } } // Anonymous namespace @@ -173,7 +172,7 @@ ResultCode AddressArbiter::WaitForAddressImpl(VAddr address, s64 timeout) { current_thread->WakeAfterDelay(timeout); - system.CpuCore(current_thread->GetProcessorID()).PrepareReschedule(); + system.PrepareReschedule(current_thread->GetProcessorID()); return RESULT_TIMEOUT; } diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp index ee1e9f006a..560ac39455 100644 --- a/src/core/hle/kernel/svc.cpp +++ b/src/core/hle/kernel/svc.cpp @@ -516,7 +516,7 @@ static ResultCode WaitSynchronization(Core::System& system, Handle* index, VAddr thread->WakeAfterDelay(nano_seconds); thread->SetWakeupCallback(DefaultThreadWakeupCallback); - system.CpuCore(thread->GetProcessorID()).PrepareReschedule(); + system.PrepareReschedule(thread->GetProcessorID()); return RESULT_TIMEOUT; } @@ -534,8 +534,7 @@ static ResultCode CancelSynchronization(Core::System& system, Handle thread_hand } thread->CancelWait(); - if (thread->GetProcessorID() >= 0) - Core::System::GetInstance().CpuCore(thread->GetProcessorID()).PrepareReschedule(); + system.PrepareReschedule(thread->GetProcessorID()); return RESULT_SUCCESS; } @@ -1069,8 +1068,7 @@ static ResultCode SetThreadActivity(Core::System& system, Handle handle, u32 act thread->SetActivity(static_cast(activity)); - if (thread->GetProcessorID() >= 0) - Core::System::GetInstance().CpuCore(thread->GetProcessorID()).PrepareReschedule(); + system.PrepareReschedule(thread->GetProcessorID()); return RESULT_SUCCESS; } @@ -1152,8 +1150,7 @@ static ResultCode SetThreadPriority(Core::System& system, Handle handle, u32 pri thread->SetPriority(priority); - if (thread->GetProcessorID() >= 0) - Core::System::GetInstance().CpuCore(thread->GetProcessorID()).PrepareReschedule(); + system.PrepareReschedule(thread->GetProcessorID()); return RESULT_SUCCESS; } @@ -1509,8 +1506,7 @@ static ResultCode CreateThread(Core::System& system, Handle* out_handle, VAddr e thread->SetName( fmt::format("thread[entry_point={:X}, handle={:X}]", entry_point, *new_thread_handle)); - if (thread->GetProcessorID() >= 0) - Core::System::GetInstance().CpuCore(thread->GetProcessorID()).PrepareReschedule(); + system.PrepareReschedule(thread->GetProcessorID()); return RESULT_SUCCESS; } @@ -1532,10 +1528,7 @@ static ResultCode StartThread(Core::System& system, Handle thread_handle) { thread->ResumeFromWait(); if (thread->GetStatus() == ThreadStatus::Ready) { - if (thread->GetProcessorID() >= 0) - Core::System::GetInstance().CpuCore(thread->GetProcessorID()).PrepareReschedule(); - else - Core::System::GetInstance().GlobalScheduler().SetReselectionPending(); + system.PrepareReschedule(thread->GetProcessorID()); } return RESULT_SUCCESS; @@ -1582,10 +1575,7 @@ static void SleepThread(Core::System& system, s64 nanoseconds) { current_thread->Sleep(nanoseconds); } - // Reschedule all CPU cores - for (std::size_t i = 0; i < Core::NUM_CPU_CORES; ++i) { - system.CpuCore(i).PrepareReschedule(); - } + system.PrepareReschedule(current_thread->GetProcessorID()); } /// Wait process wide key atomic @@ -1632,7 +1622,7 @@ static ResultCode WaitProcessWideKeyAtomic(Core::System& system, VAddr mutex_add // Note: Deliberately don't attempt to inherit the lock owner's priority. - system.CpuCore(current_thread->GetProcessorID()).PrepareReschedule(); + system.PrepareReschedule(current_thread->GetProcessorID()); return RESULT_SUCCESS; } @@ -1644,7 +1634,7 @@ static ResultCode SignalProcessWideKey(Core::System& system, VAddr condition_var // Retrieve a list of all threads that are waiting for this condition variable. std::vector> waiting_threads; - const auto& scheduler = Core::System::GetInstance().GlobalScheduler(); + const auto& scheduler = system.GlobalScheduler(); const auto& thread_list = scheduler.GetThreadList(); for (const auto& thread : thread_list) { @@ -1706,8 +1696,7 @@ static ResultCode SignalProcessWideKey(Core::System& system, VAddr condition_var thread->SetLockOwner(nullptr); thread->SetMutexWaitAddress(0); thread->SetWaitHandle(0); - if (thread->GetProcessorID() >= 0) - Core::System::GetInstance().CpuCore(thread->GetProcessorID()).PrepareReschedule(); + system.PrepareReschedule(thread->GetProcessorID()); } else { // Atomically signal that the mutex now has a waiting thread. do { @@ -1731,8 +1720,7 @@ static ResultCode SignalProcessWideKey(Core::System& system, VAddr condition_var thread->SetStatus(ThreadStatus::WaitMutex); owner->AddMutexWaiter(thread); - if (thread->GetProcessorID() >= 0) - Core::System::GetInstance().CpuCore(thread->GetProcessorID()).PrepareReschedule(); + system.PrepareReschedule(thread->GetProcessorID()); } } @@ -1758,13 +1746,10 @@ static ResultCode WaitForAddress(Core::System& system, VAddr address, u32 type, } const auto arbitration_type = static_cast(type); - auto& address_arbiter = - system.Kernel().CurrentProcess()->GetAddressArbiter(); + auto& address_arbiter = system.Kernel().CurrentProcess()->GetAddressArbiter(); ResultCode result = address_arbiter.WaitForAddress(address, arbitration_type, value, timeout); if (result == RESULT_SUCCESS) - Core::System::GetInstance() - .CpuCore(GetCurrentThread()->GetProcessorID()) - .PrepareReschedule(); + system.PrepareReschedule(); return result; } @@ -2051,10 +2036,10 @@ static ResultCode SetThreadCoreMask(Core::System& system, Handle thread_handle, return ERR_INVALID_HANDLE; } - Core::System::GetInstance().CpuCore(thread->GetProcessorID()).PrepareReschedule(); + system.PrepareReschedule(thread->GetProcessorID()); thread->ChangeCore(core, affinity_mask); - if (thread->GetProcessorID() >= 0) - Core::System::GetInstance().CpuCore(thread->GetProcessorID()).PrepareReschedule(); + system.PrepareReschedule(thread->GetProcessorID()); + return RESULT_SUCCESS; } @@ -2165,7 +2150,7 @@ static ResultCode SignalEvent(Core::System& system, Handle handle) { } writable_event->Signal(); - Core::System::GetInstance().PrepareReschedule(); + system.PrepareReschedule(); return RESULT_SUCCESS; } diff --git a/src/core/hle/kernel/wait_object.cpp b/src/core/hle/kernel/wait_object.cpp index e035a67e99..a65ec7dbc3 100644 --- a/src/core/hle/kernel/wait_object.cpp +++ b/src/core/hle/kernel/wait_object.cpp @@ -97,8 +97,7 @@ void WaitObject::WakeupWaitingThread(SharedPtr thread) { } if (resume) { thread->ResumeFromWait(); - if (thread->GetProcessorID() >= 0) - Core::System::GetInstance().CpuCore(thread->GetProcessorID()).PrepareReschedule(); + Core::System::GetInstance().PrepareReschedule(thread->GetProcessorID()); } } -- cgit v1.2.3 From abc8856e2c55f5ebc89bc10f4bf7c85581438363 Mon Sep 17 00:00:00 2001 From: Fernando Sahmkow Date: Wed, 11 Sep 2019 12:47:37 -0400 Subject: Kernel: Remove global system accessor from WaitObject --- src/core/hle/kernel/kernel.cpp | 8 ++++++++ src/core/hle/kernel/kernel.h | 6 ++++++ src/core/hle/kernel/scheduler.cpp | 2 +- src/core/hle/kernel/wait_object.cpp | 3 ++- 4 files changed, 17 insertions(+), 2 deletions(-) (limited to 'src/core/hle/kernel/wait_object.cpp') diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp index 7a913520dc..77edbcd1f1 100644 --- a/src/core/hle/kernel/kernel.cpp +++ b/src/core/hle/kernel/kernel.cpp @@ -229,6 +229,14 @@ const Kernel::GlobalScheduler& KernelCore::GlobalScheduler() const { return impl->global_scheduler; } +Core::System& KernelCore::System() { + return impl->system; +} + +const Core::System& KernelCore::System() const { + return impl->system; +} + void KernelCore::AddNamedPort(std::string name, SharedPtr port) { impl->named_ports.emplace(std::move(name), std::move(port)); } diff --git a/src/core/hle/kernel/kernel.h b/src/core/hle/kernel/kernel.h index f9f5bdc88f..0fc4d1f363 100644 --- a/src/core/hle/kernel/kernel.h +++ b/src/core/hle/kernel/kernel.h @@ -82,6 +82,12 @@ public: /// Gets the sole instance of the global scheduler const Kernel::GlobalScheduler& GlobalScheduler() const; + /// Gets the sole instance of the system + Core::System& System(); + + /// Gets the sole instance of the system + const Core::System& System() const; + /// Adds a port to the named port table void AddNamedPort(std::string name, SharedPtr port); diff --git a/src/core/hle/kernel/scheduler.cpp b/src/core/hle/kernel/scheduler.cpp index 5581c43bf8..60d936c9ac 100644 --- a/src/core/hle/kernel/scheduler.cpp +++ b/src/core/hle/kernel/scheduler.cpp @@ -287,7 +287,7 @@ void GlobalScheduler::PreemptThreads() { if (current_thread != nullptr && current_thread->GetPriority() > priority) { for (auto& thread : suggested_queue[core_id]) { const s32 source_core = thread->GetProcessorID(); - if (thread->GetPriority() > priority) { + if (thread->GetPriority() < priority) { continue; } if (source_core >= 0) { diff --git a/src/core/hle/kernel/wait_object.cpp b/src/core/hle/kernel/wait_object.cpp index a65ec7dbc3..50ed2a2f15 100644 --- a/src/core/hle/kernel/wait_object.cpp +++ b/src/core/hle/kernel/wait_object.cpp @@ -8,6 +8,7 @@ #include "common/logging/log.h" #include "core/core.h" #include "core/core_cpu.h" +#include "core/hle/kernel/kernel.h" #include "core/hle/kernel/object.h" #include "core/hle/kernel/process.h" #include "core/hle/kernel/thread.h" @@ -97,7 +98,7 @@ void WaitObject::WakeupWaitingThread(SharedPtr thread) { } if (resume) { thread->ResumeFromWait(); - Core::System::GetInstance().PrepareReschedule(thread->GetProcessorID()); + kernel.System().PrepareReschedule(thread->GetProcessorID()); } } -- cgit v1.2.3 From 3da21e4b4f8bb03f3ccfda697104179b09695214 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 + src/core/hle/kernel/thread.h | 3 +++ src/core/hle/kernel/wait_object.cpp | 3 --- 3 files changed, 4 insertions(+), 3 deletions(-) (limited to 'src/core/hle/kernel/wait_object.cpp') diff --git a/src/core/hle/kernel/thread.cpp b/src/core/hle/kernel/thread.cpp index ae62609e38..563a99bfc7 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(); } diff --git a/src/core/hle/kernel/thread.h b/src/core/hle/kernel/thread.h index 4d220c4f98..ceb4d51591 100644 --- a/src/core/hle/kernel/thread.h +++ b/src/core/hle/kernel/thread.h @@ -319,6 +319,9 @@ public: } void ClearWaitObjects() { + for (const auto& waiting_object : wait_objects) { + waiting_object->RemoveWaitingThread(this); + } wait_objects.clear(); } diff --git a/src/core/hle/kernel/wait_object.cpp b/src/core/hle/kernel/wait_object.cpp index 50ed2a2f15..0f833fb3ac 100644 --- a/src/core/hle/kernel/wait_object.cpp +++ b/src/core/hle/kernel/wait_object.cpp @@ -85,9 +85,6 @@ void WaitObject::WakeupWaitingThread(SharedPtr thread) { const std::size_t index = thread->GetWaitObjectIndex(this); - for (const auto& object : thread->GetWaitObjects()) { - object->RemoveWaitingThread(thread.get()); - } thread->ClearWaitObjects(); thread->CancelWakeupTimer(); -- cgit v1.2.3 From ac9dd91f1ec3a1607f0413308623f903f31d477c 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/kernel.cpp | 8 -------- src/core/hle/kernel/kernel.h | 6 ------ src/core/hle/kernel/thread.cpp | 16 ++++++++-------- src/core/hle/kernel/wait_object.cpp | 2 +- 4 files changed, 9 insertions(+), 23 deletions(-) (limited to 'src/core/hle/kernel/wait_object.cpp') diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp index 0d6286f845..f94ac150d0 100644 --- a/src/core/hle/kernel/kernel.cpp +++ b/src/core/hle/kernel/kernel.cpp @@ -232,14 +232,6 @@ const Kernel::GlobalScheduler& KernelCore::GlobalScheduler() const { return impl->global_scheduler; } -Core::System& KernelCore::System() { - return impl->system; -} - -const Core::System& KernelCore::System() const { - return impl->system; -} - void KernelCore::AddNamedPort(std::string name, SharedPtr port) { impl->named_ports.emplace(std::move(name), std::move(port)); } diff --git a/src/core/hle/kernel/kernel.h b/src/core/hle/kernel/kernel.h index 9fb8f52ec9..c4397fc77a 100644 --- a/src/core/hle/kernel/kernel.h +++ b/src/core/hle/kernel/kernel.h @@ -82,12 +82,6 @@ public: /// Gets the sole instance of the global scheduler const Kernel::GlobalScheduler& GlobalScheduler() const; - /// Gets the sole instance of the system - Core::System& System(); - - /// Gets the sole instance of the system - const Core::System& System() const; - /// Adds a port to the named port table void AddNamedPort(std::string name, SharedPtr port); diff --git a/src/core/hle/kernel/thread.cpp b/src/core/hle/kernel/thread.cpp index 8663fe5eed..0c11da1e0e 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; diff --git a/src/core/hle/kernel/wait_object.cpp b/src/core/hle/kernel/wait_object.cpp index 0f833fb3ac..c00cef0629 100644 --- a/src/core/hle/kernel/wait_object.cpp +++ b/src/core/hle/kernel/wait_object.cpp @@ -95,7 +95,7 @@ void WaitObject::WakeupWaitingThread(SharedPtr thread) { } if (resume) { thread->ResumeFromWait(); - kernel.System().PrepareReschedule(thread->GetProcessorID()); + Core::System::GetInstance().PrepareReschedule(thread->GetProcessorID()); } } -- cgit v1.2.3