diff options
| author | 2021-05-01 12:42:44 -0700 | |
|---|---|---|
| committer | 2021-05-05 16:40:53 -0700 | |
| commit | d23f9f75fff3b65ce5b3feae873df9726e099e93 (patch) | |
| tree | 19f8c104a6be1b345d58d7304d7eb719d87ad39d /src/core/hle/kernel | |
| parent | fixup! hle: kernel: Add initial impl. of KAutoObjectWithListContainer. (diff) | |
| download | yuzu-d23f9f75fff3b65ce5b3feae873df9726e099e93.tar.gz yuzu-d23f9f75fff3b65ce5b3feae873df9726e099e93.tar.xz yuzu-d23f9f75fff3b65ce5b3feae873df9726e099e93.zip | |
fixup! hle: kernel: Migrate to KHandleTable.
Diffstat (limited to 'src/core/hle/kernel')
| -rw-r--r-- | src/core/hle/kernel/k_handle_table.h | 118 |
1 files changed, 58 insertions, 60 deletions
diff --git a/src/core/hle/kernel/k_handle_table.h b/src/core/hle/kernel/k_handle_table.h index 74afb91b1..adce899c3 100644 --- a/src/core/hle/kernel/k_handle_table.h +++ b/src/core/hle/kernel/k_handle_table.h | |||
| @@ -29,58 +29,11 @@ class KHandleTable { | |||
| 29 | public: | 29 | public: |
| 30 | static constexpr size_t MaxTableSize = 1024; | 30 | static constexpr size_t MaxTableSize = 1024; |
| 31 | 31 | ||
| 32 | private: | ||
| 33 | union HandlePack { | ||
| 34 | u32 raw; | ||
| 35 | BitField<0, 15, u32> index; | ||
| 36 | BitField<15, 15, u32> linear_id; | ||
| 37 | BitField<30, 2, u32> reserved; | ||
| 38 | }; | ||
| 39 | |||
| 40 | static constexpr u16 MinLinearId = 1; | ||
| 41 | static constexpr u16 MaxLinearId = 0x7FFF; | ||
| 42 | |||
| 43 | static constexpr Handle EncodeHandle(u16 index, u16 linear_id) { | ||
| 44 | HandlePack handle{}; | ||
| 45 | handle.index.Assign(index); | ||
| 46 | handle.linear_id.Assign(linear_id); | ||
| 47 | handle.reserved.Assign(0); | ||
| 48 | return handle.raw; | ||
| 49 | } | ||
| 50 | |||
| 51 | union EntryInfo { | ||
| 52 | struct { | ||
| 53 | u16 linear_id; | ||
| 54 | u16 type; | ||
| 55 | } info; | ||
| 56 | s32 next_free_index; | ||
| 57 | |||
| 58 | constexpr u16 GetLinearId() const { | ||
| 59 | return info.linear_id; | ||
| 60 | } | ||
| 61 | constexpr u16 GetType() const { | ||
| 62 | return info.type; | ||
| 63 | } | ||
| 64 | constexpr s32 GetNextFreeIndex() const { | ||
| 65 | return next_free_index; | ||
| 66 | } | ||
| 67 | }; | ||
| 68 | |||
| 69 | private: | ||
| 70 | std::array<EntryInfo, MaxTableSize> m_entry_infos{}; | ||
| 71 | std::array<KAutoObject*, MaxTableSize> m_objects{}; | ||
| 72 | s32 m_free_head_index{-1}; | ||
| 73 | u16 m_table_size{}; | ||
| 74 | u16 m_max_count{}; | ||
| 75 | u16 m_next_linear_id{MinLinearId}; | ||
| 76 | u16 m_count{}; | ||
| 77 | mutable KSpinLock m_lock; | ||
| 78 | |||
| 79 | public: | 32 | public: |
| 80 | explicit KHandleTable(KernelCore& kernel_); | 33 | explicit KHandleTable(KernelCore& kernel_); |
| 81 | ~KHandleTable(); | 34 | ~KHandleTable(); |
| 82 | 35 | ||
| 83 | constexpr ResultCode Initialize(s32 size) { | 36 | ResultCode Initialize(s32 size) { |
| 84 | R_UNLESS(size <= static_cast<s32>(MaxTableSize), ResultOutOfMemory); | 37 | R_UNLESS(size <= static_cast<s32>(MaxTableSize), ResultOutOfMemory); |
| 85 | 38 | ||
| 86 | // Initialize all fields. | 39 | // Initialize all fields. |
| @@ -100,13 +53,13 @@ public: | |||
| 100 | return RESULT_SUCCESS; | 53 | return RESULT_SUCCESS; |
| 101 | } | 54 | } |
| 102 | 55 | ||
| 103 | constexpr size_t GetTableSize() const { | 56 | size_t GetTableSize() const { |
| 104 | return m_table_size; | 57 | return m_table_size; |
| 105 | } | 58 | } |
| 106 | constexpr size_t GetCount() const { | 59 | size_t GetCount() const { |
| 107 | return m_count; | 60 | return m_count; |
| 108 | } | 61 | } |
| 109 | constexpr size_t GetMaxCount() const { | 62 | size_t GetMaxCount() const { |
| 110 | return m_max_count; | 63 | return m_max_count; |
| 111 | } | 64 | } |
| 112 | 65 | ||
| @@ -118,7 +71,7 @@ public: | |||
| 118 | // Lock and look up in table. | 71 | // Lock and look up in table. |
| 119 | KScopedSpinLock lk(m_lock); | 72 | KScopedSpinLock lk(m_lock); |
| 120 | 73 | ||
| 121 | if constexpr (std::is_same<T, KAutoObject>::value) { | 74 | if constexpr (std::is_same_v<T, KAutoObject>) { |
| 122 | return this->GetObjectImpl(handle); | 75 | return this->GetObjectImpl(handle); |
| 123 | } else { | 76 | } else { |
| 124 | if (auto* obj = this->GetObjectImpl(handle); obj != nullptr) { | 77 | if (auto* obj = this->GetObjectImpl(handle); obj != nullptr) { |
| @@ -154,13 +107,13 @@ public: | |||
| 154 | 107 | ||
| 155 | template <typename T> | 108 | template <typename T> |
| 156 | ResultCode Add(Handle* out_handle, T* obj) { | 109 | ResultCode Add(Handle* out_handle, T* obj) { |
| 157 | static_assert(std::is_base_of<KAutoObject, T>::value); | 110 | static_assert(std::is_base_o_vf<KAutoObject, T>); |
| 158 | return this->Add(out_handle, obj, obj->GetTypeObj().GetClassToken()); | 111 | return this->Add(out_handle, obj, obj->GetTypeObj().GetClassToken()); |
| 159 | } | 112 | } |
| 160 | 113 | ||
| 161 | template <typename T> | 114 | template <typename T> |
| 162 | void Register(Handle handle, T* obj) { | 115 | void Register(Handle handle, T* obj) { |
| 163 | static_assert(std::is_base_of<KAutoObject, T>::value); | 116 | static_assert(std::is_base_of_v<KAutoObject, T>); |
| 164 | return this->Register(handle, obj, obj->GetTypeObj().GetClassToken()); | 117 | return this->Register(handle, obj, obj->GetTypeObj().GetClassToken()); |
| 165 | } | 118 | } |
| 166 | 119 | ||
| @@ -210,7 +163,7 @@ private: | |||
| 210 | ResultCode Add(Handle* out_handle, KAutoObject* obj, u16 type); | 163 | ResultCode Add(Handle* out_handle, KAutoObject* obj, u16 type); |
| 211 | void Register(Handle handle, KAutoObject* obj, u16 type); | 164 | void Register(Handle handle, KAutoObject* obj, u16 type); |
| 212 | 165 | ||
| 213 | constexpr s32 AllocateEntry() { | 166 | s32 AllocateEntry() { |
| 214 | ASSERT(m_count < m_table_size); | 167 | ASSERT(m_count < m_table_size); |
| 215 | 168 | ||
| 216 | const auto index = m_free_head_index; | 169 | const auto index = m_free_head_index; |
| @@ -222,7 +175,7 @@ private: | |||
| 222 | return index; | 175 | return index; |
| 223 | } | 176 | } |
| 224 | 177 | ||
| 225 | constexpr void FreeEntry(s32 index) { | 178 | void FreeEntry(s32 index) { |
| 226 | ASSERT(m_count > 0); | 179 | ASSERT(m_count > 0); |
| 227 | 180 | ||
| 228 | m_objects[index] = nullptr; | 181 | m_objects[index] = nullptr; |
| @@ -233,7 +186,7 @@ private: | |||
| 233 | --m_count; | 186 | --m_count; |
| 234 | } | 187 | } |
| 235 | 188 | ||
| 236 | constexpr u16 AllocateLinearId() { | 189 | u16 AllocateLinearId() { |
| 237 | const u16 id = m_next_linear_id++; | 190 | const u16 id = m_next_linear_id++; |
| 238 | if (m_next_linear_id > MaxLinearId) { | 191 | if (m_next_linear_id > MaxLinearId) { |
| 239 | m_next_linear_id = MinLinearId; | 192 | m_next_linear_id = MinLinearId; |
| @@ -241,7 +194,7 @@ private: | |||
| 241 | return id; | 194 | return id; |
| 242 | } | 195 | } |
| 243 | 196 | ||
| 244 | constexpr bool IsValidHandle(Handle handle) const { | 197 | bool IsValidHandle(Handle handle) const { |
| 245 | // Unpack the handle. | 198 | // Unpack the handle. |
| 246 | const auto handle_pack = HandlePack(handle); | 199 | const auto handle_pack = HandlePack(handle); |
| 247 | const auto raw_value = handle_pack.raw; | 200 | const auto raw_value = handle_pack.raw; |
| @@ -272,7 +225,7 @@ private: | |||
| 272 | return true; | 225 | return true; |
| 273 | } | 226 | } |
| 274 | 227 | ||
| 275 | constexpr KAutoObject* GetObjectImpl(Handle handle) const { | 228 | KAutoObject* GetObjectImpl(Handle handle) const { |
| 276 | // Handles must not have reserved bits set. | 229 | // Handles must not have reserved bits set. |
| 277 | const auto handle_pack = HandlePack(handle); | 230 | const auto handle_pack = HandlePack(handle); |
| 278 | if (handle_pack.reserved != 0) { | 231 | if (handle_pack.reserved != 0) { |
| @@ -286,7 +239,7 @@ private: | |||
| 286 | } | 239 | } |
| 287 | } | 240 | } |
| 288 | 241 | ||
| 289 | constexpr KAutoObject* GetObjectByIndexImpl(Handle* out_handle, size_t index) const { | 242 | KAutoObject* GetObjectByIndexImpl(Handle* out_handle, size_t index) const { |
| 290 | 243 | ||
| 291 | // Index must be in bounds. | 244 | // Index must be in bounds. |
| 292 | if (index >= m_table_size) { | 245 | if (index >= m_table_size) { |
| @@ -303,6 +256,51 @@ private: | |||
| 303 | } | 256 | } |
| 304 | 257 | ||
| 305 | private: | 258 | private: |
| 259 | union HandlePack { | ||
| 260 | u32 raw; | ||
| 261 | BitField<0, 15, u32> index; | ||
| 262 | BitField<15, 15, u32> linear_id; | ||
| 263 | BitField<30, 2, u32> reserved; | ||
| 264 | }; | ||
| 265 | |||
| 266 | static constexpr u16 MinLinearId = 1; | ||
| 267 | static constexpr u16 MaxLinearId = 0x7FFF; | ||
| 268 | |||
| 269 | static constexpr Handle EncodeHandle(u16 index, u16 linear_id) { | ||
| 270 | HandlePack handle{}; | ||
| 271 | handle.index.Assign(index); | ||
| 272 | handle.linear_id.Assign(linear_id); | ||
| 273 | handle.reserved.Assign(0); | ||
| 274 | return handle.raw; | ||
| 275 | } | ||
| 276 | |||
| 277 | union EntryInfo { | ||
| 278 | struct { | ||
| 279 | u16 linear_id; | ||
| 280 | u16 type; | ||
| 281 | } info; | ||
| 282 | s32 next_free_index; | ||
| 283 | |||
| 284 | constexpr u16 GetLinearId() const { | ||
| 285 | return info.linear_id; | ||
| 286 | } | ||
| 287 | constexpr u16 GetType() const { | ||
| 288 | return info.type; | ||
| 289 | } | ||
| 290 | constexpr s32 GetNextFreeIndex() const { | ||
| 291 | return next_free_index; | ||
| 292 | } | ||
| 293 | }; | ||
| 294 | |||
| 295 | private: | ||
| 296 | std::array<EntryInfo, MaxTableSize> m_entry_infos{}; | ||
| 297 | std::array<KAutoObject*, MaxTableSize> m_objects{}; | ||
| 298 | s32 m_free_head_index{-1}; | ||
| 299 | u16 m_table_size{}; | ||
| 300 | u16 m_max_count{}; | ||
| 301 | u16 m_next_linear_id{MinLinearId}; | ||
| 302 | u16 m_count{}; | ||
| 303 | mutable KSpinLock m_lock; | ||
| 306 | KernelCore& kernel; | 304 | KernelCore& kernel; |
| 307 | }; | 305 | }; |
| 308 | 306 | ||