diff options
Diffstat (limited to 'src')
22 files changed, 503 insertions, 381 deletions
diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index 889a2d2f8..83da30418 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt | |||
| @@ -149,8 +149,6 @@ add_library(core STATIC | |||
| 149 | hle/kernel/svc_results.h | 149 | hle/kernel/svc_results.h |
| 150 | hle/kernel/global_scheduler_context.cpp | 150 | hle/kernel/global_scheduler_context.cpp |
| 151 | hle/kernel/global_scheduler_context.h | 151 | hle/kernel/global_scheduler_context.h |
| 152 | hle/kernel/handle_table.cpp | ||
| 153 | hle/kernel/handle_table.h | ||
| 154 | hle/kernel/hle_ipc.cpp | 152 | hle/kernel/hle_ipc.cpp |
| 155 | hle/kernel/hle_ipc.h | 153 | hle/kernel/hle_ipc.h |
| 156 | hle/kernel/init/init_slab_setup.cpp | 154 | hle/kernel/init/init_slab_setup.cpp |
| @@ -174,6 +172,8 @@ add_library(core STATIC | |||
| 174 | hle/kernel/k_condition_variable.h | 172 | hle/kernel/k_condition_variable.h |
| 175 | hle/kernel/k_event.cpp | 173 | hle/kernel/k_event.cpp |
| 176 | hle/kernel/k_event.h | 174 | hle/kernel/k_event.h |
| 175 | hle/kernel/k_handle_table.cpp | ||
| 176 | hle/kernel/k_handle_table.h | ||
| 177 | hle/kernel/k_light_condition_variable.h | 177 | hle/kernel/k_light_condition_variable.h |
| 178 | hle/kernel/k_light_lock.cpp | 178 | hle/kernel/k_light_lock.cpp |
| 179 | hle/kernel/k_light_lock.h | 179 | hle/kernel/k_light_lock.h |
diff --git a/src/core/hle/kernel/handle_table.cpp b/src/core/hle/kernel/handle_table.cpp deleted file mode 100644 index 16c528f5b..000000000 --- a/src/core/hle/kernel/handle_table.cpp +++ /dev/null | |||
| @@ -1,125 +0,0 @@ | |||
| 1 | // Copyright 2014 Citra Emulator Project | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #include <utility> | ||
| 6 | #include "common/assert.h" | ||
| 7 | #include "common/logging/log.h" | ||
| 8 | #include "core/core.h" | ||
| 9 | #include "core/hle/kernel/handle_table.h" | ||
| 10 | #include "core/hle/kernel/k_process.h" | ||
| 11 | #include "core/hle/kernel/k_scheduler.h" | ||
| 12 | #include "core/hle/kernel/k_thread.h" | ||
| 13 | #include "core/hle/kernel/kernel.h" | ||
| 14 | #include "core/hle/kernel/svc_results.h" | ||
| 15 | |||
| 16 | namespace Kernel { | ||
| 17 | namespace { | ||
| 18 | constexpr u16 GetSlot(Handle handle) { | ||
| 19 | return static_cast<u16>(handle >> 15); | ||
| 20 | } | ||
| 21 | |||
| 22 | constexpr u16 GetGeneration(Handle handle) { | ||
| 23 | return static_cast<u16>(handle & 0x7FFF); | ||
| 24 | } | ||
| 25 | } // Anonymous namespace | ||
| 26 | |||
| 27 | HandleTable::HandleTable(KernelCore& kernel) : kernel{kernel} { | ||
| 28 | Clear(); | ||
| 29 | } | ||
| 30 | |||
| 31 | HandleTable::~HandleTable() = default; | ||
| 32 | |||
| 33 | ResultCode HandleTable::SetSize(s32 handle_table_size) { | ||
| 34 | if (static_cast<u32>(handle_table_size) > MAX_COUNT) { | ||
| 35 | LOG_ERROR(Kernel, "Handle table size {} is greater than {}", handle_table_size, MAX_COUNT); | ||
| 36 | return ResultOutOfMemory; | ||
| 37 | } | ||
| 38 | |||
| 39 | // Values less than or equal to zero indicate to use the maximum allowable | ||
| 40 | // size for the handle table in the actual kernel, so we ignore the given | ||
| 41 | // value in that case, since we assume this by default unless this function | ||
| 42 | // is called. | ||
| 43 | if (handle_table_size > 0) { | ||
| 44 | table_size = static_cast<u16>(handle_table_size); | ||
| 45 | } | ||
| 46 | |||
| 47 | return RESULT_SUCCESS; | ||
| 48 | } | ||
| 49 | |||
| 50 | ResultCode HandleTable::Add(Handle* out_handle, KAutoObject* obj, u16 type) { | ||
| 51 | ASSERT(obj != nullptr); | ||
| 52 | |||
| 53 | const u16 slot = next_free_slot; | ||
| 54 | if (slot >= table_size) { | ||
| 55 | LOG_ERROR(Kernel, "Unable to allocate Handle, too many slots in use."); | ||
| 56 | return ResultOutOfHandles; | ||
| 57 | } | ||
| 58 | next_free_slot = generations[slot]; | ||
| 59 | |||
| 60 | const u16 generation = next_generation++; | ||
| 61 | |||
| 62 | // Overflow count so it fits in the 15 bits dedicated to the generation in the handle. | ||
| 63 | // Horizon OS uses zero to represent an invalid handle, so skip to 1. | ||
| 64 | if (next_generation >= (1 << 15)) { | ||
| 65 | next_generation = 1; | ||
| 66 | } | ||
| 67 | |||
| 68 | generations[slot] = generation; | ||
| 69 | objects[slot] = obj; | ||
| 70 | obj->Open(); | ||
| 71 | |||
| 72 | *out_handle = generation | (slot << 15); | ||
| 73 | |||
| 74 | return RESULT_SUCCESS; | ||
| 75 | } | ||
| 76 | |||
| 77 | ResultVal<Handle> HandleTable::Duplicate(Handle handle) { | ||
| 78 | auto object = GetObject(handle); | ||
| 79 | if (object.IsNull()) { | ||
| 80 | LOG_ERROR(Kernel, "Tried to duplicate invalid handle: {:08X}", handle); | ||
| 81 | return ResultInvalidHandle; | ||
| 82 | } | ||
| 83 | |||
| 84 | Handle out_handle{}; | ||
| 85 | R_TRY(Add(&out_handle, object.GetPointerUnsafe())); | ||
| 86 | |||
| 87 | return MakeResult(out_handle); | ||
| 88 | } | ||
| 89 | |||
| 90 | bool HandleTable::Remove(Handle handle) { | ||
| 91 | if (!IsValid(handle)) { | ||
| 92 | LOG_ERROR(Kernel, "Handle is not valid! handle={:08X}", handle); | ||
| 93 | return {}; | ||
| 94 | } | ||
| 95 | |||
| 96 | const u16 slot = GetSlot(handle); | ||
| 97 | |||
| 98 | if (objects[slot]) { | ||
| 99 | objects[slot]->Close(); | ||
| 100 | } | ||
| 101 | |||
| 102 | objects[slot] = nullptr; | ||
| 103 | |||
| 104 | generations[slot] = next_free_slot; | ||
| 105 | next_free_slot = slot; | ||
| 106 | |||
| 107 | return true; | ||
| 108 | } | ||
| 109 | |||
| 110 | bool HandleTable::IsValid(Handle handle) const { | ||
| 111 | const std::size_t slot = GetSlot(handle); | ||
| 112 | const u16 generation = GetGeneration(handle); | ||
| 113 | const bool is_object_valid = (objects[slot] != nullptr); | ||
| 114 | return slot < table_size && is_object_valid && generations[slot] == generation; | ||
| 115 | } | ||
| 116 | |||
| 117 | void HandleTable::Clear() { | ||
| 118 | for (u16 i = 0; i < table_size; ++i) { | ||
| 119 | generations[i] = static_cast<u16>(i + 1); | ||
| 120 | objects[i] = nullptr; | ||
| 121 | } | ||
| 122 | next_free_slot = 0; | ||
| 123 | } | ||
| 124 | |||
| 125 | } // namespace Kernel | ||
diff --git a/src/core/hle/kernel/handle_table.h b/src/core/hle/kernel/handle_table.h deleted file mode 100644 index 791e303d1..000000000 --- a/src/core/hle/kernel/handle_table.h +++ /dev/null | |||
| @@ -1,212 +0,0 @@ | |||
| 1 | // Copyright 2014 Citra Emulator Project | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #pragma once | ||
| 6 | |||
| 7 | #include <array> | ||
| 8 | #include <cstddef> | ||
| 9 | #include <memory> | ||
| 10 | |||
| 11 | #include "common/common_types.h" | ||
| 12 | #include "core/hle/kernel/k_auto_object.h" | ||
| 13 | #include "core/hle/kernel/k_spin_lock.h" | ||
| 14 | #include "core/hle/kernel/kernel.h" | ||
| 15 | #include "core/hle/result.h" | ||
| 16 | |||
| 17 | namespace Kernel { | ||
| 18 | |||
| 19 | class KernelCore; | ||
| 20 | |||
| 21 | enum KernelHandle : Handle { | ||
| 22 | InvalidHandle = 0, | ||
| 23 | CurrentThread = 0xFFFF8000, | ||
| 24 | CurrentProcess = 0xFFFF8001, | ||
| 25 | }; | ||
| 26 | |||
| 27 | /** | ||
| 28 | * This class allows the creation of Handles, which are references to objects that can be tested | ||
| 29 | * for validity and looked up. Here they are used to pass references to kernel objects to/from the | ||
| 30 | * emulated process. it has been designed so that it follows the same handle format and has | ||
| 31 | * approximately the same restrictions as the handle manager in the CTR-OS. | ||
| 32 | * | ||
| 33 | * Handles contain two sub-fields: a slot index (bits 31:15) and a generation value (bits 14:0). | ||
| 34 | * The slot index is used to index into the arrays in this class to access the data corresponding | ||
| 35 | * to the Handle. | ||
| 36 | * | ||
| 37 | * To prevent accidental use of a freed Handle whose slot has already been reused, a global counter | ||
| 38 | * is kept and incremented every time a Handle is created. This is the Handle's "generation". The | ||
| 39 | * value of the counter is stored into the Handle as well as in the handle table (in the | ||
| 40 | * "generations" array). When looking up a handle, the Handle's generation must match with the | ||
| 41 | * value stored on the class, otherwise the Handle is considered invalid. | ||
| 42 | * | ||
| 43 | * To find free slots when allocating a Handle without needing to scan the entire object array, the | ||
| 44 | * generations field of unallocated slots is re-purposed as a linked list of indices to free slots. | ||
| 45 | * When a Handle is created, an index is popped off the list and used for the new Handle. When it | ||
| 46 | * is destroyed, it is again pushed onto the list to be re-used by the next allocation. It is | ||
| 47 | * likely that this allocation strategy differs from the one used in CTR-OS, but this hasn't been | ||
| 48 | * verified and isn't likely to cause any problems. | ||
| 49 | */ | ||
| 50 | class HandleTable final : NonCopyable { | ||
| 51 | public: | ||
| 52 | /// This is the maximum limit of handles allowed per process in Horizon | ||
| 53 | static constexpr std::size_t MAX_COUNT = 1024; | ||
| 54 | |||
| 55 | explicit HandleTable(KernelCore& kernel); | ||
| 56 | ~HandleTable(); | ||
| 57 | |||
| 58 | /** | ||
| 59 | * Sets the number of handles that may be in use at one time | ||
| 60 | * for this handle table. | ||
| 61 | * | ||
| 62 | * @param handle_table_size The desired size to limit the handle table to. | ||
| 63 | * | ||
| 64 | * @returns an error code indicating if initialization was successful. | ||
| 65 | * If initialization was not successful, then ERR_OUT_OF_MEMORY | ||
| 66 | * will be returned. | ||
| 67 | * | ||
| 68 | * @pre handle_table_size must be within the range [0, 1024] | ||
| 69 | */ | ||
| 70 | ResultCode SetSize(s32 handle_table_size); | ||
| 71 | |||
| 72 | /** | ||
| 73 | * Returns a new handle that points to the same object as the passed in handle. | ||
| 74 | * @return The duplicated Handle or one of the following errors: | ||
| 75 | * - `ERR_INVALID_HANDLE`: an invalid handle was passed in. | ||
| 76 | * - Any errors returned by `Create()`. | ||
| 77 | */ | ||
| 78 | ResultVal<Handle> Duplicate(Handle handle); | ||
| 79 | |||
| 80 | /** | ||
| 81 | * Closes a handle, removing it from the table and decreasing the object's ref-count. | ||
| 82 | * @return `RESULT_SUCCESS` or one of the following errors: | ||
| 83 | * - `ERR_INVALID_HANDLE`: an invalid handle was passed in. | ||
| 84 | */ | ||
| 85 | bool Remove(Handle handle); | ||
| 86 | |||
| 87 | /// Checks if a handle is valid and points to an existing object. | ||
| 88 | bool IsValid(Handle handle) const; | ||
| 89 | |||
| 90 | template <typename T = KAutoObject> | ||
| 91 | KAutoObject* GetObjectImpl(Handle handle) const { | ||
| 92 | if (!IsValid(handle)) { | ||
| 93 | return nullptr; | ||
| 94 | } | ||
| 95 | |||
| 96 | auto* obj = objects[static_cast<u16>(handle >> 15)]; | ||
| 97 | return obj->DynamicCast<T*>(); | ||
| 98 | } | ||
| 99 | |||
| 100 | template <typename T = KAutoObject> | ||
| 101 | KScopedAutoObject<T> GetObject(Handle handle) const { | ||
| 102 | if (handle == CurrentThread) { | ||
| 103 | return kernel.CurrentScheduler()->GetCurrentThread()->DynamicCast<T*>(); | ||
| 104 | } else if (handle == CurrentProcess) { | ||
| 105 | return kernel.CurrentProcess()->DynamicCast<T*>(); | ||
| 106 | } | ||
| 107 | |||
| 108 | if (!IsValid(handle)) { | ||
| 109 | return nullptr; | ||
| 110 | } | ||
| 111 | |||
| 112 | auto* obj = objects[static_cast<u16>(handle >> 15)]; | ||
| 113 | return obj->DynamicCast<T*>(); | ||
| 114 | } | ||
| 115 | |||
| 116 | template <typename T = KAutoObject> | ||
| 117 | KScopedAutoObject<T> GetObjectWithoutPseudoHandle(Handle handle) const { | ||
| 118 | if (!IsValid(handle)) { | ||
| 119 | return nullptr; | ||
| 120 | } | ||
| 121 | auto* obj = objects[static_cast<u16>(handle >> 15)]; | ||
| 122 | return obj->DynamicCast<T*>(); | ||
| 123 | } | ||
| 124 | |||
| 125 | /// Closes all handles held in this table. | ||
| 126 | void Clear(); | ||
| 127 | |||
| 128 | // NEW IMPL | ||
| 129 | |||
| 130 | template <typename T> | ||
| 131 | ResultCode Add(Handle* out_handle, T* obj) { | ||
| 132 | static_assert(std::is_base_of<KAutoObject, T>::value); | ||
| 133 | return this->Add(out_handle, obj, obj->GetTypeObj().GetClassToken()); | ||
| 134 | } | ||
| 135 | |||
| 136 | ResultCode Add(Handle* out_handle, KAutoObject* obj, u16 type); | ||
| 137 | |||
| 138 | template <typename T> | ||
| 139 | bool GetMultipleObjects(T** out, const Handle* handles, size_t num_handles) const { | ||
| 140 | // Try to convert and open all the handles. | ||
| 141 | size_t num_opened; | ||
| 142 | { | ||
| 143 | // Lock the table. | ||
| 144 | KScopedSpinLock lk(lock); | ||
| 145 | for (num_opened = 0; num_opened < num_handles; num_opened++) { | ||
| 146 | // Get the current handle. | ||
| 147 | const auto cur_handle = handles[num_opened]; | ||
| 148 | |||
| 149 | // Get the object for the current handle. | ||
| 150 | KAutoObject* cur_object = this->GetObjectImpl(cur_handle); | ||
| 151 | if (cur_object == nullptr) { | ||
| 152 | break; | ||
| 153 | } | ||
| 154 | |||
| 155 | // Cast the current object to the desired type. | ||
| 156 | T* cur_t = cur_object->DynamicCast<T*>(); | ||
| 157 | if (cur_t == nullptr) { | ||
| 158 | break; | ||
| 159 | } | ||
| 160 | |||
| 161 | // Open a reference to the current object. | ||
| 162 | cur_t->Open(); | ||
| 163 | out[num_opened] = cur_t; | ||
| 164 | } | ||
| 165 | } | ||
| 166 | |||
| 167 | // If we converted every object, succeed. | ||
| 168 | if (num_opened == num_handles) { | ||
| 169 | return true; | ||
| 170 | } | ||
| 171 | |||
| 172 | // If we didn't convert entry object, close the ones we opened. | ||
| 173 | for (size_t i = 0; i < num_opened; i++) { | ||
| 174 | out[i]->Close(); | ||
| 175 | } | ||
| 176 | |||
| 177 | return false; | ||
| 178 | } | ||
| 179 | |||
| 180 | private: | ||
| 181 | /// Stores the Object referenced by the handle or null if the slot is empty. | ||
| 182 | std::array<KAutoObject*, MAX_COUNT> objects{}; | ||
| 183 | |||
| 184 | /** | ||
| 185 | * The value of `next_generation` when the handle was created, used to check for validity. For | ||
| 186 | * empty slots, contains the index of the next free slot in the list. | ||
| 187 | */ | ||
| 188 | std::array<u16, MAX_COUNT> generations; | ||
| 189 | |||
| 190 | /** | ||
| 191 | * The limited size of the handle table. This can be specified by process | ||
| 192 | * capabilities in order to restrict the overall number of handles that | ||
| 193 | * can be created in a process instance | ||
| 194 | */ | ||
| 195 | u16 table_size = static_cast<u16>(MAX_COUNT); | ||
| 196 | |||
| 197 | /** | ||
| 198 | * Global counter of the number of created handles. Stored in `generations` when a handle is | ||
| 199 | * created, and wraps around to 1 when it hits 0x8000. | ||
| 200 | */ | ||
| 201 | u16 next_generation = 1; | ||
| 202 | |||
| 203 | /// Head of the free slots linked list. | ||
| 204 | u16 next_free_slot = 0; | ||
| 205 | |||
| 206 | mutable KSpinLock lock; | ||
| 207 | |||
| 208 | /// Underlying kernel instance that this handle table operates under. | ||
| 209 | KernelCore& kernel; | ||
| 210 | }; | ||
| 211 | |||
| 212 | } // namespace Kernel | ||
diff --git a/src/core/hle/kernel/hle_ipc.cpp b/src/core/hle/kernel/hle_ipc.cpp index 69190286d..b505d20a6 100644 --- a/src/core/hle/kernel/hle_ipc.cpp +++ b/src/core/hle/kernel/hle_ipc.cpp | |||
| @@ -14,8 +14,8 @@ | |||
| 14 | #include "common/common_types.h" | 14 | #include "common/common_types.h" |
| 15 | #include "common/logging/log.h" | 15 | #include "common/logging/log.h" |
| 16 | #include "core/hle/ipc_helpers.h" | 16 | #include "core/hle/ipc_helpers.h" |
| 17 | #include "core/hle/kernel/handle_table.h" | ||
| 18 | #include "core/hle/kernel/hle_ipc.h" | 17 | #include "core/hle/kernel/hle_ipc.h" |
| 18 | #include "core/hle/kernel/k_handle_table.h" | ||
| 19 | #include "core/hle/kernel/k_process.h" | 19 | #include "core/hle/kernel/k_process.h" |
| 20 | #include "core/hle/kernel/k_readable_event.h" | 20 | #include "core/hle/kernel/k_readable_event.h" |
| 21 | #include "core/hle/kernel/k_scheduler.h" | 21 | #include "core/hle/kernel/k_scheduler.h" |
| @@ -50,7 +50,7 @@ HLERequestContext::HLERequestContext(KernelCore& kernel_, Core::Memory::Memory& | |||
| 50 | 50 | ||
| 51 | HLERequestContext::~HLERequestContext() = default; | 51 | HLERequestContext::~HLERequestContext() = default; |
| 52 | 52 | ||
| 53 | void HLERequestContext::ParseCommandBuffer(const HandleTable& handle_table, u32_le* src_cmdbuf, | 53 | void HLERequestContext::ParseCommandBuffer(const KHandleTable& handle_table, u32_le* src_cmdbuf, |
| 54 | bool incoming) { | 54 | bool incoming) { |
| 55 | IPC::RequestParser rp(src_cmdbuf); | 55 | IPC::RequestParser rp(src_cmdbuf); |
| 56 | command_header = rp.PopRaw<IPC::CommandHeader>(); | 56 | command_header = rp.PopRaw<IPC::CommandHeader>(); |
| @@ -163,7 +163,7 @@ void HLERequestContext::ParseCommandBuffer(const HandleTable& handle_table, u32_ | |||
| 163 | rp.Skip(1, false); // The command is actually an u64, but we don't use the high part. | 163 | rp.Skip(1, false); // The command is actually an u64, but we don't use the high part. |
| 164 | } | 164 | } |
| 165 | 165 | ||
| 166 | ResultCode HLERequestContext::PopulateFromIncomingCommandBuffer(const HandleTable& handle_table, | 166 | ResultCode HLERequestContext::PopulateFromIncomingCommandBuffer(const KHandleTable& handle_table, |
| 167 | u32_le* src_cmdbuf) { | 167 | u32_le* src_cmdbuf) { |
| 168 | ParseCommandBuffer(handle_table, src_cmdbuf, true); | 168 | ParseCommandBuffer(handle_table, src_cmdbuf, true); |
| 169 | if (command_header->type == IPC::CommandType::Close) { | 169 | if (command_header->type == IPC::CommandType::Close) { |
diff --git a/src/core/hle/kernel/hle_ipc.h b/src/core/hle/kernel/hle_ipc.h index 4b92ba655..fa031c121 100644 --- a/src/core/hle/kernel/hle_ipc.h +++ b/src/core/hle/kernel/hle_ipc.h | |||
| @@ -17,6 +17,7 @@ | |||
| 17 | #include "common/swap.h" | 17 | #include "common/swap.h" |
| 18 | #include "core/hle/ipc.h" | 18 | #include "core/hle/ipc.h" |
| 19 | #include "core/hle/kernel/k_auto_object.h" | 19 | #include "core/hle/kernel/k_auto_object.h" |
| 20 | #include "core/hle/kernel/svc_common.h" | ||
| 20 | 21 | ||
| 21 | union ResultCode; | 22 | union ResultCode; |
| 22 | 23 | ||
| @@ -35,9 +36,9 @@ class ServiceFrameworkBase; | |||
| 35 | namespace Kernel { | 36 | namespace Kernel { |
| 36 | 37 | ||
| 37 | class Domain; | 38 | class Domain; |
| 38 | class HandleTable; | ||
| 39 | class HLERequestContext; | 39 | class HLERequestContext; |
| 40 | class KernelCore; | 40 | class KernelCore; |
| 41 | class KHandleTable; | ||
| 41 | class KProcess; | 42 | class KProcess; |
| 42 | class KServerSession; | 43 | class KServerSession; |
| 43 | class KThread; | 44 | class KThread; |
| @@ -121,7 +122,7 @@ public: | |||
| 121 | } | 122 | } |
| 122 | 123 | ||
| 123 | /// Populates this context with data from the requesting process/thread. | 124 | /// Populates this context with data from the requesting process/thread. |
| 124 | ResultCode PopulateFromIncomingCommandBuffer(const HandleTable& handle_table, | 125 | ResultCode PopulateFromIncomingCommandBuffer(const KHandleTable& handle_table, |
| 125 | u32_le* src_cmdbuf); | 126 | u32_le* src_cmdbuf); |
| 126 | 127 | ||
| 127 | /// Writes data from this context back to the requesting process/thread. | 128 | /// Writes data from this context back to the requesting process/thread. |
| @@ -267,7 +268,7 @@ public: | |||
| 267 | private: | 268 | private: |
| 268 | friend class IPC::ResponseBuilder; | 269 | friend class IPC::ResponseBuilder; |
| 269 | 270 | ||
| 270 | void ParseCommandBuffer(const HandleTable& handle_table, u32_le* src_cmdbuf, bool incoming); | 271 | void ParseCommandBuffer(const KHandleTable& handle_table, u32_le* src_cmdbuf, bool incoming); |
| 271 | 272 | ||
| 272 | std::array<u32, IPC::COMMAND_BUFFER_LENGTH> cmd_buf; | 273 | std::array<u32, IPC::COMMAND_BUFFER_LENGTH> cmd_buf; |
| 273 | Kernel::KServerSession* server_session{}; | 274 | Kernel::KServerSession* server_session{}; |
diff --git a/src/core/hle/kernel/k_auto_object.h b/src/core/hle/kernel/k_auto_object.h index 5a180b7dc..32aaf9fc5 100644 --- a/src/core/hle/kernel/k_auto_object.h +++ b/src/core/hle/kernel/k_auto_object.h | |||
| @@ -17,8 +17,6 @@ namespace Kernel { | |||
| 17 | class KernelCore; | 17 | class KernelCore; |
| 18 | class KProcess; | 18 | class KProcess; |
| 19 | 19 | ||
| 20 | using Handle = u32; | ||
| 21 | |||
| 22 | #define KERNEL_AUTOOBJECT_TRAITS(CLASS, BASE_CLASS) \ | 20 | #define KERNEL_AUTOOBJECT_TRAITS(CLASS, BASE_CLASS) \ |
| 23 | NON_COPYABLE(CLASS); \ | 21 | NON_COPYABLE(CLASS); \ |
| 24 | NON_MOVEABLE(CLASS); \ | 22 | NON_MOVEABLE(CLASS); \ |
diff --git a/src/core/hle/kernel/k_condition_variable.cpp b/src/core/hle/kernel/k_condition_variable.cpp index a9738f7ce..f51cf3e7b 100644 --- a/src/core/hle/kernel/k_condition_variable.cpp +++ b/src/core/hle/kernel/k_condition_variable.cpp | |||
| @@ -179,7 +179,7 @@ KThread* KConditionVariable::SignalImpl(KThread* thread) { | |||
| 179 | 179 | ||
| 180 | KThread* thread_to_close = nullptr; | 180 | KThread* thread_to_close = nullptr; |
| 181 | if (can_access) { | 181 | if (can_access) { |
| 182 | if (prev_tag == InvalidHandle) { | 182 | if (prev_tag == Svc::InvalidHandle) { |
| 183 | // If nobody held the lock previously, we're all good. | 183 | // If nobody held the lock previously, we're all good. |
| 184 | thread->SetSyncedObject(nullptr, RESULT_SUCCESS); | 184 | thread->SetSyncedObject(nullptr, RESULT_SUCCESS); |
| 185 | thread->Wakeup(); | 185 | thread->Wakeup(); |
diff --git a/src/core/hle/kernel/k_handle_table.cpp b/src/core/hle/kernel/k_handle_table.cpp new file mode 100644 index 000000000..0378447f6 --- /dev/null +++ b/src/core/hle/kernel/k_handle_table.cpp | |||
| @@ -0,0 +1,135 @@ | |||
| 1 | // Copyright 2021 yuzu emulator team | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #include "core/hle/kernel/k_handle_table.h" | ||
| 6 | |||
| 7 | namespace Kernel { | ||
| 8 | |||
| 9 | KHandleTable::KHandleTable(KernelCore& kernel_) : kernel{kernel_} {} | ||
| 10 | KHandleTable ::~KHandleTable() = default; | ||
| 11 | |||
| 12 | ResultCode KHandleTable::Finalize() { | ||
| 13 | // Get the table and clear our record of it. | ||
| 14 | u16 saved_table_size = 0; | ||
| 15 | { | ||
| 16 | KScopedSpinLock lk(m_lock); | ||
| 17 | |||
| 18 | std::swap(m_table_size, saved_table_size); | ||
| 19 | } | ||
| 20 | |||
| 21 | // Close and free all entries. | ||
| 22 | for (size_t i = 0; i < saved_table_size; i++) { | ||
| 23 | if (KAutoObject* obj = m_objects[i]; obj != nullptr) { | ||
| 24 | obj->Close(); | ||
| 25 | } | ||
| 26 | } | ||
| 27 | |||
| 28 | return RESULT_SUCCESS; | ||
| 29 | } | ||
| 30 | |||
| 31 | bool KHandleTable::Remove(Handle handle) { | ||
| 32 | // Don't allow removal of a pseudo-handle. | ||
| 33 | if (Svc::IsPseudoHandle(handle)) { | ||
| 34 | return false; | ||
| 35 | } | ||
| 36 | |||
| 37 | // Handles must not have reserved bits set. | ||
| 38 | const auto handle_pack = HandlePack(handle); | ||
| 39 | if (handle_pack.reserved != 0) { | ||
| 40 | return false; | ||
| 41 | } | ||
| 42 | |||
| 43 | // Find the object and free the entry. | ||
| 44 | KAutoObject* obj = nullptr; | ||
| 45 | { | ||
| 46 | KScopedSpinLock lk(m_lock); | ||
| 47 | |||
| 48 | if (this->IsValidHandle(handle)) { | ||
| 49 | const auto index = handle_pack.index; | ||
| 50 | |||
| 51 | obj = m_objects[index]; | ||
| 52 | this->FreeEntry(index); | ||
| 53 | } else { | ||
| 54 | return false; | ||
| 55 | } | ||
| 56 | } | ||
| 57 | |||
| 58 | // Close the object. | ||
| 59 | obj->Close(); | ||
| 60 | return true; | ||
| 61 | } | ||
| 62 | |||
| 63 | ResultCode KHandleTable::Add(Handle* out_handle, KAutoObject* obj, u16 type) { | ||
| 64 | KScopedSpinLock lk(m_lock); | ||
| 65 | |||
| 66 | // Never exceed our capacity. | ||
| 67 | R_UNLESS(m_count < m_table_size, ResultOutOfHandles); | ||
| 68 | |||
| 69 | // Allocate entry, set output handle. | ||
| 70 | { | ||
| 71 | const auto linear_id = this->AllocateLinearId(); | ||
| 72 | const auto index = this->AllocateEntry(); | ||
| 73 | |||
| 74 | m_entry_infos[index].info = {.linear_id = linear_id, .type = type}; | ||
| 75 | m_objects[index] = obj; | ||
| 76 | |||
| 77 | obj->Open(); | ||
| 78 | |||
| 79 | *out_handle = EncodeHandle(static_cast<u16>(index), linear_id); | ||
| 80 | } | ||
| 81 | |||
| 82 | return RESULT_SUCCESS; | ||
| 83 | } | ||
| 84 | |||
| 85 | ResultCode KHandleTable::Reserve(Handle* out_handle) { | ||
| 86 | KScopedSpinLock lk(m_lock); | ||
| 87 | |||
| 88 | // Never exceed our capacity. | ||
| 89 | R_UNLESS(m_count < m_table_size, ResultOutOfHandles); | ||
| 90 | |||
| 91 | *out_handle = EncodeHandle(static_cast<u16>(this->AllocateEntry()), this->AllocateLinearId()); | ||
| 92 | return RESULT_SUCCESS; | ||
| 93 | } | ||
| 94 | |||
| 95 | void KHandleTable::Unreserve(Handle handle) { | ||
| 96 | KScopedSpinLock lk(m_lock); | ||
| 97 | |||
| 98 | // Unpack the handle. | ||
| 99 | const auto handle_pack = HandlePack(handle); | ||
| 100 | const auto index = handle_pack.index; | ||
| 101 | const auto linear_id = handle_pack.linear_id; | ||
| 102 | const auto reserved = handle_pack.reserved; | ||
| 103 | ASSERT(reserved == 0); | ||
| 104 | ASSERT(linear_id != 0); | ||
| 105 | |||
| 106 | if (index < m_table_size) { | ||
| 107 | // NOTE: This code does not check the linear id. | ||
| 108 | ASSERT(m_objects[index] == nullptr); | ||
| 109 | this->FreeEntry(index); | ||
| 110 | } | ||
| 111 | } | ||
| 112 | |||
| 113 | void KHandleTable::Register(Handle handle, KAutoObject* obj, u16 type) { | ||
| 114 | KScopedSpinLock lk(m_lock); | ||
| 115 | |||
| 116 | // Unpack the handle. | ||
| 117 | const auto handle_pack = HandlePack(handle); | ||
| 118 | const auto index = handle_pack.index; | ||
| 119 | const auto linear_id = handle_pack.linear_id; | ||
| 120 | const auto reserved = handle_pack.reserved; | ||
| 121 | ASSERT(reserved == 0); | ||
| 122 | ASSERT(linear_id != 0); | ||
| 123 | |||
| 124 | if (index < m_table_size) { | ||
| 125 | // Set the entry. | ||
| 126 | ASSERT(m_objects[index] == nullptr); | ||
| 127 | |||
| 128 | m_entry_infos[index].info = {.linear_id = static_cast<u16>(linear_id), .type = type}; | ||
| 129 | m_objects[index] = obj; | ||
| 130 | |||
| 131 | obj->Open(); | ||
| 132 | } | ||
| 133 | } | ||
| 134 | |||
| 135 | } // namespace Kernel | ||
diff --git a/src/core/hle/kernel/k_handle_table.h b/src/core/hle/kernel/k_handle_table.h new file mode 100644 index 000000000..e38ad0fd9 --- /dev/null +++ b/src/core/hle/kernel/k_handle_table.h | |||
| @@ -0,0 +1,309 @@ | |||
| 1 | // Copyright 2021 yuzu emulator team | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #pragma once | ||
| 6 | |||
| 7 | #include <array> | ||
| 8 | |||
| 9 | #include "common/assert.h" | ||
| 10 | #include "common/bit_field.h" | ||
| 11 | #include "common/bit_util.h" | ||
| 12 | #include "common/common_types.h" | ||
| 13 | #include "core/hle/kernel/k_auto_object.h" | ||
| 14 | #include "core/hle/kernel/k_spin_lock.h" | ||
| 15 | #include "core/hle/kernel/k_thread.h" | ||
| 16 | #include "core/hle/kernel/kernel.h" | ||
| 17 | #include "core/hle/kernel/svc_common.h" | ||
| 18 | #include "core/hle/kernel/svc_results.h" | ||
| 19 | #include "core/hle/result.h" | ||
| 20 | |||
| 21 | namespace Kernel { | ||
| 22 | |||
| 23 | class KernelCore; | ||
| 24 | |||
| 25 | class KHandleTable { | ||
| 26 | NON_COPYABLE(KHandleTable); | ||
| 27 | NON_MOVEABLE(KHandleTable); | ||
| 28 | |||
| 29 | public: | ||
| 30 | static constexpr size_t MaxTableSize = 1024; | ||
| 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: | ||
| 80 | explicit KHandleTable(KernelCore& kernel_); | ||
| 81 | ~KHandleTable(); | ||
| 82 | |||
| 83 | constexpr ResultCode Initialize(s32 size) { | ||
| 84 | R_UNLESS(size <= static_cast<s32>(MaxTableSize), ResultOutOfMemory); | ||
| 85 | |||
| 86 | // Initialize all fields. | ||
| 87 | m_max_count = 0; | ||
| 88 | m_table_size = static_cast<u16>((size <= 0) ? MaxTableSize : size); | ||
| 89 | m_next_linear_id = MinLinearId; | ||
| 90 | m_count = 0; | ||
| 91 | m_free_head_index = -1; | ||
| 92 | |||
| 93 | // Free all entries. | ||
| 94 | for (s32 i = 0; i < static_cast<s32>(m_table_size); ++i) { | ||
| 95 | m_objects[i] = nullptr; | ||
| 96 | m_entry_infos[i].next_free_index = i - 1; | ||
| 97 | m_free_head_index = i; | ||
| 98 | } | ||
| 99 | |||
| 100 | return RESULT_SUCCESS; | ||
| 101 | } | ||
| 102 | |||
| 103 | constexpr size_t GetTableSize() const { | ||
| 104 | return m_table_size; | ||
| 105 | } | ||
| 106 | constexpr size_t GetCount() const { | ||
| 107 | return m_count; | ||
| 108 | } | ||
| 109 | constexpr size_t GetMaxCount() const { | ||
| 110 | return m_max_count; | ||
| 111 | } | ||
| 112 | |||
| 113 | ResultCode Finalize(); | ||
| 114 | bool Remove(Handle handle); | ||
| 115 | |||
| 116 | template <typename T = KAutoObject> | ||
| 117 | KScopedAutoObject<T> GetObjectWithoutPseudoHandle(Handle handle) const { | ||
| 118 | // Lock and look up in table. | ||
| 119 | KScopedSpinLock lk(m_lock); | ||
| 120 | |||
| 121 | if constexpr (std::is_same<T, KAutoObject>::value) { | ||
| 122 | return this->GetObjectImpl(handle); | ||
| 123 | } else { | ||
| 124 | if (auto* obj = this->GetObjectImpl(handle); obj != nullptr) { | ||
| 125 | return obj->DynamicCast<T*>(); | ||
| 126 | } else { | ||
| 127 | return nullptr; | ||
| 128 | } | ||
| 129 | } | ||
| 130 | } | ||
| 131 | |||
| 132 | template <typename T = KAutoObject> | ||
| 133 | KScopedAutoObject<T> GetObject(Handle handle) const { | ||
| 134 | // Handle pseudo-handles. | ||
| 135 | if constexpr (std::derived_from<KProcess, T>) { | ||
| 136 | if (handle == Svc::PseudoHandle::CurrentProcess) { | ||
| 137 | auto* const cur_process = kernel.CurrentProcess(); | ||
| 138 | ASSERT(cur_process != nullptr); | ||
| 139 | return cur_process; | ||
| 140 | } | ||
| 141 | } else if constexpr (std::derived_from<KThread, T>) { | ||
| 142 | if (handle == Svc::PseudoHandle::CurrentThread) { | ||
| 143 | auto* const cur_thread = GetCurrentThreadPointer(kernel); | ||
| 144 | ASSERT(cur_thread != nullptr); | ||
| 145 | return cur_thread; | ||
| 146 | } | ||
| 147 | } | ||
| 148 | |||
| 149 | return this->template GetObjectWithoutPseudoHandle<T>(handle); | ||
| 150 | } | ||
| 151 | |||
| 152 | ResultCode Reserve(Handle* out_handle); | ||
| 153 | void Unreserve(Handle handle); | ||
| 154 | |||
| 155 | template <typename T> | ||
| 156 | ResultCode Add(Handle* out_handle, T* obj) { | ||
| 157 | static_assert(std::is_base_of<KAutoObject, T>::value); | ||
| 158 | return this->Add(out_handle, obj, obj->GetTypeObj().GetClassToken()); | ||
| 159 | } | ||
| 160 | |||
| 161 | template <typename T> | ||
| 162 | void Register(Handle handle, T* obj) { | ||
| 163 | static_assert(std::is_base_of<KAutoObject, T>::value); | ||
| 164 | return this->Register(handle, obj, obj->GetTypeObj().GetClassToken()); | ||
| 165 | } | ||
| 166 | |||
| 167 | template <typename T> | ||
| 168 | bool GetMultipleObjects(T** out, const Handle* handles, size_t num_handles) const { | ||
| 169 | // Try to convert and open all the handles. | ||
| 170 | size_t num_opened; | ||
| 171 | { | ||
| 172 | // Lock the table. | ||
| 173 | KScopedSpinLock lk(m_lock); | ||
| 174 | for (num_opened = 0; num_opened < num_handles; num_opened++) { | ||
| 175 | // Get the current handle. | ||
| 176 | const auto cur_handle = handles[num_opened]; | ||
| 177 | |||
| 178 | // Get the object for the current handle. | ||
| 179 | KAutoObject* cur_object = this->GetObjectImpl(cur_handle); | ||
| 180 | if (cur_object == nullptr) { | ||
| 181 | break; | ||
| 182 | } | ||
| 183 | |||
| 184 | // Cast the current object to the desired type. | ||
| 185 | T* cur_t = cur_object->DynamicCast<T*>(); | ||
| 186 | if (cur_t == nullptr) { | ||
| 187 | break; | ||
| 188 | } | ||
| 189 | |||
| 190 | // Open a reference to the current object. | ||
| 191 | cur_t->Open(); | ||
| 192 | out[num_opened] = cur_t; | ||
| 193 | } | ||
| 194 | } | ||
| 195 | |||
| 196 | // If we converted every object, succeed. | ||
| 197 | if (num_opened == num_handles) { | ||
| 198 | return true; | ||
| 199 | } | ||
| 200 | |||
| 201 | // If we didn't convert entry object, close the ones we opened. | ||
| 202 | for (size_t i = 0; i < num_opened; i++) { | ||
| 203 | out[i]->Close(); | ||
| 204 | } | ||
| 205 | |||
| 206 | return false; | ||
| 207 | } | ||
| 208 | |||
| 209 | private: | ||
| 210 | ResultCode Add(Handle* out_handle, KAutoObject* obj, u16 type); | ||
| 211 | void Register(Handle handle, KAutoObject* obj, u16 type); | ||
| 212 | |||
| 213 | constexpr s32 AllocateEntry() { | ||
| 214 | ASSERT(m_count < m_table_size); | ||
| 215 | |||
| 216 | const auto index = m_free_head_index; | ||
| 217 | |||
| 218 | m_free_head_index = m_entry_infos[index].GetNextFreeIndex(); | ||
| 219 | |||
| 220 | m_max_count = std::max(m_max_count, ++m_count); | ||
| 221 | |||
| 222 | return index; | ||
| 223 | } | ||
| 224 | |||
| 225 | constexpr void FreeEntry(s32 index) { | ||
| 226 | ASSERT(m_count > 0); | ||
| 227 | |||
| 228 | m_objects[index] = nullptr; | ||
| 229 | m_entry_infos[index].next_free_index = m_free_head_index; | ||
| 230 | |||
| 231 | m_free_head_index = index; | ||
| 232 | |||
| 233 | --m_count; | ||
| 234 | } | ||
| 235 | |||
| 236 | constexpr u16 AllocateLinearId() { | ||
| 237 | const u16 id = m_next_linear_id++; | ||
| 238 | if (m_next_linear_id > MaxLinearId) { | ||
| 239 | m_next_linear_id = MinLinearId; | ||
| 240 | } | ||
| 241 | return id; | ||
| 242 | } | ||
| 243 | |||
| 244 | constexpr bool IsValidHandle(Handle handle) const { | ||
| 245 | // Unpack the handle. | ||
| 246 | const auto handle_pack = HandlePack(handle); | ||
| 247 | const auto raw_value = handle_pack.raw; | ||
| 248 | const auto index = handle_pack.index; | ||
| 249 | const auto linear_id = handle_pack.linear_id; | ||
| 250 | const auto reserved = handle_pack.reserved; | ||
| 251 | ASSERT(reserved == 0); | ||
| 252 | |||
| 253 | // Validate our indexing information. | ||
| 254 | if (raw_value == 0) { | ||
| 255 | return false; | ||
| 256 | } | ||
| 257 | if (linear_id == 0) { | ||
| 258 | return false; | ||
| 259 | } | ||
| 260 | if (index >= m_table_size) { | ||
| 261 | return false; | ||
| 262 | } | ||
| 263 | |||
| 264 | // Check that there's an object, and our serial id is correct. | ||
| 265 | if (m_objects[index] == nullptr) { | ||
| 266 | return false; | ||
| 267 | } | ||
| 268 | if (m_entry_infos[index].GetLinearId() != linear_id) { | ||
| 269 | return false; | ||
| 270 | } | ||
| 271 | |||
| 272 | return true; | ||
| 273 | } | ||
| 274 | |||
| 275 | constexpr KAutoObject* GetObjectImpl(Handle handle) const { | ||
| 276 | // Handles must not have reserved bits set. | ||
| 277 | const auto handle_pack = HandlePack(handle); | ||
| 278 | if (handle_pack.reserved != 0) { | ||
| 279 | return nullptr; | ||
| 280 | } | ||
| 281 | |||
| 282 | if (this->IsValidHandle(handle)) { | ||
| 283 | return m_objects[handle_pack.index]; | ||
| 284 | } else { | ||
| 285 | return nullptr; | ||
| 286 | } | ||
| 287 | } | ||
| 288 | |||
| 289 | constexpr KAutoObject* GetObjectByIndexImpl(Handle* out_handle, size_t index) const { | ||
| 290 | |||
| 291 | // Index must be in bounds. | ||
| 292 | if (index >= m_table_size) { | ||
| 293 | return nullptr; | ||
| 294 | } | ||
| 295 | |||
| 296 | // Ensure entry has an object. | ||
| 297 | if (KAutoObject* obj = m_objects[index]; obj != nullptr) { | ||
| 298 | *out_handle = EncodeHandle(static_cast<u16>(index), m_entry_infos[index].GetLinearId()); | ||
| 299 | return obj; | ||
| 300 | } else { | ||
| 301 | return nullptr; | ||
| 302 | } | ||
| 303 | } | ||
| 304 | |||
| 305 | private: | ||
| 306 | KernelCore& kernel; | ||
| 307 | }; | ||
| 308 | |||
| 309 | } // namespace Kernel | ||
diff --git a/src/core/hle/kernel/k_process.cpp b/src/core/hle/kernel/k_process.cpp index e542b1f07..174318180 100644 --- a/src/core/hle/kernel/k_process.cpp +++ b/src/core/hle/kernel/k_process.cpp | |||
| @@ -354,7 +354,7 @@ ResultCode KProcess::LoadFromMetadata(const FileSys::ProgramMetadata& metadata, | |||
| 354 | tls_region_address = CreateTLSRegion(); | 354 | tls_region_address = CreateTLSRegion(); |
| 355 | memory_reservation.Commit(); | 355 | memory_reservation.Commit(); |
| 356 | 356 | ||
| 357 | return handle_table.SetSize(capabilities.GetHandleTableSize()); | 357 | return handle_table.Initialize(capabilities.GetHandleTableSize()); |
| 358 | } | 358 | } |
| 359 | 359 | ||
| 360 | void KProcess::Run(s32 main_thread_priority, u64 stack_size) { | 360 | void KProcess::Run(s32 main_thread_priority, u64 stack_size) { |
diff --git a/src/core/hle/kernel/k_process.h b/src/core/hle/kernel/k_process.h index 5c54c6360..62ab26b05 100644 --- a/src/core/hle/kernel/k_process.h +++ b/src/core/hle/kernel/k_process.h | |||
| @@ -11,10 +11,10 @@ | |||
| 11 | #include <unordered_map> | 11 | #include <unordered_map> |
| 12 | #include <vector> | 12 | #include <vector> |
| 13 | #include "common/common_types.h" | 13 | #include "common/common_types.h" |
| 14 | #include "core/hle/kernel/handle_table.h" | ||
| 15 | #include "core/hle/kernel/k_address_arbiter.h" | 14 | #include "core/hle/kernel/k_address_arbiter.h" |
| 16 | #include "core/hle/kernel/k_auto_object.h" | 15 | #include "core/hle/kernel/k_auto_object.h" |
| 17 | #include "core/hle/kernel/k_condition_variable.h" | 16 | #include "core/hle/kernel/k_condition_variable.h" |
| 17 | #include "core/hle/kernel/k_handle_table.h" | ||
| 18 | #include "core/hle/kernel/k_synchronization_object.h" | 18 | #include "core/hle/kernel/k_synchronization_object.h" |
| 19 | #include "core/hle/kernel/process_capability.h" | 19 | #include "core/hle/kernel/process_capability.h" |
| 20 | #include "core/hle/kernel/slab_helpers.h" | 20 | #include "core/hle/kernel/slab_helpers.h" |
| @@ -104,12 +104,12 @@ public: | |||
| 104 | } | 104 | } |
| 105 | 105 | ||
| 106 | /// Gets a reference to the process' handle table. | 106 | /// Gets a reference to the process' handle table. |
| 107 | HandleTable& GetHandleTable() { | 107 | KHandleTable& GetHandleTable() { |
| 108 | return handle_table; | 108 | return handle_table; |
| 109 | } | 109 | } |
| 110 | 110 | ||
| 111 | /// Gets a const reference to the process' handle table. | 111 | /// Gets a const reference to the process' handle table. |
| 112 | const HandleTable& GetHandleTable() const { | 112 | const KHandleTable& GetHandleTable() const { |
| 113 | return handle_table; | 113 | return handle_table; |
| 114 | } | 114 | } |
| 115 | 115 | ||
| @@ -429,7 +429,7 @@ private: | |||
| 429 | u64 total_process_running_time_ticks = 0; | 429 | u64 total_process_running_time_ticks = 0; |
| 430 | 430 | ||
| 431 | /// Per-process handle table for storing created object handles in. | 431 | /// Per-process handle table for storing created object handles in. |
| 432 | HandleTable handle_table; | 432 | KHandleTable handle_table; |
| 433 | 433 | ||
| 434 | /// Per-process address arbiter. | 434 | /// Per-process address arbiter. |
| 435 | KAddressArbiter address_arbiter; | 435 | KAddressArbiter address_arbiter; |
diff --git a/src/core/hle/kernel/k_scoped_scheduler_lock_and_sleep.h b/src/core/hle/kernel/k_scoped_scheduler_lock_and_sleep.h index ebecf0c77..1bfbbcfe2 100644 --- a/src/core/hle/kernel/k_scoped_scheduler_lock_and_sleep.h +++ b/src/core/hle/kernel/k_scoped_scheduler_lock_and_sleep.h | |||
| @@ -8,7 +8,7 @@ | |||
| 8 | #pragma once | 8 | #pragma once |
| 9 | 9 | ||
| 10 | #include "common/common_types.h" | 10 | #include "common/common_types.h" |
| 11 | #include "core/hle/kernel/handle_table.h" | 11 | #include "core/hle/kernel/k_handle_table.h" |
| 12 | #include "core/hle/kernel/k_thread.h" | 12 | #include "core/hle/kernel/k_thread.h" |
| 13 | #include "core/hle/kernel/kernel.h" | 13 | #include "core/hle/kernel/kernel.h" |
| 14 | #include "core/hle/kernel/time_manager.h" | 14 | #include "core/hle/kernel/time_manager.h" |
| @@ -17,7 +17,7 @@ namespace Kernel { | |||
| 17 | 17 | ||
| 18 | class [[nodiscard]] KScopedSchedulerLockAndSleep { | 18 | class [[nodiscard]] KScopedSchedulerLockAndSleep { |
| 19 | public: | 19 | public: |
| 20 | explicit KScopedSchedulerLockAndSleep(KernelCore & kernel, KThread * t, s64 timeout) | 20 | explicit KScopedSchedulerLockAndSleep(KernelCore& kernel, KThread* t, s64 timeout) |
| 21 | : kernel(kernel), thread(t), timeout_tick(timeout) { | 21 | : kernel(kernel), thread(t), timeout_tick(timeout) { |
| 22 | // Lock the scheduler. | 22 | // Lock the scheduler. |
| 23 | kernel.GlobalSchedulerContext().scheduler_lock.Lock(); | 23 | kernel.GlobalSchedulerContext().scheduler_lock.Lock(); |
diff --git a/src/core/hle/kernel/k_server_session.cpp b/src/core/hle/kernel/k_server_session.cpp index 3bc259693..c8acaa453 100644 --- a/src/core/hle/kernel/k_server_session.cpp +++ b/src/core/hle/kernel/k_server_session.cpp | |||
| @@ -10,9 +10,9 @@ | |||
| 10 | #include "common/logging/log.h" | 10 | #include "common/logging/log.h" |
| 11 | #include "core/core_timing.h" | 11 | #include "core/core_timing.h" |
| 12 | #include "core/hle/ipc_helpers.h" | 12 | #include "core/hle/ipc_helpers.h" |
| 13 | #include "core/hle/kernel/handle_table.h" | ||
| 14 | #include "core/hle/kernel/hle_ipc.h" | 13 | #include "core/hle/kernel/hle_ipc.h" |
| 15 | #include "core/hle/kernel/k_client_port.h" | 14 | #include "core/hle/kernel/k_client_port.h" |
| 15 | #include "core/hle/kernel/k_handle_table.h" | ||
| 16 | #include "core/hle/kernel/k_process.h" | 16 | #include "core/hle/kernel/k_process.h" |
| 17 | #include "core/hle/kernel/k_scheduler.h" | 17 | #include "core/hle/kernel/k_scheduler.h" |
| 18 | #include "core/hle/kernel/k_server_session.h" | 18 | #include "core/hle/kernel/k_server_session.h" |
diff --git a/src/core/hle/kernel/k_thread.cpp b/src/core/hle/kernel/k_thread.cpp index 3de0157ac..ef6dfeeca 100644 --- a/src/core/hle/kernel/k_thread.cpp +++ b/src/core/hle/kernel/k_thread.cpp | |||
| @@ -18,8 +18,8 @@ | |||
| 18 | #include "core/core.h" | 18 | #include "core/core.h" |
| 19 | #include "core/cpu_manager.h" | 19 | #include "core/cpu_manager.h" |
| 20 | #include "core/hardware_properties.h" | 20 | #include "core/hardware_properties.h" |
| 21 | #include "core/hle/kernel/handle_table.h" | ||
| 22 | #include "core/hle/kernel/k_condition_variable.h" | 21 | #include "core/hle/kernel/k_condition_variable.h" |
| 22 | #include "core/hle/kernel/k_handle_table.h" | ||
| 23 | #include "core/hle/kernel/k_memory_layout.h" | 23 | #include "core/hle/kernel/k_memory_layout.h" |
| 24 | #include "core/hle/kernel/k_process.h" | 24 | #include "core/hle/kernel/k_process.h" |
| 25 | #include "core/hle/kernel/k_resource_limit.h" | 25 | #include "core/hle/kernel/k_resource_limit.h" |
diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp index f64e07081..825fab694 100644 --- a/src/core/hle/kernel/kernel.cpp +++ b/src/core/hle/kernel/kernel.cpp | |||
| @@ -26,9 +26,9 @@ | |||
| 26 | #include "core/cpu_manager.h" | 26 | #include "core/cpu_manager.h" |
| 27 | #include "core/device_memory.h" | 27 | #include "core/device_memory.h" |
| 28 | #include "core/hardware_properties.h" | 28 | #include "core/hardware_properties.h" |
| 29 | #include "core/hle/kernel/handle_table.h" | ||
| 30 | #include "core/hle/kernel/init/init_slab_setup.h" | 29 | #include "core/hle/kernel/init/init_slab_setup.h" |
| 31 | #include "core/hle/kernel/k_client_port.h" | 30 | #include "core/hle/kernel/k_client_port.h" |
| 31 | #include "core/hle/kernel/k_handle_table.h" | ||
| 32 | #include "core/hle/kernel/k_memory_layout.h" | 32 | #include "core/hle/kernel/k_memory_layout.h" |
| 33 | #include "core/hle/kernel/k_memory_manager.h" | 33 | #include "core/hle/kernel/k_memory_manager.h" |
| 34 | #include "core/hle/kernel/k_process.h" | 34 | #include "core/hle/kernel/k_process.h" |
| @@ -52,8 +52,7 @@ namespace Kernel { | |||
| 52 | 52 | ||
| 53 | struct KernelCore::Impl { | 53 | struct KernelCore::Impl { |
| 54 | explicit Impl(Core::System& system, KernelCore& kernel) | 54 | explicit Impl(Core::System& system, KernelCore& kernel) |
| 55 | : time_manager{system}, global_handle_table{kernel}, | 55 | : time_manager{system}, object_list_container{kernel}, system{system} {} |
| 56 | object_list_container{kernel}, system{system} {} | ||
| 57 | 56 | ||
| 58 | void SetMulticore(bool is_multicore) { | 57 | void SetMulticore(bool is_multicore) { |
| 59 | this->is_multicore = is_multicore; | 58 | this->is_multicore = is_multicore; |
| @@ -61,6 +60,7 @@ struct KernelCore::Impl { | |||
| 61 | 60 | ||
| 62 | void Initialize(KernelCore& kernel) { | 61 | void Initialize(KernelCore& kernel) { |
| 63 | global_scheduler_context = std::make_unique<Kernel::GlobalSchedulerContext>(kernel); | 62 | global_scheduler_context = std::make_unique<Kernel::GlobalSchedulerContext>(kernel); |
| 63 | global_handle_table = std::make_unique<Kernel::KHandleTable>(kernel); | ||
| 64 | 64 | ||
| 65 | service_thread_manager = | 65 | service_thread_manager = |
| 66 | std::make_unique<Common::ThreadWorker>(1, "yuzu:ServiceThreadManager"); | 66 | std::make_unique<Common::ThreadWorker>(1, "yuzu:ServiceThreadManager"); |
| @@ -118,7 +118,7 @@ struct KernelCore::Impl { | |||
| 118 | current_process = nullptr; | 118 | current_process = nullptr; |
| 119 | } | 119 | } |
| 120 | 120 | ||
| 121 | global_handle_table.Clear(); | 121 | global_handle_table.reset(); |
| 122 | 122 | ||
| 123 | preemption_event = nullptr; | 123 | preemption_event = nullptr; |
| 124 | 124 | ||
| @@ -648,7 +648,7 @@ struct KernelCore::Impl { | |||
| 648 | 648 | ||
| 649 | // This is the kernel's handle table or supervisor handle table which | 649 | // This is the kernel's handle table or supervisor handle table which |
| 650 | // stores all the objects in place. | 650 | // stores all the objects in place. |
| 651 | HandleTable global_handle_table; | 651 | std::unique_ptr<KHandleTable> global_handle_table; |
| 652 | 652 | ||
| 653 | KAutoObjectWithListContainer object_list_container; | 653 | KAutoObjectWithListContainer object_list_container; |
| 654 | 654 | ||
| @@ -722,7 +722,7 @@ KResourceLimit* KernelCore::GetSystemResourceLimit() { | |||
| 722 | } | 722 | } |
| 723 | 723 | ||
| 724 | KScopedAutoObject<KThread> KernelCore::RetrieveThreadFromGlobalHandleTable(Handle handle) const { | 724 | KScopedAutoObject<KThread> KernelCore::RetrieveThreadFromGlobalHandleTable(Handle handle) const { |
| 725 | return impl->global_handle_table.GetObject<KThread>(handle); | 725 | return impl->global_handle_table->GetObject<KThread>(handle); |
| 726 | } | 726 | } |
| 727 | 727 | ||
| 728 | void KernelCore::AppendNewProcess(KProcess* process) { | 728 | void KernelCore::AppendNewProcess(KProcess* process) { |
| @@ -876,12 +876,12 @@ u64 KernelCore::CreateNewUserProcessID() { | |||
| 876 | return impl->next_user_process_id++; | 876 | return impl->next_user_process_id++; |
| 877 | } | 877 | } |
| 878 | 878 | ||
| 879 | Kernel::HandleTable& KernelCore::GlobalHandleTable() { | 879 | KHandleTable& KernelCore::GlobalHandleTable() { |
| 880 | return impl->global_handle_table; | 880 | return *impl->global_handle_table; |
| 881 | } | 881 | } |
| 882 | 882 | ||
| 883 | const Kernel::HandleTable& KernelCore::GlobalHandleTable() const { | 883 | const KHandleTable& KernelCore::GlobalHandleTable() const { |
| 884 | return impl->global_handle_table; | 884 | return *impl->global_handle_table; |
| 885 | } | 885 | } |
| 886 | 886 | ||
| 887 | void KernelCore::RegisterCoreThread(std::size_t core_id) { | 887 | void KernelCore::RegisterCoreThread(std::size_t core_id) { |
diff --git a/src/core/hle/kernel/kernel.h b/src/core/hle/kernel/kernel.h index 0dd9deaeb..7c46aa997 100644 --- a/src/core/hle/kernel/kernel.h +++ b/src/core/hle/kernel/kernel.h | |||
| @@ -14,6 +14,7 @@ | |||
| 14 | #include "core/hle/kernel/k_auto_object.h" | 14 | #include "core/hle/kernel/k_auto_object.h" |
| 15 | #include "core/hle/kernel/k_slab_heap.h" | 15 | #include "core/hle/kernel/k_slab_heap.h" |
| 16 | #include "core/hle/kernel/memory_types.h" | 16 | #include "core/hle/kernel/memory_types.h" |
| 17 | #include "core/hle/kernel/svc_common.h" | ||
| 17 | 18 | ||
| 18 | namespace Core { | 19 | namespace Core { |
| 19 | class CPUInterruptHandler; | 20 | class CPUInterruptHandler; |
| @@ -30,10 +31,10 @@ namespace Kernel { | |||
| 30 | 31 | ||
| 31 | class KClientPort; | 32 | class KClientPort; |
| 32 | class GlobalSchedulerContext; | 33 | class GlobalSchedulerContext; |
| 33 | class HandleTable; | ||
| 34 | class KAutoObjectWithListContainer; | 34 | class KAutoObjectWithListContainer; |
| 35 | class KClientSession; | 35 | class KClientSession; |
| 36 | class KEvent; | 36 | class KEvent; |
| 37 | class KHandleTable; | ||
| 37 | class KLinkedListNode; | 38 | class KLinkedListNode; |
| 38 | class KMemoryManager; | 39 | class KMemoryManager; |
| 39 | class KPort; | 40 | class KPort; |
| @@ -308,10 +309,10 @@ private: | |||
| 308 | u64 CreateNewThreadID(); | 309 | u64 CreateNewThreadID(); |
| 309 | 310 | ||
| 310 | /// Provides a reference to the global handle table. | 311 | /// Provides a reference to the global handle table. |
| 311 | Kernel::HandleTable& GlobalHandleTable(); | 312 | KHandleTable& GlobalHandleTable(); |
| 312 | 313 | ||
| 313 | /// Provides a const reference to the global handle table. | 314 | /// Provides a const reference to the global handle table. |
| 314 | const Kernel::HandleTable& GlobalHandleTable() const; | 315 | const KHandleTable& GlobalHandleTable() const; |
| 315 | 316 | ||
| 316 | struct Impl; | 317 | struct Impl; |
| 317 | std::unique_ptr<Impl> impl; | 318 | std::unique_ptr<Impl> impl; |
diff --git a/src/core/hle/kernel/process_capability.cpp b/src/core/hle/kernel/process_capability.cpp index 4ccac0b06..fcb8b1ea5 100644 --- a/src/core/hle/kernel/process_capability.cpp +++ b/src/core/hle/kernel/process_capability.cpp | |||
| @@ -6,7 +6,7 @@ | |||
| 6 | 6 | ||
| 7 | #include "common/bit_util.h" | 7 | #include "common/bit_util.h" |
| 8 | #include "common/logging/log.h" | 8 | #include "common/logging/log.h" |
| 9 | #include "core/hle/kernel/handle_table.h" | 9 | #include "core/hle/kernel/k_handle_table.h" |
| 10 | #include "core/hle/kernel/k_page_table.h" | 10 | #include "core/hle/kernel/k_page_table.h" |
| 11 | #include "core/hle/kernel/process_capability.h" | 11 | #include "core/hle/kernel/process_capability.h" |
| 12 | #include "core/hle/kernel/svc_results.h" | 12 | #include "core/hle/kernel/svc_results.h" |
| @@ -99,7 +99,7 @@ void ProcessCapabilities::InitializeForMetadatalessProcess() { | |||
| 99 | interrupt_capabilities.set(); | 99 | interrupt_capabilities.set(); |
| 100 | 100 | ||
| 101 | // Allow using the maximum possible amount of handles | 101 | // Allow using the maximum possible amount of handles |
| 102 | handle_table_size = static_cast<s32>(HandleTable::MAX_COUNT); | 102 | handle_table_size = static_cast<s32>(KHandleTable::MaxTableSize); |
| 103 | 103 | ||
| 104 | // Allow all debugging capabilities. | 104 | // Allow all debugging capabilities. |
| 105 | is_debuggable = true; | 105 | is_debuggable = true; |
diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp index 156c565b0..d3293a1fe 100644 --- a/src/core/hle/kernel/svc.cpp +++ b/src/core/hle/kernel/svc.cpp | |||
| @@ -21,12 +21,12 @@ | |||
| 21 | #include "core/core_timing.h" | 21 | #include "core/core_timing.h" |
| 22 | #include "core/core_timing_util.h" | 22 | #include "core/core_timing_util.h" |
| 23 | #include "core/cpu_manager.h" | 23 | #include "core/cpu_manager.h" |
| 24 | #include "core/hle/kernel/handle_table.h" | ||
| 25 | #include "core/hle/kernel/k_address_arbiter.h" | 24 | #include "core/hle/kernel/k_address_arbiter.h" |
| 26 | #include "core/hle/kernel/k_client_port.h" | 25 | #include "core/hle/kernel/k_client_port.h" |
| 27 | #include "core/hle/kernel/k_client_session.h" | 26 | #include "core/hle/kernel/k_client_session.h" |
| 28 | #include "core/hle/kernel/k_condition_variable.h" | 27 | #include "core/hle/kernel/k_condition_variable.h" |
| 29 | #include "core/hle/kernel/k_event.h" | 28 | #include "core/hle/kernel/k_event.h" |
| 29 | #include "core/hle/kernel/k_handle_table.h" | ||
| 30 | #include "core/hle/kernel/k_memory_block.h" | 30 | #include "core/hle/kernel/k_memory_block.h" |
| 31 | #include "core/hle/kernel/k_memory_layout.h" | 31 | #include "core/hle/kernel/k_memory_layout.h" |
| 32 | #include "core/hle/kernel/k_page_table.h" | 32 | #include "core/hle/kernel/k_page_table.h" |
| @@ -839,10 +839,10 @@ static ResultCode GetInfo(Core::System& system, u64* result, u64 info_id, Handle | |||
| 839 | } | 839 | } |
| 840 | 840 | ||
| 841 | KProcess* const current_process = system.Kernel().CurrentProcess(); | 841 | KProcess* const current_process = system.Kernel().CurrentProcess(); |
| 842 | HandleTable& handle_table = current_process->GetHandleTable(); | 842 | KHandleTable& handle_table = current_process->GetHandleTable(); |
| 843 | const auto resource_limit = current_process->GetResourceLimit(); | 843 | const auto resource_limit = current_process->GetResourceLimit(); |
| 844 | if (!resource_limit) { | 844 | if (!resource_limit) { |
| 845 | *result = KernelHandle::InvalidHandle; | 845 | *result = Svc::InvalidHandle; |
| 846 | // Yes, the kernel considers this a successful operation. | 846 | // Yes, the kernel considers this a successful operation. |
| 847 | return RESULT_SUCCESS; | 847 | return RESULT_SUCCESS; |
| 848 | } | 848 | } |
| @@ -1993,7 +1993,7 @@ static ResultCode SignalEvent(Core::System& system, Handle event_handle) { | |||
| 1993 | LOG_DEBUG(Kernel_SVC, "called, event_handle=0x{:08X}", event_handle); | 1993 | LOG_DEBUG(Kernel_SVC, "called, event_handle=0x{:08X}", event_handle); |
| 1994 | 1994 | ||
| 1995 | // Get the current handle table. | 1995 | // Get the current handle table. |
| 1996 | const HandleTable& handle_table = system.Kernel().CurrentProcess()->GetHandleTable(); | 1996 | const KHandleTable& handle_table = system.Kernel().CurrentProcess()->GetHandleTable(); |
| 1997 | 1997 | ||
| 1998 | // Get the writable event. | 1998 | // Get the writable event. |
| 1999 | KScopedAutoObject writable_event = handle_table.GetObject<KWritableEvent>(event_handle); | 1999 | KScopedAutoObject writable_event = handle_table.GetObject<KWritableEvent>(event_handle); |
diff --git a/src/core/hle/kernel/svc_common.h b/src/core/hle/kernel/svc_common.h index 4af049551..8a8f347b5 100644 --- a/src/core/hle/kernel/svc_common.h +++ b/src/core/hle/kernel/svc_common.h | |||
| @@ -6,9 +6,24 @@ | |||
| 6 | 6 | ||
| 7 | #include "common/common_types.h" | 7 | #include "common/common_types.h" |
| 8 | 8 | ||
| 9 | namespace Kernel { | ||
| 10 | using Handle = u32; | ||
| 11 | } | ||
| 12 | |||
| 9 | namespace Kernel::Svc { | 13 | namespace Kernel::Svc { |
| 10 | 14 | ||
| 11 | constexpr s32 ArgumentHandleCountMax = 0x40; | 15 | constexpr s32 ArgumentHandleCountMax = 0x40; |
| 12 | constexpr u32 HandleWaitMask{1u << 30}; | 16 | constexpr u32 HandleWaitMask{1u << 30}; |
| 13 | 17 | ||
| 18 | constexpr inline Handle InvalidHandle = Handle(0); | ||
| 19 | |||
| 20 | enum PseudoHandle : Handle { | ||
| 21 | CurrentThread = 0xFFFF8000, | ||
| 22 | CurrentProcess = 0xFFFF8001, | ||
| 23 | }; | ||
| 24 | |||
| 25 | constexpr bool IsPseudoHandle(const Handle& handle) { | ||
| 26 | return handle == PseudoHandle::CurrentProcess || handle == PseudoHandle::CurrentThread; | ||
| 27 | } | ||
| 28 | |||
| 14 | } // namespace Kernel::Svc | 29 | } // namespace Kernel::Svc |
diff --git a/src/core/hle/kernel/time_manager.cpp b/src/core/hle/kernel/time_manager.cpp index 59ebfc51f..ae9b4be2f 100644 --- a/src/core/hle/kernel/time_manager.cpp +++ b/src/core/hle/kernel/time_manager.cpp | |||
| @@ -6,7 +6,6 @@ | |||
| 6 | #include "core/core.h" | 6 | #include "core/core.h" |
| 7 | #include "core/core_timing.h" | 7 | #include "core/core_timing.h" |
| 8 | #include "core/core_timing_util.h" | 8 | #include "core/core_timing_util.h" |
| 9 | #include "core/hle/kernel/handle_table.h" | ||
| 10 | #include "core/hle/kernel/k_scheduler.h" | 9 | #include "core/hle/kernel/k_scheduler.h" |
| 11 | #include "core/hle/kernel/k_thread.h" | 10 | #include "core/hle/kernel/k_thread.h" |
| 12 | #include "core/hle/kernel/kernel.h" | 11 | #include "core/hle/kernel/kernel.h" |
diff --git a/src/yuzu/debugger/wait_tree.cpp b/src/yuzu/debugger/wait_tree.cpp index f040b4c08..bdfda6c54 100644 --- a/src/yuzu/debugger/wait_tree.cpp +++ b/src/yuzu/debugger/wait_tree.cpp | |||
| @@ -12,8 +12,8 @@ | |||
| 12 | #include "common/assert.h" | 12 | #include "common/assert.h" |
| 13 | #include "core/arm/arm_interface.h" | 13 | #include "core/arm/arm_interface.h" |
| 14 | #include "core/core.h" | 14 | #include "core/core.h" |
| 15 | #include "core/hle/kernel/handle_table.h" | ||
| 16 | #include "core/hle/kernel/k_class_token.h" | 15 | #include "core/hle/kernel/k_class_token.h" |
| 16 | #include "core/hle/kernel/k_handle_table.h" | ||
| 17 | #include "core/hle/kernel/k_process.h" | 17 | #include "core/hle/kernel/k_process.h" |
| 18 | #include "core/hle/kernel/k_readable_event.h" | 18 | #include "core/hle/kernel/k_readable_event.h" |
| 19 | #include "core/hle/kernel/k_scheduler.h" | 19 | #include "core/hle/kernel/k_scheduler.h" |
| @@ -115,7 +115,7 @@ QString WaitTreeText::GetText() const { | |||
| 115 | return text; | 115 | return text; |
| 116 | } | 116 | } |
| 117 | 117 | ||
| 118 | WaitTreeMutexInfo::WaitTreeMutexInfo(VAddr mutex_address, const Kernel::HandleTable& handle_table) | 118 | WaitTreeMutexInfo::WaitTreeMutexInfo(VAddr mutex_address, const Kernel::KHandleTable& handle_table) |
| 119 | : mutex_address(mutex_address) { | 119 | : mutex_address(mutex_address) { |
| 120 | mutex_value = Core::System::GetInstance().Memory().Read32(mutex_address); | 120 | mutex_value = Core::System::GetInstance().Memory().Read32(mutex_address); |
| 121 | owner_handle = static_cast<Kernel::Handle>(mutex_value & Kernel::Svc::HandleWaitMask); | 121 | owner_handle = static_cast<Kernel::Handle>(mutex_value & Kernel::Svc::HandleWaitMask); |
diff --git a/src/yuzu/debugger/wait_tree.h b/src/yuzu/debugger/wait_tree.h index 3dd4acab0..d450345df 100644 --- a/src/yuzu/debugger/wait_tree.h +++ b/src/yuzu/debugger/wait_tree.h | |||
| @@ -14,11 +14,12 @@ | |||
| 14 | 14 | ||
| 15 | #include "common/common_types.h" | 15 | #include "common/common_types.h" |
| 16 | #include "core/hle/kernel/k_auto_object.h" | 16 | #include "core/hle/kernel/k_auto_object.h" |
| 17 | #include "core/hle/kernel/svc_common.h" | ||
| 17 | 18 | ||
| 18 | class EmuThread; | 19 | class EmuThread; |
| 19 | 20 | ||
| 20 | namespace Kernel { | 21 | namespace Kernel { |
| 21 | class HandleTable; | 22 | class KHandleTable; |
| 22 | class KReadableEvent; | 23 | class KReadableEvent; |
| 23 | class KSynchronizationObject; | 24 | class KSynchronizationObject; |
| 24 | class KThread; | 25 | class KThread; |
| @@ -74,7 +75,7 @@ public: | |||
| 74 | class WaitTreeMutexInfo : public WaitTreeExpandableItem { | 75 | class WaitTreeMutexInfo : public WaitTreeExpandableItem { |
| 75 | Q_OBJECT | 76 | Q_OBJECT |
| 76 | public: | 77 | public: |
| 77 | explicit WaitTreeMutexInfo(VAddr mutex_address, const Kernel::HandleTable& handle_table); | 78 | explicit WaitTreeMutexInfo(VAddr mutex_address, const Kernel::KHandleTable& handle_table); |
| 78 | ~WaitTreeMutexInfo() override; | 79 | ~WaitTreeMutexInfo() override; |
| 79 | 80 | ||
| 80 | QString GetText() const override; | 81 | QString GetText() const override; |