diff options
author | bunnei <bunneidev@gmail.com> | 2021-04-21 07:18:56 +0200 |
---|---|---|
committer | bunnei <bunneidev@gmail.com> | 2021-05-06 01:40:52 +0200 |
commit | aa2844bcf9b2b9bca2ce263270b963ffd13b05e7 (patch) | |
tree | 63af3d8c8b09f5fb834f764dd6a557ac0900f664 /src/core/hle | |
parent | hle: kernel: Migrate KResourceLimit to KAutoObject. (diff) | |
download | yuzu-aa2844bcf9b2b9bca2ce263270b963ffd13b05e7.tar yuzu-aa2844bcf9b2b9bca2ce263270b963ffd13b05e7.tar.gz yuzu-aa2844bcf9b2b9bca2ce263270b963ffd13b05e7.tar.bz2 yuzu-aa2844bcf9b2b9bca2ce263270b963ffd13b05e7.tar.lz yuzu-aa2844bcf9b2b9bca2ce263270b963ffd13b05e7.tar.xz yuzu-aa2844bcf9b2b9bca2ce263270b963ffd13b05e7.tar.zst yuzu-aa2844bcf9b2b9bca2ce263270b963ffd13b05e7.zip |
Diffstat (limited to 'src/core/hle')
-rw-r--r-- | src/core/hle/kernel/handle_table.cpp | 77 | ||||
-rw-r--r-- | src/core/hle/kernel/handle_table.h | 32 | ||||
-rw-r--r-- | src/core/hle/kernel/hle_ipc.cpp | 8 | ||||
-rw-r--r-- | src/core/hle/kernel/hle_ipc.h | 10 | ||||
-rw-r--r-- | src/core/hle/kernel/svc.cpp | 2 |
5 files changed, 23 insertions, 106 deletions
diff --git a/src/core/hle/kernel/handle_table.cpp b/src/core/hle/kernel/handle_table.cpp index 9291f0a76..cd752da4e 100644 --- a/src/core/hle/kernel/handle_table.cpp +++ b/src/core/hle/kernel/handle_table.cpp @@ -47,50 +47,6 @@ ResultCode HandleTable::SetSize(s32 handle_table_size) { return RESULT_SUCCESS; } -ResultVal<Handle> HandleTable::Create(Object* obj) { - DEBUG_ASSERT(obj != nullptr); - - switch (obj->GetHandleType()) { - case HandleType::SharedMemory: - case HandleType::Thread: - case HandleType::Event: - case HandleType::Process: - case HandleType::ReadableEvent: - case HandleType::WritableEvent: - case HandleType::ClientSession: - case HandleType::ServerSession: - case HandleType::Session: - case HandleType::TransferMemory: { - Handle handle{}; - Add(&handle, reinterpret_cast<KAutoObject*>(obj), {}); - return MakeResult<Handle>(handle); - } - default: - break; - } - - const u16 slot = next_free_slot; - if (slot >= table_size) { - LOG_ERROR(Kernel, "Unable to allocate Handle, too many slots in use."); - return ResultOutOfHandles; - } - next_free_slot = generations[slot]; - - const u16 generation = next_generation++; - - // Overflow count so it fits in the 15 bits dedicated to the generation in the handle. - // Horizon OS uses zero to represent an invalid handle, so skip to 1. - if (next_generation >= (1 << 15)) { - next_generation = 1; - } - - generations[slot] = generation; - objects[slot] = std::move(SharedFrom(obj)); - - Handle handle = generation | (slot << 15); - return MakeResult<Handle>(handle); -} - ResultCode HandleTable::Add(Handle* out_handle, KAutoObject* obj, u16 type) { ASSERT(obj != nullptr); @@ -110,7 +66,7 @@ ResultCode HandleTable::Add(Handle* out_handle, KAutoObject* obj, u16 type) { } generations[slot] = generation; - objects_new[slot] = obj; + objects[slot] = obj; obj->Open(); *out_handle = generation | (slot << 15); @@ -119,12 +75,16 @@ ResultCode HandleTable::Add(Handle* out_handle, KAutoObject* obj, u16 type) { } ResultVal<Handle> HandleTable::Duplicate(Handle handle) { - auto object = GetGeneric(handle); - if (object == nullptr) { + auto object = GetObject(handle); + if (object.IsNull()) { LOG_ERROR(Kernel, "Tried to duplicate invalid handle: {:08X}", handle); return ResultInvalidHandle; } - return Create(object); + + Handle out_handle{}; + R_TRY(Add(&out_handle, object.GetPointerUnsafe())); + + return MakeResult(out_handle); } bool HandleTable::Remove(Handle handle) { @@ -139,12 +99,7 @@ bool HandleTable::Remove(Handle handle) { objects[slot]->Close(); } - if (objects_new[slot]) { - objects_new[slot]->Close(); - } - objects[slot] = nullptr; - objects_new[slot] = nullptr; generations[slot] = next_free_slot; next_free_slot = slot; @@ -155,28 +110,14 @@ bool HandleTable::Remove(Handle handle) { bool HandleTable::IsValid(Handle handle) const { const std::size_t slot = GetSlot(handle); const u16 generation = GetGeneration(handle); - const bool is_object_valid = (objects[slot] != nullptr) || (objects_new[slot] != nullptr); + const bool is_object_valid = (objects[slot] != nullptr); return slot < table_size && is_object_valid && generations[slot] == generation; } -Object* HandleTable::GetGeneric(Handle handle) const { - if (handle == CurrentThread) { - return (kernel.CurrentScheduler()->GetCurrentThread()); - } else if (handle == CurrentProcess) { - return (kernel.CurrentProcess()); - } - - if (!IsValid(handle)) { - return nullptr; - } - return objects[GetSlot(handle)].get(); -} - void HandleTable::Clear() { for (u16 i = 0; i < table_size; ++i) { generations[i] = static_cast<u16>(i + 1); objects[i] = nullptr; - objects_new[i] = nullptr; } next_free_slot = 0; } diff --git a/src/core/hle/kernel/handle_table.h b/src/core/hle/kernel/handle_table.h index d6abdcd47..2e0b2d8b8 100644 --- a/src/core/hle/kernel/handle_table.h +++ b/src/core/hle/kernel/handle_table.h @@ -71,13 +71,6 @@ public: ResultCode SetSize(s32 handle_table_size); /** - * Allocates a handle for the given object. - * @return The created Handle or one of the following errors: - * - `ERR_HANDLE_TABLE_FULL`: the maximum number of handles has been exceeded. - */ - ResultVal<Handle> Create(Object* obj); - - /** * Returns a new handle that points to the same object as the passed in handle. * @return The duplicated Handle or one of the following errors: * - `ERR_INVALID_HANDLE`: an invalid handle was passed in. @@ -95,29 +88,13 @@ public: /// Checks if a handle is valid and points to an existing object. bool IsValid(Handle handle) const; - /** - * Looks up a handle. - * @return Pointer to the looked-up object, or `nullptr` if the handle is not valid. - */ - Object* GetGeneric(Handle handle) const; - - /** - * Looks up a handle while verifying its type. - * @return Pointer to the looked-up object, or `nullptr` if the handle is not valid or its - * type differs from the requested one. - */ - template <class T> - T* Get(Handle handle) const { - return DynamicObjectCast<T>(GetGeneric(handle)); - } - template <typename T = KAutoObject> KAutoObject* GetObjectImpl(Handle handle) const { if (!IsValid(handle)) { return nullptr; } - auto* obj = objects_new[static_cast<u16>(handle >> 15)]; + auto* obj = objects[static_cast<u16>(handle >> 15)]; return obj->DynamicCast<T*>(); } @@ -133,7 +110,7 @@ public: return nullptr; } - auto* obj = objects_new[static_cast<u16>(handle >> 15)]; + auto* obj = objects[static_cast<u16>(handle >> 15)]; return obj->DynamicCast<T*>(); } @@ -142,7 +119,7 @@ public: if (!IsValid(handle)) { return nullptr; } - auto* obj = objects_new[static_cast<u16>(handle >> 15)]; + auto* obj = objects[static_cast<u16>(handle >> 15)]; return obj->DynamicCast<T*>(); } @@ -203,8 +180,7 @@ public: private: /// Stores the Object referenced by the handle or null if the slot is empty. - std::array<std::shared_ptr<Object>, MAX_COUNT> objects; - std::array<KAutoObject*, MAX_COUNT> objects_new{}; + std::array<KAutoObject*, MAX_COUNT> objects{}; /** * The value of `next_generation` when the handle was created, used to check for validity. For diff --git a/src/core/hle/kernel/hle_ipc.cpp b/src/core/hle/kernel/hle_ipc.cpp index d647d9dd3..9e1e63204 100644 --- a/src/core/hle/kernel/hle_ipc.cpp +++ b/src/core/hle/kernel/hle_ipc.cpp @@ -74,12 +74,12 @@ void HLERequestContext::ParseCommandBuffer(const HandleTable& handle_table, u32_ for (u32 handle = 0; handle < handle_descriptor_header->num_handles_to_copy; ++handle) { const u32 copy_handle{rp.Pop<Handle>()}; copy_handles.push_back(copy_handle); - copy_objects.push_back(handle_table.GetGeneric(copy_handle)); + copy_objects.push_back(handle_table.GetObject(copy_handle).GetPointerUnsafe()); } for (u32 handle = 0; handle < handle_descriptor_header->num_handles_to_move; ++handle) { const u32 move_handle{rp.Pop<Handle>()}; move_handles.push_back(move_handle); - move_objects.push_back(handle_table.GetGeneric(move_handle)); + move_objects.push_back(handle_table.GetObject(move_handle).GetPointerUnsafe()); } } else { // For responses we just ignore the handles, they're empty and will be populated when @@ -220,12 +220,12 @@ ResultCode HLERequestContext::WriteToOutgoingCommandBuffer(KThread& thread) { // for specific values in each of these descriptors. for (auto& object : copy_objects) { ASSERT(object != nullptr); - dst_cmdbuf[current_offset++] = handle_table.Create(object).Unwrap(); + R_TRY(handle_table.Add(&dst_cmdbuf[current_offset++], object)); } for (auto& object : move_objects) { ASSERT(object != nullptr); - dst_cmdbuf[current_offset++] = handle_table.Create(object).Unwrap(); + R_TRY(handle_table.Add(&dst_cmdbuf[current_offset++], object)); } } diff --git a/src/core/hle/kernel/hle_ipc.h b/src/core/hle/kernel/hle_ipc.h index dc5c3b47d..b7484c445 100644 --- a/src/core/hle/kernel/hle_ipc.h +++ b/src/core/hle/kernel/hle_ipc.h @@ -16,7 +16,7 @@ #include "common/concepts.h" #include "common/swap.h" #include "core/hle/ipc.h" -#include "core/hle/kernel/object.h" +#include "core/hle/kernel/k_auto_object.h" union ResultCode; @@ -228,11 +228,11 @@ public: return DynamicObjectCast<T>(move_objects.at(index)); } - void AddMoveObject(Object* object) { + void AddMoveObject(KAutoObject* object) { move_objects.emplace_back(object); } - void AddCopyObject(Object* object) { + void AddCopyObject(KAutoObject* object) { copy_objects.emplace_back(object); } @@ -292,8 +292,8 @@ private: // TODO(yuriks): Check common usage of this and optimize size accordingly boost::container::small_vector<Handle, 8> move_handles; boost::container::small_vector<Handle, 8> copy_handles; - boost::container::small_vector<Object*, 8> move_objects; - boost::container::small_vector<Object*, 8> copy_objects; + boost::container::small_vector<KAutoObject*, 8> move_objects; + boost::container::small_vector<KAutoObject*, 8> copy_objects; boost::container::small_vector<std::shared_ptr<SessionRequestHandler>, 8> domain_objects; std::optional<IPC::CommandHeader> command_header; diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp index a78bfd1da..fa85bd631 100644 --- a/src/core/hle/kernel/svc.cpp +++ b/src/core/hle/kernel/svc.cpp @@ -328,7 +328,7 @@ static ResultCode ConnectToNamedPort(Core::System& system, Handle* out_handle, // Return the client session auto& handle_table = kernel.CurrentProcess()->GetHandleTable(); - CASCADE_RESULT(*out_handle, handle_table.Create(client_session)); + handle_table.Add(out_handle, client_session); return RESULT_SUCCESS; } |