From 45f8343659202a713dc6b51204303b45f91fc39d Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Tue, 10 Mar 2020 04:54:53 -0700 Subject: [PATCH] kern: tweak KHandleTable impl --- .../mesosphere/kern_k_handle_table.hpp | 47 ++++++++++++++++++- 1 file changed, 45 insertions(+), 2 deletions(-) diff --git a/libraries/libmesosphere/include/mesosphere/kern_k_handle_table.hpp b/libraries/libmesosphere/include/mesosphere/kern_k_handle_table.hpp index 6f8ceeebc..281e8aa01 100644 --- a/libraries/libmesosphere/include/mesosphere/kern_k_handle_table.hpp +++ b/libraries/libmesosphere/include/mesosphere/kern_k_handle_table.hpp @@ -278,7 +278,7 @@ namespace ams::kern { return entry; } - constexpr NOINLINE KAutoObject *GetObjectImpl(ams::svc::Handle handle) const { + constexpr ALWAYS_INLINE KAutoObject *GetObjectImpl(ams::svc::Handle handle) const { MESOSPHERE_ASSERT_THIS(); /* Handles must not have reserved bits set. */ @@ -293,7 +293,7 @@ namespace ams::kern { } } - constexpr NOINLINE KAutoObject *GetObjectByIndexImpl(ams::svc::Handle *out_handle, size_t index) const { + constexpr ALWAYS_INLINE KAutoObject *GetObjectByIndexImpl(ams::svc::Handle *out_handle, size_t index) const { MESOSPHERE_ASSERT_THIS(); /* Index must be in bounds. */ @@ -310,6 +310,49 @@ namespace ams::kern { *out_handle = EncodeHandle(index, entry->GetLinearId()); return entry->GetObject(); } + + template + ALWAYS_INLINE bool GetMultipleObjects(T **out, const ams::svc::Handle *handles, size_t num_handles) const { + /* Try to convert and open all the handles. */ + size_t num_opened; + { + /* Lock the table. */ + KScopedDisableDispatch dd; + KScopedSpinLock lk(this->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 (AMS_UNLIKELY(cur_object == nullptr)) { + break; + } + + /* Cast the current object to the desired type. */ + T *cur_t = cur_object->DynamicCast(); + if (AMS_UNLIKELY(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 (AMS_LIKELY(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; + } }; }