fixup! hle: kernel: Migrate to KHandleTable.

This commit is contained in:
bunnei 2021-05-01 12:42:44 -07:00
parent 4356361faf
commit d23f9f75ff

View File

@ -29,58 +29,11 @@ class KHandleTable {
public: public:
static constexpr size_t MaxTableSize = 1024; static constexpr size_t MaxTableSize = 1024;
private:
union HandlePack {
u32 raw;
BitField<0, 15, u32> index;
BitField<15, 15, u32> linear_id;
BitField<30, 2, u32> reserved;
};
static constexpr u16 MinLinearId = 1;
static constexpr u16 MaxLinearId = 0x7FFF;
static constexpr Handle EncodeHandle(u16 index, u16 linear_id) {
HandlePack handle{};
handle.index.Assign(index);
handle.linear_id.Assign(linear_id);
handle.reserved.Assign(0);
return handle.raw;
}
union EntryInfo {
struct {
u16 linear_id;
u16 type;
} info;
s32 next_free_index;
constexpr u16 GetLinearId() const {
return info.linear_id;
}
constexpr u16 GetType() const {
return info.type;
}
constexpr s32 GetNextFreeIndex() const {
return next_free_index;
}
};
private:
std::array<EntryInfo, MaxTableSize> m_entry_infos{};
std::array<KAutoObject*, MaxTableSize> m_objects{};
s32 m_free_head_index{-1};
u16 m_table_size{};
u16 m_max_count{};
u16 m_next_linear_id{MinLinearId};
u16 m_count{};
mutable KSpinLock m_lock;
public: public:
explicit KHandleTable(KernelCore& kernel_); explicit KHandleTable(KernelCore& kernel_);
~KHandleTable(); ~KHandleTable();
constexpr ResultCode Initialize(s32 size) { ResultCode Initialize(s32 size) {
R_UNLESS(size <= static_cast<s32>(MaxTableSize), ResultOutOfMemory); R_UNLESS(size <= static_cast<s32>(MaxTableSize), ResultOutOfMemory);
// Initialize all fields. // Initialize all fields.
@ -100,13 +53,13 @@ public:
return RESULT_SUCCESS; return RESULT_SUCCESS;
} }
constexpr size_t GetTableSize() const { size_t GetTableSize() const {
return m_table_size; return m_table_size;
} }
constexpr size_t GetCount() const { size_t GetCount() const {
return m_count; return m_count;
} }
constexpr size_t GetMaxCount() const { size_t GetMaxCount() const {
return m_max_count; return m_max_count;
} }
@ -118,7 +71,7 @@ public:
// Lock and look up in table. // Lock and look up in table.
KScopedSpinLock lk(m_lock); KScopedSpinLock lk(m_lock);
if constexpr (std::is_same<T, KAutoObject>::value) { if constexpr (std::is_same_v<T, KAutoObject>) {
return this->GetObjectImpl(handle); return this->GetObjectImpl(handle);
} else { } else {
if (auto* obj = this->GetObjectImpl(handle); obj != nullptr) { if (auto* obj = this->GetObjectImpl(handle); obj != nullptr) {
@ -154,13 +107,13 @@ public:
template <typename T> template <typename T>
ResultCode Add(Handle* out_handle, T* obj) { ResultCode Add(Handle* out_handle, T* obj) {
static_assert(std::is_base_of<KAutoObject, T>::value); static_assert(std::is_base_o_vf<KAutoObject, T>);
return this->Add(out_handle, obj, obj->GetTypeObj().GetClassToken()); return this->Add(out_handle, obj, obj->GetTypeObj().GetClassToken());
} }
template <typename T> template <typename T>
void Register(Handle handle, T* obj) { void Register(Handle handle, T* obj) {
static_assert(std::is_base_of<KAutoObject, T>::value); static_assert(std::is_base_of_v<KAutoObject, T>);
return this->Register(handle, obj, obj->GetTypeObj().GetClassToken()); return this->Register(handle, obj, obj->GetTypeObj().GetClassToken());
} }
@ -210,7 +163,7 @@ private:
ResultCode Add(Handle* out_handle, KAutoObject* obj, u16 type); ResultCode Add(Handle* out_handle, KAutoObject* obj, u16 type);
void Register(Handle handle, KAutoObject* obj, u16 type); void Register(Handle handle, KAutoObject* obj, u16 type);
constexpr s32 AllocateEntry() { s32 AllocateEntry() {
ASSERT(m_count < m_table_size); ASSERT(m_count < m_table_size);
const auto index = m_free_head_index; const auto index = m_free_head_index;
@ -222,7 +175,7 @@ private:
return index; return index;
} }
constexpr void FreeEntry(s32 index) { void FreeEntry(s32 index) {
ASSERT(m_count > 0); ASSERT(m_count > 0);
m_objects[index] = nullptr; m_objects[index] = nullptr;
@ -233,7 +186,7 @@ private:
--m_count; --m_count;
} }
constexpr u16 AllocateLinearId() { u16 AllocateLinearId() {
const u16 id = m_next_linear_id++; const u16 id = m_next_linear_id++;
if (m_next_linear_id > MaxLinearId) { if (m_next_linear_id > MaxLinearId) {
m_next_linear_id = MinLinearId; m_next_linear_id = MinLinearId;
@ -241,7 +194,7 @@ private:
return id; return id;
} }
constexpr bool IsValidHandle(Handle handle) const { bool IsValidHandle(Handle handle) const {
// Unpack the handle. // Unpack the handle.
const auto handle_pack = HandlePack(handle); const auto handle_pack = HandlePack(handle);
const auto raw_value = handle_pack.raw; const auto raw_value = handle_pack.raw;
@ -272,7 +225,7 @@ private:
return true; return true;
} }
constexpr KAutoObject* GetObjectImpl(Handle handle) const { KAutoObject* GetObjectImpl(Handle handle) const {
// Handles must not have reserved bits set. // Handles must not have reserved bits set.
const auto handle_pack = HandlePack(handle); const auto handle_pack = HandlePack(handle);
if (handle_pack.reserved != 0) { if (handle_pack.reserved != 0) {
@ -286,7 +239,7 @@ private:
} }
} }
constexpr KAutoObject* GetObjectByIndexImpl(Handle* out_handle, size_t index) const { KAutoObject* GetObjectByIndexImpl(Handle* out_handle, size_t index) const {
// Index must be in bounds. // Index must be in bounds.
if (index >= m_table_size) { if (index >= m_table_size) {
@ -303,6 +256,51 @@ private:
} }
private: private:
union HandlePack {
u32 raw;
BitField<0, 15, u32> index;
BitField<15, 15, u32> linear_id;
BitField<30, 2, u32> reserved;
};
static constexpr u16 MinLinearId = 1;
static constexpr u16 MaxLinearId = 0x7FFF;
static constexpr Handle EncodeHandle(u16 index, u16 linear_id) {
HandlePack handle{};
handle.index.Assign(index);
handle.linear_id.Assign(linear_id);
handle.reserved.Assign(0);
return handle.raw;
}
union EntryInfo {
struct {
u16 linear_id;
u16 type;
} info;
s32 next_free_index;
constexpr u16 GetLinearId() const {
return info.linear_id;
}
constexpr u16 GetType() const {
return info.type;
}
constexpr s32 GetNextFreeIndex() const {
return next_free_index;
}
};
private:
std::array<EntryInfo, MaxTableSize> m_entry_infos{};
std::array<KAutoObject*, MaxTableSize> m_objects{};
s32 m_free_head_index{-1};
u16 m_table_size{};
u16 m_max_count{};
u16 m_next_linear_id{MinLinearId};
u16 m_count{};
mutable KSpinLock m_lock;
KernelCore& kernel; KernelCore& kernel;
}; };