From 674122038ad01aae7eb4b6eff604f94fb8864bd4 Mon Sep 17 00:00:00 2001 From: bunnei Date: Sat, 17 Apr 2021 23:38:20 -0700 Subject: hle: kernel: svc: Migrate WaitSynchronization. --- src/core/hle/kernel/handle_table.h | 55 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) (limited to 'src/core/hle/kernel/handle_table.h') diff --git a/src/core/hle/kernel/handle_table.h b/src/core/hle/kernel/handle_table.h index d57188844..d6abdcd47 100644 --- a/src/core/hle/kernel/handle_table.h +++ b/src/core/hle/kernel/handle_table.h @@ -10,6 +10,7 @@ #include "common/common_types.h" #include "core/hle/kernel/k_auto_object.h" +#include "core/hle/kernel/k_spin_lock.h" #include "core/hle/kernel/kernel.h" #include "core/hle/kernel/object.h" #include "core/hle/result.h" @@ -110,6 +111,16 @@ public: return DynamicObjectCast(GetGeneric(handle)); } + template + KAutoObject* GetObjectImpl(Handle handle) const { + if (!IsValid(handle)) { + return nullptr; + } + + auto* obj = objects_new[static_cast(handle >> 15)]; + return obj->DynamicCast(); + } + template KScopedAutoObject GetObject(Handle handle) const { if (handle == CurrentThread) { @@ -148,6 +159,48 @@ public: ResultCode Add(Handle* out_handle, KAutoObject* obj, u16 type); + template + bool GetMultipleObjects(T** out, const Handle* handles, size_t num_handles) const { + // Try to convert and open all the handles. + size_t num_opened; + { + // Lock the table. + KScopedSpinLock lk(lock); + for (num_opened = 0; num_opened < num_handles; num_opened++) { + // Get the current handle. + const auto cur_handle = handles[num_opened]; + + // Get the object for the current handle. + KAutoObject* cur_object = this->GetObjectImpl(cur_handle); + if (cur_object == nullptr) { + break; + } + + // Cast the current object to the desired type. + T* cur_t = cur_object->DynamicCast(); + if (cur_t == nullptr) { + break; + } + + // Open a reference to the current object. + cur_t->Open(); + out[num_opened] = cur_t; + } + } + + // If we converted every object, succeed. + if (num_opened == num_handles) { + return true; + } + + // If we didn't convert entry object, close the ones we opened. + for (size_t i = 0; i < num_opened; i++) { + out[i]->Close(); + } + + return false; + } + private: /// Stores the Object referenced by the handle or null if the slot is empty. std::array, MAX_COUNT> objects; @@ -175,6 +228,8 @@ private: /// Head of the free slots linked list. u16 next_free_slot = 0; + mutable KSpinLock lock; + /// Underlying kernel instance that this handle table operates under. KernelCore& kernel; }; -- cgit v1.2.3