From 669a2d2c67bd9a3267286bc0c2e6e3c1dc98c154 Mon Sep 17 00:00:00 2001 From: bunnei Date: Fri, 6 Aug 2021 22:45:18 -0700 Subject: core: hle: kernel: Reflect non-emulated threads as core 3. --- src/core/hle/kernel/k_address_arbiter.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/core/hle/kernel/k_address_arbiter.cpp') diff --git a/src/core/hle/kernel/k_address_arbiter.cpp b/src/core/hle/kernel/k_address_arbiter.cpp index 1b429bc1e..6771ef621 100644 --- a/src/core/hle/kernel/k_address_arbiter.cpp +++ b/src/core/hle/kernel/k_address_arbiter.cpp @@ -28,7 +28,7 @@ bool ReadFromUser(Core::System& system, s32* out, VAddr address) { bool DecrementIfLessThan(Core::System& system, s32* out, VAddr address, s32 value) { auto& monitor = system.Monitor(); - const auto current_core = system.CurrentCoreIndex(); + const auto current_core = system.Kernel().CurrentPhysicalCoreIndex(); // TODO(bunnei): We should disable interrupts here via KScopedInterruptDisable. // TODO(bunnei): We should call CanAccessAtomic(..) here. @@ -58,7 +58,7 @@ bool DecrementIfLessThan(Core::System& system, s32* out, VAddr address, s32 valu bool UpdateIfEqual(Core::System& system, s32* out, VAddr address, s32 value, s32 new_value) { auto& monitor = system.Monitor(); - const auto current_core = system.CurrentCoreIndex(); + const auto current_core = system.Kernel().CurrentPhysicalCoreIndex(); // TODO(bunnei): We should disable interrupts here via KScopedInterruptDisable. // TODO(bunnei): We should call CanAccessAtomic(..) here. -- cgit v1.2.3 From 2f894560413db9bf8efc1febc26904937a28380f Mon Sep 17 00:00:00 2001 From: bunnei Date: Tue, 9 Nov 2021 19:21:20 -0800 Subject: hle: kernel: KThread: Remove tracking of sync object from threads. --- src/core/hle/kernel/k_address_arbiter.cpp | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) (limited to 'src/core/hle/kernel/k_address_arbiter.cpp') diff --git a/src/core/hle/kernel/k_address_arbiter.cpp b/src/core/hle/kernel/k_address_arbiter.cpp index 6771ef621..c5c81a880 100644 --- a/src/core/hle/kernel/k_address_arbiter.cpp +++ b/src/core/hle/kernel/k_address_arbiter.cpp @@ -97,7 +97,7 @@ ResultCode KAddressArbiter::Signal(VAddr addr, s32 count) { while ((it != thread_tree.end()) && (count <= 0 || num_waiters < count) && (it->GetAddressArbiterKey() == addr)) { KThread* target_thread = std::addressof(*it); - target_thread->SetSyncedObject(nullptr, ResultSuccess); + target_thread->SetWaitResult(ResultSuccess); ASSERT(target_thread->IsWaitingForAddressArbiter()); target_thread->Wakeup(); @@ -130,7 +130,7 @@ ResultCode KAddressArbiter::SignalAndIncrementIfEqual(VAddr addr, s32 value, s32 while ((it != thread_tree.end()) && (count <= 0 || num_waiters < count) && (it->GetAddressArbiterKey() == addr)) { KThread* target_thread = std::addressof(*it); - target_thread->SetSyncedObject(nullptr, ResultSuccess); + target_thread->SetWaitResult(ResultSuccess); ASSERT(target_thread->IsWaitingForAddressArbiter()); target_thread->Wakeup(); @@ -198,7 +198,7 @@ ResultCode KAddressArbiter::SignalAndModifyByWaitingCountIfEqual(VAddr addr, s32 while ((it != thread_tree.end()) && (count <= 0 || num_waiters < count) && (it->GetAddressArbiterKey() == addr)) { KThread* target_thread = std::addressof(*it); - target_thread->SetSyncedObject(nullptr, ResultSuccess); + target_thread->SetWaitResult(ResultSuccess); ASSERT(target_thread->IsWaitingForAddressArbiter()); target_thread->Wakeup(); @@ -225,7 +225,7 @@ ResultCode KAddressArbiter::WaitIfLessThan(VAddr addr, s32 value, bool decrement } // Set the synced object. - cur_thread->SetSyncedObject(nullptr, ResultTimedOut); + cur_thread->SetWaitResult(ResultTimedOut); // Read the value from userspace. s32 user_value{}; @@ -274,8 +274,7 @@ ResultCode KAddressArbiter::WaitIfLessThan(VAddr addr, s32 value, bool decrement } // Get the result. - KSynchronizationObject* dummy{}; - return cur_thread->GetWaitResult(&dummy); + return cur_thread->GetWaitResult(); } ResultCode KAddressArbiter::WaitIfEqual(VAddr addr, s32 value, s64 timeout) { @@ -292,7 +291,7 @@ ResultCode KAddressArbiter::WaitIfEqual(VAddr addr, s32 value, s64 timeout) { } // Set the synced object. - cur_thread->SetSyncedObject(nullptr, ResultTimedOut); + cur_thread->SetWaitResult(ResultTimedOut); // Read the value from userspace. s32 user_value{}; @@ -334,8 +333,7 @@ ResultCode KAddressArbiter::WaitIfEqual(VAddr addr, s32 value, s64 timeout) { } // Get the result. - KSynchronizationObject* dummy{}; - return cur_thread->GetWaitResult(&dummy); + return cur_thread->GetWaitResult(); } } // namespace Kernel -- cgit v1.2.3 From 15c721b90977865d964e26537f8a8f8740134164 Mon Sep 17 00:00:00 2001 From: bunnei Date: Tue, 9 Nov 2021 19:23:37 -0800 Subject: hle: kernel: KAddressArbiter: Migrate to updated KThreadQueue. --- src/core/hle/kernel/k_address_arbiter.cpp | 82 +++++++++++++++---------------- 1 file changed, 39 insertions(+), 43 deletions(-) (limited to 'src/core/hle/kernel/k_address_arbiter.cpp') diff --git a/src/core/hle/kernel/k_address_arbiter.cpp b/src/core/hle/kernel/k_address_arbiter.cpp index c5c81a880..165475fbf 100644 --- a/src/core/hle/kernel/k_address_arbiter.cpp +++ b/src/core/hle/kernel/k_address_arbiter.cpp @@ -8,6 +8,7 @@ #include "core/hle/kernel/k_scheduler.h" #include "core/hle/kernel/k_scoped_scheduler_lock_and_sleep.h" #include "core/hle/kernel/k_thread.h" +#include "core/hle/kernel/k_thread_queue.h" #include "core/hle/kernel/kernel.h" #include "core/hle/kernel/svc_results.h" #include "core/hle/kernel/time_manager.h" @@ -85,6 +86,27 @@ bool UpdateIfEqual(Core::System& system, s32* out, VAddr address, s32 value, s32 return true; } +class ThreadQueueImplForKAddressArbiter final : public KThreadQueue { +private: + KAddressArbiter::ThreadTree* m_tree; + +public: + explicit ThreadQueueImplForKAddressArbiter(KernelCore& kernel_, KAddressArbiter::ThreadTree* t) + : KThreadQueue(kernel_), m_tree(t) {} + + virtual void CancelWait(KThread* waiting_thread, ResultCode wait_result, + bool cancel_timer_task) override { + // If the thread is waiting on an address arbiter, remove it from the tree. + if (waiting_thread->IsWaitingForAddressArbiter()) { + m_tree->erase(m_tree->iterator_to(*waiting_thread)); + waiting_thread->ClearAddressArbiter(); + } + + // Invoke the base cancel wait handler. + KThreadQueue::CancelWait(waiting_thread, wait_result, cancel_timer_task); + } +}; + } // namespace ResultCode KAddressArbiter::Signal(VAddr addr, s32 count) { @@ -96,14 +118,14 @@ ResultCode KAddressArbiter::Signal(VAddr addr, s32 count) { auto it = thread_tree.nfind_light({addr, -1}); while ((it != thread_tree.end()) && (count <= 0 || num_waiters < count) && (it->GetAddressArbiterKey() == addr)) { + // End the thread's wait. KThread* target_thread = std::addressof(*it); - target_thread->SetWaitResult(ResultSuccess); + target_thread->EndWait(ResultSuccess); ASSERT(target_thread->IsWaitingForAddressArbiter()); - target_thread->Wakeup(); + target_thread->ClearAddressArbiter(); it = thread_tree.erase(it); - target_thread->ClearAddressArbiter(); ++num_waiters; } } @@ -129,14 +151,14 @@ ResultCode KAddressArbiter::SignalAndIncrementIfEqual(VAddr addr, s32 value, s32 auto it = thread_tree.nfind_light({addr, -1}); while ((it != thread_tree.end()) && (count <= 0 || num_waiters < count) && (it->GetAddressArbiterKey() == addr)) { + // End the thread's wait. KThread* target_thread = std::addressof(*it); - target_thread->SetWaitResult(ResultSuccess); + target_thread->EndWait(ResultSuccess); ASSERT(target_thread->IsWaitingForAddressArbiter()); - target_thread->Wakeup(); + target_thread->ClearAddressArbiter(); it = thread_tree.erase(it); - target_thread->ClearAddressArbiter(); ++num_waiters; } } @@ -197,14 +219,14 @@ ResultCode KAddressArbiter::SignalAndModifyByWaitingCountIfEqual(VAddr addr, s32 while ((it != thread_tree.end()) && (count <= 0 || num_waiters < count) && (it->GetAddressArbiterKey() == addr)) { + // End the thread's wait. KThread* target_thread = std::addressof(*it); - target_thread->SetWaitResult(ResultSuccess); + target_thread->EndWait(ResultSuccess); ASSERT(target_thread->IsWaitingForAddressArbiter()); - target_thread->Wakeup(); + target_thread->ClearAddressArbiter(); it = thread_tree.erase(it); - target_thread->ClearAddressArbiter(); ++num_waiters; } } @@ -214,6 +236,7 @@ ResultCode KAddressArbiter::SignalAndModifyByWaitingCountIfEqual(VAddr addr, s32 ResultCode KAddressArbiter::WaitIfLessThan(VAddr addr, s32 value, bool decrement, s64 timeout) { // Prepare to wait. KThread* cur_thread = kernel.CurrentScheduler()->GetCurrentThread(); + ThreadQueueImplForKAddressArbiter wait_queue(kernel, std::addressof(thread_tree)); { KScopedSchedulerLockAndSleep slp{kernel, cur_thread, timeout}; @@ -224,9 +247,6 @@ ResultCode KAddressArbiter::WaitIfLessThan(VAddr addr, s32 value, bool decrement return ResultTerminationRequested; } - // Set the synced object. - cur_thread->SetWaitResult(ResultTimedOut); - // Read the value from userspace. s32 user_value{}; bool succeeded{}; @@ -256,21 +276,10 @@ ResultCode KAddressArbiter::WaitIfLessThan(VAddr addr, s32 value, bool decrement // Set the arbiter. cur_thread->SetAddressArbiter(&thread_tree, addr); thread_tree.insert(*cur_thread); - cur_thread->SetState(ThreadState::Waiting); - cur_thread->SetWaitReasonForDebugging(ThreadWaitReasonForDebugging::Arbitration); - } - // Cancel the timer wait. - kernel.TimeManager().UnscheduleTimeEvent(cur_thread); - - // Remove from the address arbiter. - { - KScopedSchedulerLock sl(kernel); - - if (cur_thread->IsWaitingForAddressArbiter()) { - thread_tree.erase(thread_tree.iterator_to(*cur_thread)); - cur_thread->ClearAddressArbiter(); - } + // Wait for the thread to finish. + cur_thread->BeginWait(std::addressof(wait_queue)); + cur_thread->SetWaitReasonForDebugging(ThreadWaitReasonForDebugging::Arbitration); } // Get the result. @@ -280,6 +289,7 @@ ResultCode KAddressArbiter::WaitIfLessThan(VAddr addr, s32 value, bool decrement ResultCode KAddressArbiter::WaitIfEqual(VAddr addr, s32 value, s64 timeout) { // Prepare to wait. KThread* cur_thread = kernel.CurrentScheduler()->GetCurrentThread(); + ThreadQueueImplForKAddressArbiter wait_queue(kernel, std::addressof(thread_tree)); { KScopedSchedulerLockAndSleep slp{kernel, cur_thread, timeout}; @@ -290,9 +300,6 @@ ResultCode KAddressArbiter::WaitIfEqual(VAddr addr, s32 value, s64 timeout) { return ResultTerminationRequested; } - // Set the synced object. - cur_thread->SetWaitResult(ResultTimedOut); - // Read the value from userspace. s32 user_value{}; if (!ReadFromUser(system, &user_value, addr)) { @@ -315,21 +322,10 @@ ResultCode KAddressArbiter::WaitIfEqual(VAddr addr, s32 value, s64 timeout) { // Set the arbiter. cur_thread->SetAddressArbiter(&thread_tree, addr); thread_tree.insert(*cur_thread); - cur_thread->SetState(ThreadState::Waiting); - cur_thread->SetWaitReasonForDebugging(ThreadWaitReasonForDebugging::Arbitration); - } - - // Cancel the timer wait. - kernel.TimeManager().UnscheduleTimeEvent(cur_thread); - // Remove from the address arbiter. - { - KScopedSchedulerLock sl(kernel); - - if (cur_thread->IsWaitingForAddressArbiter()) { - thread_tree.erase(thread_tree.iterator_to(*cur_thread)); - cur_thread->ClearAddressArbiter(); - } + // Wait for the thread to finish. + cur_thread->BeginWait(std::addressof(wait_queue)); + cur_thread->SetWaitReasonForDebugging(ThreadWaitReasonForDebugging::Arbitration); } // Get the result. -- cgit v1.2.3 From 8f4ff06c4cf807ff68619eb69cc69dc20659d6d6 Mon Sep 17 00:00:00 2001 From: bunnei Date: Sun, 21 Nov 2021 02:29:53 -0800 Subject: hle: kernel: Cleanup to match coding style. --- src/core/hle/kernel/k_address_arbiter.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/core/hle/kernel/k_address_arbiter.cpp') diff --git a/src/core/hle/kernel/k_address_arbiter.cpp b/src/core/hle/kernel/k_address_arbiter.cpp index 165475fbf..a4ce99402 100644 --- a/src/core/hle/kernel/k_address_arbiter.cpp +++ b/src/core/hle/kernel/k_address_arbiter.cpp @@ -87,9 +87,6 @@ bool UpdateIfEqual(Core::System& system, s32* out, VAddr address, s32 value, s32 } class ThreadQueueImplForKAddressArbiter final : public KThreadQueue { -private: - KAddressArbiter::ThreadTree* m_tree; - public: explicit ThreadQueueImplForKAddressArbiter(KernelCore& kernel_, KAddressArbiter::ThreadTree* t) : KThreadQueue(kernel_), m_tree(t) {} @@ -105,6 +102,9 @@ public: // Invoke the base cancel wait handler. KThreadQueue::CancelWait(waiting_thread, wait_result, cancel_timer_task); } + +private: + KAddressArbiter::ThreadTree* m_tree; }; } // namespace -- cgit v1.2.3 From 0d1bdfc1d4f9cb9ceecdb2dd9c784a664f6ba0c8 Mon Sep 17 00:00:00 2001 From: bunnei Date: Sun, 5 Dec 2021 23:49:26 -0800 Subject: hle: kernel: Remove unnecessary virtual specifier on CancelWait. --- src/core/hle/kernel/k_address_arbiter.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/core/hle/kernel/k_address_arbiter.cpp') diff --git a/src/core/hle/kernel/k_address_arbiter.cpp b/src/core/hle/kernel/k_address_arbiter.cpp index a4ce99402..783c69858 100644 --- a/src/core/hle/kernel/k_address_arbiter.cpp +++ b/src/core/hle/kernel/k_address_arbiter.cpp @@ -91,8 +91,8 @@ public: explicit ThreadQueueImplForKAddressArbiter(KernelCore& kernel_, KAddressArbiter::ThreadTree* t) : KThreadQueue(kernel_), m_tree(t) {} - virtual void CancelWait(KThread* waiting_thread, ResultCode wait_result, - bool cancel_timer_task) override { + void CancelWait(KThread* waiting_thread, ResultCode wait_result, + bool cancel_timer_task) override { // If the thread is waiting on an address arbiter, remove it from the tree. if (waiting_thread->IsWaitingForAddressArbiter()) { m_tree->erase(m_tree->iterator_to(*waiting_thread)); -- cgit v1.2.3