diff options
| author | 2017-05-29 16:45:42 -0700 | |
|---|---|---|
| committer | 2017-05-29 17:34:39 -0700 | |
| commit | be031989ee9384786fb9ed380dab9a260ad69fd5 (patch) | |
| tree | 875d7725802afed2849be9ca6947f129b0b60134 /src/core/hle/kernel/kernel.h | |
| parent | Kernel: Move WaitObject to a separate file (diff) | |
| download | yuzu-be031989ee9384786fb9ed380dab9a260ad69fd5.tar.gz yuzu-be031989ee9384786fb9ed380dab9a260ad69fd5.tar.xz yuzu-be031989ee9384786fb9ed380dab9a260ad69fd5.zip | |
Kernel: Move HandleTable to a separate file
Diffstat (limited to 'src/core/hle/kernel/kernel.h')
| -rw-r--r-- | src/core/hle/kernel/kernel.h | 116 |
1 files changed, 1 insertions, 115 deletions
diff --git a/src/core/hle/kernel/kernel.h b/src/core/hle/kernel/kernel.h index 5335a961d..9cf288b08 100644 --- a/src/core/hle/kernel/kernel.h +++ b/src/core/hle/kernel/kernel.h | |||
| @@ -4,24 +4,16 @@ | |||
| 4 | 4 | ||
| 5 | #pragma once | 5 | #pragma once |
| 6 | 6 | ||
| 7 | #include <algorithm> | ||
| 8 | #include <array> | ||
| 9 | #include <cstddef> | 7 | #include <cstddef> |
| 10 | #include <string> | 8 | #include <string> |
| 11 | #include <vector> | 9 | #include <utility> |
| 12 | #include <boost/smart_ptr/intrusive_ptr.hpp> | 10 | #include <boost/smart_ptr/intrusive_ptr.hpp> |
| 13 | #include "common/common_types.h" | 11 | #include "common/common_types.h" |
| 14 | #include "core/hle/result.h" | ||
| 15 | 12 | ||
| 16 | namespace Kernel { | 13 | namespace Kernel { |
| 17 | 14 | ||
| 18 | using Handle = u32; | 15 | using Handle = u32; |
| 19 | 16 | ||
| 20 | enum KernelHandle : Handle { | ||
| 21 | CurrentThread = 0xFFFF8000, | ||
| 22 | CurrentProcess = 0xFFFF8001, | ||
| 23 | }; | ||
| 24 | |||
| 25 | enum class HandleType : u32 { | 17 | enum class HandleType : u32 { |
| 26 | Unknown, | 18 | Unknown, |
| 27 | Event, | 19 | Event, |
| @@ -131,112 +123,6 @@ inline SharedPtr<T> DynamicObjectCast(SharedPtr<Object> object) { | |||
| 131 | return nullptr; | 123 | return nullptr; |
| 132 | } | 124 | } |
| 133 | 125 | ||
| 134 | /** | ||
| 135 | * This class allows the creation of Handles, which are references to objects that can be tested | ||
| 136 | * for validity and looked up. Here they are used to pass references to kernel objects to/from the | ||
| 137 | * emulated process. it has been designed so that it follows the same handle format and has | ||
| 138 | * approximately the same restrictions as the handle manager in the CTR-OS. | ||
| 139 | * | ||
| 140 | * Handles contain two sub-fields: a slot index (bits 31:15) and a generation value (bits 14:0). | ||
| 141 | * The slot index is used to index into the arrays in this class to access the data corresponding | ||
| 142 | * to the Handle. | ||
| 143 | * | ||
| 144 | * To prevent accidental use of a freed Handle whose slot has already been reused, a global counter | ||
| 145 | * is kept and incremented every time a Handle is created. This is the Handle's "generation". The | ||
| 146 | * value of the counter is stored into the Handle as well as in the handle table (in the | ||
| 147 | * "generations" array). When looking up a handle, the Handle's generation must match with the | ||
| 148 | * value stored on the class, otherwise the Handle is considered invalid. | ||
| 149 | * | ||
| 150 | * To find free slots when allocating a Handle without needing to scan the entire object array, the | ||
| 151 | * generations field of unallocated slots is re-purposed as a linked list of indices to free slots. | ||
| 152 | * When a Handle is created, an index is popped off the list and used for the new Handle. When it | ||
| 153 | * is destroyed, it is again pushed onto the list to be re-used by the next allocation. It is | ||
| 154 | * likely that this allocation strategy differs from the one used in CTR-OS, but this hasn't been | ||
| 155 | * verified and isn't likely to cause any problems. | ||
| 156 | */ | ||
| 157 | class HandleTable final : NonCopyable { | ||
| 158 | public: | ||
| 159 | HandleTable(); | ||
| 160 | |||
| 161 | /** | ||
| 162 | * Allocates a handle for the given object. | ||
| 163 | * @return The created Handle or one of the following errors: | ||
| 164 | * - `ERR_OUT_OF_HANDLES`: the maximum number of handles has been exceeded. | ||
| 165 | */ | ||
| 166 | ResultVal<Handle> Create(SharedPtr<Object> obj); | ||
| 167 | |||
| 168 | /** | ||
| 169 | * Returns a new handle that points to the same object as the passed in handle. | ||
| 170 | * @return The duplicated Handle or one of the following errors: | ||
| 171 | * - `ERR_INVALID_HANDLE`: an invalid handle was passed in. | ||
| 172 | * - Any errors returned by `Create()`. | ||
| 173 | */ | ||
| 174 | ResultVal<Handle> Duplicate(Handle handle); | ||
| 175 | |||
| 176 | /** | ||
| 177 | * Closes a handle, removing it from the table and decreasing the object's ref-count. | ||
| 178 | * @return `RESULT_SUCCESS` or one of the following errors: | ||
| 179 | * - `ERR_INVALID_HANDLE`: an invalid handle was passed in. | ||
| 180 | */ | ||
| 181 | ResultCode Close(Handle handle); | ||
| 182 | |||
| 183 | /// Checks if a handle is valid and points to an existing object. | ||
| 184 | bool IsValid(Handle handle) const; | ||
| 185 | |||
| 186 | /** | ||
| 187 | * Looks up a handle. | ||
| 188 | * @return Pointer to the looked-up object, or `nullptr` if the handle is not valid. | ||
| 189 | */ | ||
| 190 | SharedPtr<Object> GetGeneric(Handle handle) const; | ||
| 191 | |||
| 192 | /** | ||
| 193 | * Looks up a handle while verifying its type. | ||
| 194 | * @return Pointer to the looked-up object, or `nullptr` if the handle is not valid or its | ||
| 195 | * type differs from the requested one. | ||
| 196 | */ | ||
| 197 | template <class T> | ||
| 198 | SharedPtr<T> Get(Handle handle) const { | ||
| 199 | return DynamicObjectCast<T>(GetGeneric(handle)); | ||
| 200 | } | ||
| 201 | |||
| 202 | /// Closes all handles held in this table. | ||
| 203 | void Clear(); | ||
| 204 | |||
| 205 | private: | ||
| 206 | /** | ||
| 207 | * This is the maximum limit of handles allowed per process in CTR-OS. It can be further | ||
| 208 | * reduced by ExHeader values, but this is not emulated here. | ||
| 209 | */ | ||
| 210 | static const size_t MAX_COUNT = 4096; | ||
| 211 | |||
| 212 | static u16 GetSlot(Handle handle) { | ||
| 213 | return handle >> 15; | ||
| 214 | } | ||
| 215 | static u16 GetGeneration(Handle handle) { | ||
| 216 | return handle & 0x7FFF; | ||
| 217 | } | ||
| 218 | |||
| 219 | /// Stores the Object referenced by the handle or null if the slot is empty. | ||
| 220 | std::array<SharedPtr<Object>, MAX_COUNT> objects; | ||
| 221 | |||
| 222 | /** | ||
| 223 | * The value of `next_generation` when the handle was created, used to check for validity. For | ||
| 224 | * empty slots, contains the index of the next free slot in the list. | ||
| 225 | */ | ||
| 226 | std::array<u16, MAX_COUNT> generations; | ||
| 227 | |||
| 228 | /** | ||
| 229 | * Global counter of the number of created handles. Stored in `generations` when a handle is | ||
| 230 | * created, and wraps around to 1 when it hits 0x8000. | ||
| 231 | */ | ||
| 232 | u16 next_generation; | ||
| 233 | |||
| 234 | /// Head of the free slots linked list. | ||
| 235 | u16 next_free_slot; | ||
| 236 | }; | ||
| 237 | |||
| 238 | extern HandleTable g_handle_table; | ||
| 239 | |||
| 240 | /// Initialize the kernel with the specified system mode. | 126 | /// Initialize the kernel with the specified system mode. |
| 241 | void Init(u32 system_mode); | 127 | void Init(u32 system_mode); |
| 242 | 128 | ||