summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar bunnei2022-10-29 14:26:39 -0700
committerGravatar bunnei2022-11-03 21:17:07 -0700
commit6636b81573c1048d91cb1c5ac16ab2698d21ee23 (patch)
tree8dec47c156b709ee56a019067f225cc335ee4a29 /src
parentcore: hle: kernel: k_memory_layout: Refresh. (diff)
downloadyuzu-6636b81573c1048d91cb1c5ac16ab2698d21ee23.tar.gz
yuzu-6636b81573c1048d91cb1c5ac16ab2698d21ee23.tar.xz
yuzu-6636b81573c1048d91cb1c5ac16ab2698d21ee23.zip
core: hle: kernel: k_handle_table: Refresh.
Diffstat (limited to 'src')
-rw-r--r--src/core/hle/kernel/k_handle_table.cpp33
-rw-r--r--src/core/hle/kernel/k_handle_table.h108
2 files changed, 87 insertions, 54 deletions
diff --git a/src/core/hle/kernel/k_handle_table.cpp b/src/core/hle/kernel/k_handle_table.cpp
index e830ca46e..1c7a766c8 100644
--- a/src/core/hle/kernel/k_handle_table.cpp
+++ b/src/core/hle/kernel/k_handle_table.cpp
@@ -5,14 +5,11 @@
5 5
6namespace Kernel { 6namespace Kernel {
7 7
8KHandleTable::KHandleTable(KernelCore& kernel_) : kernel{kernel_} {}
9KHandleTable::~KHandleTable() = default;
10
11Result KHandleTable::Finalize() { 8Result KHandleTable::Finalize() {
12 // Get the table and clear our record of it. 9 // Get the table and clear our record of it.
13 u16 saved_table_size = 0; 10 u16 saved_table_size = 0;
14 { 11 {
15 KScopedDisableDispatch dd(kernel); 12 KScopedDisableDispatch dd{m_kernel};
16 KScopedSpinLock lk(m_lock); 13 KScopedSpinLock lk(m_lock);
17 14
18 std::swap(m_table_size, saved_table_size); 15 std::swap(m_table_size, saved_table_size);
@@ -25,28 +22,28 @@ Result KHandleTable::Finalize() {
25 } 22 }
26 } 23 }
27 24
28 return ResultSuccess; 25 R_SUCCEED();
29} 26}
30 27
31bool KHandleTable::Remove(Handle handle) { 28bool KHandleTable::Remove(Handle handle) {
32 // Don't allow removal of a pseudo-handle. 29 // Don't allow removal of a pseudo-handle.
33 if (Svc::IsPseudoHandle(handle)) { 30 if (Svc::IsPseudoHandle(handle)) [[unlikely]] {
34 return false; 31 return false;
35 } 32 }
36 33
37 // Handles must not have reserved bits set. 34 // Handles must not have reserved bits set.
38 const auto handle_pack = HandlePack(handle); 35 const auto handle_pack = HandlePack(handle);
39 if (handle_pack.reserved != 0) { 36 if (handle_pack.reserved != 0) [[unlikely]] {
40 return false; 37 return false;
41 } 38 }
42 39
43 // Find the object and free the entry. 40 // Find the object and free the entry.
44 KAutoObject* obj = nullptr; 41 KAutoObject* obj = nullptr;
45 { 42 {
46 KScopedDisableDispatch dd(kernel); 43 KScopedDisableDispatch dd{m_kernel};
47 KScopedSpinLock lk(m_lock); 44 KScopedSpinLock lk(m_lock);
48 45
49 if (this->IsValidHandle(handle)) { 46 if (this->IsValidHandle(handle)) [[likely]] {
50 const auto index = handle_pack.index; 47 const auto index = handle_pack.index;
51 48
52 obj = m_objects[index]; 49 obj = m_objects[index];
@@ -57,13 +54,13 @@ bool KHandleTable::Remove(Handle handle) {
57 } 54 }
58 55
59 // Close the object. 56 // Close the object.
60 kernel.UnregisterInUseObject(obj); 57 m_kernel.UnregisterInUseObject(obj);
61 obj->Close(); 58 obj->Close();
62 return true; 59 return true;
63} 60}
64 61
65Result KHandleTable::Add(Handle* out_handle, KAutoObject* obj) { 62Result KHandleTable::Add(Handle* out_handle, KAutoObject* obj) {
66 KScopedDisableDispatch dd(kernel); 63 KScopedDisableDispatch dd{m_kernel};
67 KScopedSpinLock lk(m_lock); 64 KScopedSpinLock lk(m_lock);
68 65
69 // Never exceed our capacity. 66 // Never exceed our capacity.
@@ -82,22 +79,22 @@ Result KHandleTable::Add(Handle* out_handle, KAutoObject* obj) {
82 *out_handle = EncodeHandle(static_cast<u16>(index), linear_id); 79 *out_handle = EncodeHandle(static_cast<u16>(index), linear_id);
83 } 80 }
84 81
85 return ResultSuccess; 82 R_SUCCEED();
86} 83}
87 84
88Result KHandleTable::Reserve(Handle* out_handle) { 85Result KHandleTable::Reserve(Handle* out_handle) {
89 KScopedDisableDispatch dd(kernel); 86 KScopedDisableDispatch dd{m_kernel};
90 KScopedSpinLock lk(m_lock); 87 KScopedSpinLock lk(m_lock);
91 88
92 // Never exceed our capacity. 89 // Never exceed our capacity.
93 R_UNLESS(m_count < m_table_size, ResultOutOfHandles); 90 R_UNLESS(m_count < m_table_size, ResultOutOfHandles);
94 91
95 *out_handle = EncodeHandle(static_cast<u16>(this->AllocateEntry()), this->AllocateLinearId()); 92 *out_handle = EncodeHandle(static_cast<u16>(this->AllocateEntry()), this->AllocateLinearId());
96 return ResultSuccess; 93 R_SUCCEED();
97} 94}
98 95
99void KHandleTable::Unreserve(Handle handle) { 96void KHandleTable::Unreserve(Handle handle) {
100 KScopedDisableDispatch dd(kernel); 97 KScopedDisableDispatch dd{m_kernel};
101 KScopedSpinLock lk(m_lock); 98 KScopedSpinLock lk(m_lock);
102 99
103 // Unpack the handle. 100 // Unpack the handle.
@@ -108,7 +105,7 @@ void KHandleTable::Unreserve(Handle handle) {
108 ASSERT(reserved == 0); 105 ASSERT(reserved == 0);
109 ASSERT(linear_id != 0); 106 ASSERT(linear_id != 0);
110 107
111 if (index < m_table_size) { 108 if (index < m_table_size) [[likely]] {
112 // NOTE: This code does not check the linear id. 109 // NOTE: This code does not check the linear id.
113 ASSERT(m_objects[index] == nullptr); 110 ASSERT(m_objects[index] == nullptr);
114 this->FreeEntry(index); 111 this->FreeEntry(index);
@@ -116,7 +113,7 @@ void KHandleTable::Unreserve(Handle handle) {
116} 113}
117 114
118void KHandleTable::Register(Handle handle, KAutoObject* obj) { 115void KHandleTable::Register(Handle handle, KAutoObject* obj) {
119 KScopedDisableDispatch dd(kernel); 116 KScopedDisableDispatch dd{m_kernel};
120 KScopedSpinLock lk(m_lock); 117 KScopedSpinLock lk(m_lock);
121 118
122 // Unpack the handle. 119 // Unpack the handle.
@@ -127,7 +124,7 @@ void KHandleTable::Register(Handle handle, KAutoObject* obj) {
127 ASSERT(reserved == 0); 124 ASSERT(reserved == 0);
128 ASSERT(linear_id != 0); 125 ASSERT(linear_id != 0);
129 126
130 if (index < m_table_size) { 127 if (index < m_table_size) [[likely]] {
131 // Set the entry. 128 // Set the entry.
132 ASSERT(m_objects[index] == nullptr); 129 ASSERT(m_objects[index] == nullptr);
133 130
diff --git a/src/core/hle/kernel/k_handle_table.h b/src/core/hle/kernel/k_handle_table.h
index 0864a737c..e98a01c86 100644
--- a/src/core/hle/kernel/k_handle_table.h
+++ b/src/core/hle/kernel/k_handle_table.h
@@ -21,33 +21,38 @@ namespace Kernel {
21class KernelCore; 21class KernelCore;
22 22
23class KHandleTable { 23class KHandleTable {
24public:
25 YUZU_NON_COPYABLE(KHandleTable); 24 YUZU_NON_COPYABLE(KHandleTable);
26 YUZU_NON_MOVEABLE(KHandleTable); 25 YUZU_NON_MOVEABLE(KHandleTable);
27 26
27public:
28 static constexpr size_t MaxTableSize = 1024; 28 static constexpr size_t MaxTableSize = 1024;
29 29
30 explicit KHandleTable(KernelCore& kernel_); 30public:
31 ~KHandleTable(); 31 explicit KHandleTable(KernelCore& kernel) : m_kernel(kernel) {}
32 32
33 Result Initialize(s32 size) { 33 Result Initialize(s32 size) {
34 // Check that the table size is valid.
34 R_UNLESS(size <= static_cast<s32>(MaxTableSize), ResultOutOfMemory); 35 R_UNLESS(size <= static_cast<s32>(MaxTableSize), ResultOutOfMemory);
35 36
37 // Lock.
38 KScopedDisableDispatch dd{m_kernel};
39 KScopedSpinLock lk(m_lock);
40
36 // Initialize all fields. 41 // Initialize all fields.
37 m_max_count = 0; 42 m_max_count = 0;
38 m_table_size = static_cast<u16>((size <= 0) ? MaxTableSize : size); 43 m_table_size = static_cast<s16>((size <= 0) ? MaxTableSize : size);
39 m_next_linear_id = MinLinearId; 44 m_next_linear_id = MinLinearId;
40 m_count = 0; 45 m_count = 0;
41 m_free_head_index = -1; 46 m_free_head_index = -1;
42 47
43 // Free all entries. 48 // Free all entries.
44 for (s16 i = 0; i < static_cast<s16>(m_table_size); ++i) { 49 for (s32 i = 0; i < static_cast<s32>(m_table_size); ++i) {
45 m_objects[i] = nullptr; 50 m_objects[i] = nullptr;
46 m_entry_infos[i].next_free_index = i - 1; 51 m_entry_infos[i].next_free_index = static_cast<s16>(i - 1);
47 m_free_head_index = i; 52 m_free_head_index = i;
48 } 53 }
49 54
50 return ResultSuccess; 55 R_SUCCEED();
51 } 56 }
52 57
53 size_t GetTableSize() const { 58 size_t GetTableSize() const {
@@ -66,13 +71,13 @@ public:
66 template <typename T = KAutoObject> 71 template <typename T = KAutoObject>
67 KScopedAutoObject<T> GetObjectWithoutPseudoHandle(Handle handle) const { 72 KScopedAutoObject<T> GetObjectWithoutPseudoHandle(Handle handle) const {
68 // Lock and look up in table. 73 // Lock and look up in table.
69 KScopedDisableDispatch dd(kernel); 74 KScopedDisableDispatch dd{m_kernel};
70 KScopedSpinLock lk(m_lock); 75 KScopedSpinLock lk(m_lock);
71 76
72 if constexpr (std::is_same_v<T, KAutoObject>) { 77 if constexpr (std::is_same<T, KAutoObject>::value) {
73 return this->GetObjectImpl(handle); 78 return this->GetObjectImpl(handle);
74 } else { 79 } else {
75 if (auto* obj = this->GetObjectImpl(handle); obj != nullptr) { 80 if (auto* obj = this->GetObjectImpl(handle); obj != nullptr) [[likely]] {
76 return obj->DynamicCast<T*>(); 81 return obj->DynamicCast<T*>();
77 } else { 82 } else {
78 return nullptr; 83 return nullptr;
@@ -85,13 +90,13 @@ public:
85 // Handle pseudo-handles. 90 // Handle pseudo-handles.
86 if constexpr (std::derived_from<KProcess, T>) { 91 if constexpr (std::derived_from<KProcess, T>) {
87 if (handle == Svc::PseudoHandle::CurrentProcess) { 92 if (handle == Svc::PseudoHandle::CurrentProcess) {
88 auto* const cur_process = kernel.CurrentProcess(); 93 auto* const cur_process = m_kernel.CurrentProcess();
89 ASSERT(cur_process != nullptr); 94 ASSERT(cur_process != nullptr);
90 return cur_process; 95 return cur_process;
91 } 96 }
92 } else if constexpr (std::derived_from<KThread, T>) { 97 } else if constexpr (std::derived_from<KThread, T>) {
93 if (handle == Svc::PseudoHandle::CurrentThread) { 98 if (handle == Svc::PseudoHandle::CurrentThread) {
94 auto* const cur_thread = GetCurrentThreadPointer(kernel); 99 auto* const cur_thread = GetCurrentThreadPointer(m_kernel);
95 ASSERT(cur_thread != nullptr); 100 ASSERT(cur_thread != nullptr);
96 return cur_thread; 101 return cur_thread;
97 } 102 }
@@ -100,6 +105,37 @@ public:
100 return this->template GetObjectWithoutPseudoHandle<T>(handle); 105 return this->template GetObjectWithoutPseudoHandle<T>(handle);
101 } 106 }
102 107
108 KScopedAutoObject<KAutoObject> GetObjectForIpcWithoutPseudoHandle(Handle handle) const {
109 // Lock and look up in table.
110 KScopedDisableDispatch dd{m_kernel};
111 KScopedSpinLock lk(m_lock);
112
113 return this->GetObjectImpl(handle);
114 }
115
116 KScopedAutoObject<KAutoObject> GetObjectForIpc(Handle handle, KThread* cur_thread) const {
117 // Handle pseudo-handles.
118 ASSERT(cur_thread != nullptr);
119 if (handle == Svc::PseudoHandle::CurrentProcess) {
120 auto* const cur_process =
121 static_cast<KAutoObject*>(static_cast<void*>(cur_thread->GetOwnerProcess()));
122 ASSERT(cur_process != nullptr);
123 return cur_process;
124 }
125 if (handle == Svc::PseudoHandle::CurrentThread) {
126 return static_cast<KAutoObject*>(cur_thread);
127 }
128
129 return GetObjectForIpcWithoutPseudoHandle(handle);
130 }
131
132 KScopedAutoObject<KAutoObject> GetObjectByIndex(Handle* out_handle, size_t index) const {
133 KScopedDisableDispatch dd{m_kernel};
134 KScopedSpinLock lk(m_lock);
135
136 return this->GetObjectByIndexImpl(out_handle, index);
137 }
138
103 Result Reserve(Handle* out_handle); 139 Result Reserve(Handle* out_handle);
104 void Unreserve(Handle handle); 140 void Unreserve(Handle handle);
105 141
@@ -112,7 +148,7 @@ public:
112 size_t num_opened; 148 size_t num_opened;
113 { 149 {
114 // Lock the table. 150 // Lock the table.
115 KScopedDisableDispatch dd(kernel); 151 KScopedDisableDispatch dd{m_kernel};
116 KScopedSpinLock lk(m_lock); 152 KScopedSpinLock lk(m_lock);
117 for (num_opened = 0; num_opened < num_handles; num_opened++) { 153 for (num_opened = 0; num_opened < num_handles; num_opened++) {
118 // Get the current handle. 154 // Get the current handle.
@@ -120,13 +156,13 @@ public:
120 156
121 // Get the object for the current handle. 157 // Get the object for the current handle.
122 KAutoObject* cur_object = this->GetObjectImpl(cur_handle); 158 KAutoObject* cur_object = this->GetObjectImpl(cur_handle);
123 if (cur_object == nullptr) { 159 if (cur_object == nullptr) [[unlikely]] {
124 break; 160 break;
125 } 161 }
126 162
127 // Cast the current object to the desired type. 163 // Cast the current object to the desired type.
128 T* cur_t = cur_object->DynamicCast<T*>(); 164 T* cur_t = cur_object->DynamicCast<T*>();
129 if (cur_t == nullptr) { 165 if (cur_t == nullptr) [[unlikely]] {
130 break; 166 break;
131 } 167 }
132 168
@@ -137,7 +173,7 @@ public:
137 } 173 }
138 174
139 // If we converted every object, succeed. 175 // If we converted every object, succeed.
140 if (num_opened == num_handles) { 176 if (num_opened == num_handles) [[likely]] {
141 return true; 177 return true;
142 } 178 }
143 179
@@ -191,21 +227,21 @@ private:
191 ASSERT(reserved == 0); 227 ASSERT(reserved == 0);
192 228
193 // Validate our indexing information. 229 // Validate our indexing information.
194 if (raw_value == 0) { 230 if (raw_value == 0) [[unlikely]] {
195 return false; 231 return false;
196 } 232 }
197 if (linear_id == 0) { 233 if (linear_id == 0) [[unlikely]] {
198 return false; 234 return false;
199 } 235 }
200 if (index >= m_table_size) { 236 if (index >= m_table_size) [[unlikely]] {
201 return false; 237 return false;
202 } 238 }
203 239
204 // Check that there's an object, and our serial id is correct. 240 // Check that there's an object, and our serial id is correct.
205 if (m_objects[index] == nullptr) { 241 if (m_objects[index] == nullptr) [[unlikely]] {
206 return false; 242 return false;
207 } 243 }
208 if (m_entry_infos[index].GetLinearId() != linear_id) { 244 if (m_entry_infos[index].GetLinearId() != linear_id) [[unlikely]] {
209 return false; 245 return false;
210 } 246 }
211 247
@@ -215,11 +251,11 @@ private:
215 KAutoObject* GetObjectImpl(Handle handle) const { 251 KAutoObject* GetObjectImpl(Handle handle) const {
216 // Handles must not have reserved bits set. 252 // Handles must not have reserved bits set.
217 const auto handle_pack = HandlePack(handle); 253 const auto handle_pack = HandlePack(handle);
218 if (handle_pack.reserved != 0) { 254 if (handle_pack.reserved != 0) [[unlikely]] {
219 return nullptr; 255 return nullptr;
220 } 256 }
221 257
222 if (this->IsValidHandle(handle)) { 258 if (this->IsValidHandle(handle)) [[likely]] {
223 return m_objects[handle_pack.index]; 259 return m_objects[handle_pack.index];
224 } else { 260 } else {
225 return nullptr; 261 return nullptr;
@@ -227,9 +263,8 @@ private:
227 } 263 }
228 264
229 KAutoObject* GetObjectByIndexImpl(Handle* out_handle, size_t index) const { 265 KAutoObject* GetObjectByIndexImpl(Handle* out_handle, size_t index) const {
230
231 // Index must be in bounds. 266 // Index must be in bounds.
232 if (index >= m_table_size) { 267 if (index >= m_table_size) [[unlikely]] {
233 return nullptr; 268 return nullptr;
234 } 269 }
235 270
@@ -244,18 +279,15 @@ private:
244 279
245private: 280private:
246 union HandlePack { 281 union HandlePack {
247 HandlePack() = default; 282 constexpr HandlePack() = default;
248 HandlePack(Handle handle) : raw{static_cast<u32>(handle)} {} 283 constexpr HandlePack(Handle handle) : raw{static_cast<u32>(handle)} {}
249 284
250 u32 raw; 285 u32 raw{};
251 BitField<0, 15, u32> index; 286 BitField<0, 15, u32> index;
252 BitField<15, 15, u32> linear_id; 287 BitField<15, 15, u32> linear_id;
253 BitField<30, 2, u32> reserved; 288 BitField<30, 2, u32> reserved;
254 }; 289 };
255 290
256 static constexpr u16 MinLinearId = 1;
257 static constexpr u16 MaxLinearId = 0x7FFF;
258
259 static constexpr Handle EncodeHandle(u16 index, u16 linear_id) { 291 static constexpr Handle EncodeHandle(u16 index, u16 linear_id) {
260 HandlePack handle{}; 292 HandlePack handle{};
261 handle.index.Assign(index); 293 handle.index.Assign(index);
@@ -264,6 +296,10 @@ private:
264 return handle.raw; 296 return handle.raw;
265 } 297 }
266 298
299private:
300 static constexpr u16 MinLinearId = 1;
301 static constexpr u16 MaxLinearId = 0x7FFF;
302
267 union EntryInfo { 303 union EntryInfo {
268 u16 linear_id; 304 u16 linear_id;
269 s16 next_free_index; 305 s16 next_free_index;
@@ -271,21 +307,21 @@ private:
271 constexpr u16 GetLinearId() const { 307 constexpr u16 GetLinearId() const {
272 return linear_id; 308 return linear_id;
273 } 309 }
274 constexpr s16 GetNextFreeIndex() const { 310 constexpr s32 GetNextFreeIndex() const {
275 return next_free_index; 311 return next_free_index;
276 } 312 }
277 }; 313 };
278 314
279private: 315private:
316 KernelCore& m_kernel;
280 std::array<EntryInfo, MaxTableSize> m_entry_infos{}; 317 std::array<EntryInfo, MaxTableSize> m_entry_infos{};
281 std::array<KAutoObject*, MaxTableSize> m_objects{}; 318 std::array<KAutoObject*, MaxTableSize> m_objects{};
282 s32 m_free_head_index{-1}; 319 mutable KSpinLock m_lock;
320 s32 m_free_head_index{};
283 u16 m_table_size{}; 321 u16 m_table_size{};
284 u16 m_max_count{}; 322 u16 m_max_count{};
285 u16 m_next_linear_id{MinLinearId}; 323 u16 m_next_linear_id{};
286 u16 m_count{}; 324 u16 m_count{};
287 mutable KSpinLock m_lock;
288 KernelCore& kernel;
289}; 325};
290 326
291} // namespace Kernel 327} // namespace Kernel