mirror of
https://git.suyu.dev/suyu/suyu
synced 2024-12-24 10:23:01 -06:00
hle: kernel: HandleTable: Remove deprecated APIs.
This commit is contained in:
parent
b57c5a9b54
commit
aa2844bcf9
7 changed files with 28 additions and 111 deletions
|
@ -47,50 +47,6 @@ ResultCode HandleTable::SetSize(s32 handle_table_size) {
|
||||||
return RESULT_SUCCESS;
|
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) {
|
ResultCode HandleTable::Add(Handle* out_handle, KAutoObject* obj, u16 type) {
|
||||||
ASSERT(obj != nullptr);
|
ASSERT(obj != nullptr);
|
||||||
|
|
||||||
|
@ -110,7 +66,7 @@ ResultCode HandleTable::Add(Handle* out_handle, KAutoObject* obj, u16 type) {
|
||||||
}
|
}
|
||||||
|
|
||||||
generations[slot] = generation;
|
generations[slot] = generation;
|
||||||
objects_new[slot] = obj;
|
objects[slot] = obj;
|
||||||
obj->Open();
|
obj->Open();
|
||||||
|
|
||||||
*out_handle = generation | (slot << 15);
|
*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) {
|
ResultVal<Handle> HandleTable::Duplicate(Handle handle) {
|
||||||
auto object = GetGeneric(handle);
|
auto object = GetObject(handle);
|
||||||
if (object == nullptr) {
|
if (object.IsNull()) {
|
||||||
LOG_ERROR(Kernel, "Tried to duplicate invalid handle: {:08X}", handle);
|
LOG_ERROR(Kernel, "Tried to duplicate invalid handle: {:08X}", handle);
|
||||||
return ResultInvalidHandle;
|
return ResultInvalidHandle;
|
||||||
}
|
}
|
||||||
return Create(object);
|
|
||||||
|
Handle out_handle{};
|
||||||
|
R_TRY(Add(&out_handle, object.GetPointerUnsafe()));
|
||||||
|
|
||||||
|
return MakeResult(out_handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool HandleTable::Remove(Handle handle) {
|
bool HandleTable::Remove(Handle handle) {
|
||||||
|
@ -139,12 +99,7 @@ bool HandleTable::Remove(Handle handle) {
|
||||||
objects[slot]->Close();
|
objects[slot]->Close();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (objects_new[slot]) {
|
|
||||||
objects_new[slot]->Close();
|
|
||||||
}
|
|
||||||
|
|
||||||
objects[slot] = nullptr;
|
objects[slot] = nullptr;
|
||||||
objects_new[slot] = nullptr;
|
|
||||||
|
|
||||||
generations[slot] = next_free_slot;
|
generations[slot] = next_free_slot;
|
||||||
next_free_slot = slot;
|
next_free_slot = slot;
|
||||||
|
@ -155,28 +110,14 @@ bool HandleTable::Remove(Handle handle) {
|
||||||
bool HandleTable::IsValid(Handle handle) const {
|
bool HandleTable::IsValid(Handle handle) const {
|
||||||
const std::size_t slot = GetSlot(handle);
|
const std::size_t slot = GetSlot(handle);
|
||||||
const u16 generation = GetGeneration(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;
|
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() {
|
void HandleTable::Clear() {
|
||||||
for (u16 i = 0; i < table_size; ++i) {
|
for (u16 i = 0; i < table_size; ++i) {
|
||||||
generations[i] = static_cast<u16>(i + 1);
|
generations[i] = static_cast<u16>(i + 1);
|
||||||
objects[i] = nullptr;
|
objects[i] = nullptr;
|
||||||
objects_new[i] = nullptr;
|
|
||||||
}
|
}
|
||||||
next_free_slot = 0;
|
next_free_slot = 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -70,13 +70,6 @@ public:
|
||||||
*/
|
*/
|
||||||
ResultCode SetSize(s32 handle_table_size);
|
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.
|
* 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:
|
* @return The duplicated Handle or one of the following errors:
|
||||||
|
@ -95,29 +88,13 @@ public:
|
||||||
/// Checks if a handle is valid and points to an existing object.
|
/// Checks if a handle is valid and points to an existing object.
|
||||||
bool IsValid(Handle handle) const;
|
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>
|
template <typename T = KAutoObject>
|
||||||
KAutoObject* GetObjectImpl(Handle handle) const {
|
KAutoObject* GetObjectImpl(Handle handle) const {
|
||||||
if (!IsValid(handle)) {
|
if (!IsValid(handle)) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto* obj = objects_new[static_cast<u16>(handle >> 15)];
|
auto* obj = objects[static_cast<u16>(handle >> 15)];
|
||||||
return obj->DynamicCast<T*>();
|
return obj->DynamicCast<T*>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -133,7 +110,7 @@ public:
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto* obj = objects_new[static_cast<u16>(handle >> 15)];
|
auto* obj = objects[static_cast<u16>(handle >> 15)];
|
||||||
return obj->DynamicCast<T*>();
|
return obj->DynamicCast<T*>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -142,7 +119,7 @@ public:
|
||||||
if (!IsValid(handle)) {
|
if (!IsValid(handle)) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
auto* obj = objects_new[static_cast<u16>(handle >> 15)];
|
auto* obj = objects[static_cast<u16>(handle >> 15)];
|
||||||
return obj->DynamicCast<T*>();
|
return obj->DynamicCast<T*>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -203,8 +180,7 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/// Stores the Object referenced by the handle or null if the slot is empty.
|
/// 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{};
|
||||||
std::array<KAutoObject*, MAX_COUNT> objects_new{};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The value of `next_generation` when the handle was created, used to check for validity. For
|
* The value of `next_generation` when the handle was created, used to check for validity. For
|
||||||
|
|
|
@ -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) {
|
for (u32 handle = 0; handle < handle_descriptor_header->num_handles_to_copy; ++handle) {
|
||||||
const u32 copy_handle{rp.Pop<Handle>()};
|
const u32 copy_handle{rp.Pop<Handle>()};
|
||||||
copy_handles.push_back(copy_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) {
|
for (u32 handle = 0; handle < handle_descriptor_header->num_handles_to_move; ++handle) {
|
||||||
const u32 move_handle{rp.Pop<Handle>()};
|
const u32 move_handle{rp.Pop<Handle>()};
|
||||||
move_handles.push_back(move_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 {
|
} else {
|
||||||
// For responses we just ignore the handles, they're empty and will be populated when
|
// 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 specific values in each of these descriptors.
|
||||||
for (auto& object : copy_objects) {
|
for (auto& object : copy_objects) {
|
||||||
ASSERT(object != nullptr);
|
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) {
|
for (auto& object : move_objects) {
|
||||||
ASSERT(object != nullptr);
|
ASSERT(object != nullptr);
|
||||||
dst_cmdbuf[current_offset++] = handle_table.Create(object).Unwrap();
|
R_TRY(handle_table.Add(&dst_cmdbuf[current_offset++], object));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
#include "common/concepts.h"
|
#include "common/concepts.h"
|
||||||
#include "common/swap.h"
|
#include "common/swap.h"
|
||||||
#include "core/hle/ipc.h"
|
#include "core/hle/ipc.h"
|
||||||
#include "core/hle/kernel/object.h"
|
#include "core/hle/kernel/k_auto_object.h"
|
||||||
|
|
||||||
union ResultCode;
|
union ResultCode;
|
||||||
|
|
||||||
|
@ -228,11 +228,11 @@ public:
|
||||||
return DynamicObjectCast<T>(move_objects.at(index));
|
return DynamicObjectCast<T>(move_objects.at(index));
|
||||||
}
|
}
|
||||||
|
|
||||||
void AddMoveObject(Object* object) {
|
void AddMoveObject(KAutoObject* object) {
|
||||||
move_objects.emplace_back(object);
|
move_objects.emplace_back(object);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AddCopyObject(Object* object) {
|
void AddCopyObject(KAutoObject* object) {
|
||||||
copy_objects.emplace_back(object);
|
copy_objects.emplace_back(object);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -292,8 +292,8 @@ private:
|
||||||
// TODO(yuriks): Check common usage of this and optimize size accordingly
|
// 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> move_handles;
|
||||||
boost::container::small_vector<Handle, 8> copy_handles;
|
boost::container::small_vector<Handle, 8> copy_handles;
|
||||||
boost::container::small_vector<Object*, 8> move_objects;
|
boost::container::small_vector<KAutoObject*, 8> move_objects;
|
||||||
boost::container::small_vector<Object*, 8> copy_objects;
|
boost::container::small_vector<KAutoObject*, 8> copy_objects;
|
||||||
boost::container::small_vector<std::shared_ptr<SessionRequestHandler>, 8> domain_objects;
|
boost::container::small_vector<std::shared_ptr<SessionRequestHandler>, 8> domain_objects;
|
||||||
|
|
||||||
std::optional<IPC::CommandHeader> command_header;
|
std::optional<IPC::CommandHeader> command_header;
|
||||||
|
|
|
@ -328,7 +328,7 @@ static ResultCode ConnectToNamedPort(Core::System& system, Handle* out_handle,
|
||||||
|
|
||||||
// Return the client session
|
// Return the client session
|
||||||
auto& handle_table = kernel.CurrentProcess()->GetHandleTable();
|
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;
|
return RESULT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -118,7 +118,7 @@ WaitTreeMutexInfo::WaitTreeMutexInfo(VAddr mutex_address, const Kernel::HandleTa
|
||||||
: mutex_address(mutex_address) {
|
: mutex_address(mutex_address) {
|
||||||
mutex_value = Core::System::GetInstance().Memory().Read32(mutex_address);
|
mutex_value = Core::System::GetInstance().Memory().Read32(mutex_address);
|
||||||
owner_handle = static_cast<Kernel::Handle>(mutex_value & Kernel::Svc::HandleWaitMask);
|
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;
|
WaitTreeMutexInfo::~WaitTreeMutexInfo() = default;
|
||||||
|
|
|
@ -80,10 +80,10 @@ public:
|
||||||
std::vector<std::unique_ptr<WaitTreeItem>> GetChildren() const override;
|
std::vector<std::unique_ptr<WaitTreeItem>> GetChildren() const override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
VAddr mutex_address;
|
VAddr mutex_address{};
|
||||||
u32 mutex_value;
|
u32 mutex_value{};
|
||||||
Kernel::Handle owner_handle;
|
Kernel::Handle owner_handle{};
|
||||||
std::shared_ptr<Kernel::KThread> owner;
|
Kernel::KThread* owner{};
|
||||||
};
|
};
|
||||||
|
|
||||||
class WaitTreeCallstack : public WaitTreeExpandableItem {
|
class WaitTreeCallstack : public WaitTreeExpandableItem {
|
||||||
|
|
Loading…
Reference in a new issue