summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorbunnei <bunneidev@gmail.com>2021-04-21 07:18:56 +0200
committerbunnei <bunneidev@gmail.com>2021-05-06 01:40:52 +0200
commitaa2844bcf9b2b9bca2ce263270b963ffd13b05e7 (patch)
tree63af3d8c8b09f5fb834f764dd6a557ac0900f664
parenthle: kernel: Migrate KResourceLimit to KAutoObject. (diff)
downloadyuzu-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
-rw-r--r--src/core/hle/kernel/handle_table.cpp77
-rw-r--r--src/core/hle/kernel/handle_table.h32
-rw-r--r--src/core/hle/kernel/hle_ipc.cpp8
-rw-r--r--src/core/hle/kernel/hle_ipc.h10
-rw-r--r--src/core/hle/kernel/svc.cpp2
-rw-r--r--src/yuzu/debugger/wait_tree.cpp2
-rw-r--r--src/yuzu/debugger/wait_tree.h8
7 files changed, 28 insertions, 111 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;
}
diff --git a/src/yuzu/debugger/wait_tree.cpp b/src/yuzu/debugger/wait_tree.cpp
index f4eeba2c5..317c42631 100644
--- a/src/yuzu/debugger/wait_tree.cpp
+++ b/src/yuzu/debugger/wait_tree.cpp
@@ -118,7 +118,7 @@ WaitTreeMutexInfo::WaitTreeMutexInfo(VAddr mutex_address, const Kernel::HandleTa
: mutex_address(mutex_address) {
mutex_value = Core::System::GetInstance().Memory().Read32(mutex_address);
owner_handle = static_cast<Kernel::Handle>(mutex_value & Kernel::Svc::HandleWaitMask);
- owner = SharedFrom(handle_table.Get<Kernel::KThread>(owner_handle));
+ owner = handle_table.GetObject<Kernel::KThread>(owner_handle).GetPointerUnsafe();
}
WaitTreeMutexInfo::~WaitTreeMutexInfo() = default;
diff --git a/src/yuzu/debugger/wait_tree.h b/src/yuzu/debugger/wait_tree.h
index 3da2fdfd2..bf8120a71 100644
--- a/src/yuzu/debugger/wait_tree.h
+++ b/src/yuzu/debugger/wait_tree.h
@@ -80,10 +80,10 @@ public:
std::vector<std::unique_ptr<WaitTreeItem>> GetChildren() const override;
private:
- VAddr mutex_address;
- u32 mutex_value;
- Kernel::Handle owner_handle;
- std::shared_ptr<Kernel::KThread> owner;
+ VAddr mutex_address{};
+ u32 mutex_value{};
+ Kernel::Handle owner_handle{};
+ Kernel::KThread* owner{};
};
class WaitTreeCallstack : public WaitTreeExpandableItem {