diff options
Diffstat (limited to 'src/core/hle/kernel')
| -rw-r--r-- | src/core/hle/kernel/address_arbiter.cpp | 15 | ||||
| -rw-r--r-- | src/core/hle/kernel/address_arbiter.h | 2 | ||||
| -rw-r--r-- | src/core/hle/kernel/archive.cpp | 176 | ||||
| -rw-r--r-- | src/core/hle/kernel/archive.h | 23 | ||||
| -rw-r--r-- | src/core/hle/kernel/event.cpp | 43 | ||||
| -rw-r--r-- | src/core/hle/kernel/event.h | 12 | ||||
| -rw-r--r-- | src/core/hle/kernel/kernel.h | 44 | ||||
| -rw-r--r-- | src/core/hle/kernel/mutex.cpp | 35 | ||||
| -rw-r--r-- | src/core/hle/kernel/mutex.h | 3 | ||||
| -rw-r--r-- | src/core/hle/kernel/shared_memory.cpp | 43 | ||||
| -rw-r--r-- | src/core/hle/kernel/shared_memory.h | 5 | ||||
| -rw-r--r-- | src/core/hle/kernel/thread.cpp | 78 | ||||
| -rw-r--r-- | src/core/hle/kernel/thread.h | 7 |
13 files changed, 195 insertions, 291 deletions
diff --git a/src/core/hle/kernel/address_arbiter.cpp b/src/core/hle/kernel/address_arbiter.cpp index 2b21657da..db571b895 100644 --- a/src/core/hle/kernel/address_arbiter.cpp +++ b/src/core/hle/kernel/address_arbiter.cpp | |||
| @@ -25,22 +25,17 @@ public: | |||
| 25 | 25 | ||
| 26 | std::string name; ///< Name of address arbiter object (optional) | 26 | std::string name; ///< Name of address arbiter object (optional) |
| 27 | 27 | ||
| 28 | /** | 28 | ResultVal<bool> WaitSynchronization() override { |
| 29 | * Wait for kernel object to synchronize | ||
| 30 | * @param wait Boolean wait set if current thread should wait as a result of sync operation | ||
| 31 | * @return Result of operation, 0 on success, otherwise error code | ||
| 32 | */ | ||
| 33 | Result WaitSynchronization(bool* wait) override { | ||
| 34 | // TODO(bunnei): ImplementMe | 29 | // TODO(bunnei): ImplementMe |
| 35 | ERROR_LOG(OSHLE, "(UNIMPLEMENTED)"); | 30 | ERROR_LOG(OSHLE, "(UNIMPLEMENTED)"); |
| 36 | return 0; | 31 | return UnimplementedFunction(ErrorModule::OS); |
| 37 | } | 32 | } |
| 38 | }; | 33 | }; |
| 39 | 34 | ||
| 40 | //////////////////////////////////////////////////////////////////////////////////////////////////// | 35 | //////////////////////////////////////////////////////////////////////////////////////////////////// |
| 41 | 36 | ||
| 42 | /// Arbitrate an address | 37 | /// Arbitrate an address |
| 43 | Result ArbitrateAddress(Handle handle, ArbitrationType type, u32 address, s32 value) { | 38 | ResultCode ArbitrateAddress(Handle handle, ArbitrationType type, u32 address, s32 value) { |
| 44 | switch (type) { | 39 | switch (type) { |
| 45 | 40 | ||
| 46 | // Signal thread(s) waiting for arbitrate address... | 41 | // Signal thread(s) waiting for arbitrate address... |
| @@ -65,9 +60,9 @@ Result ArbitrateAddress(Handle handle, ArbitrationType type, u32 address, s32 va | |||
| 65 | 60 | ||
| 66 | default: | 61 | default: |
| 67 | ERROR_LOG(KERNEL, "unknown type=%d", type); | 62 | ERROR_LOG(KERNEL, "unknown type=%d", type); |
| 68 | return -1; | 63 | return ResultCode(ErrorDescription::InvalidEnumValue, ErrorModule::Kernel, ErrorSummary::WrongArgument, ErrorLevel::Usage); |
| 69 | } | 64 | } |
| 70 | return 0; | 65 | return RESULT_SUCCESS; |
| 71 | } | 66 | } |
| 72 | 67 | ||
| 73 | /// Create an address arbiter | 68 | /// Create an address arbiter |
diff --git a/src/core/hle/kernel/address_arbiter.h b/src/core/hle/kernel/address_arbiter.h index 6886e479d..8a5fb10b4 100644 --- a/src/core/hle/kernel/address_arbiter.h +++ b/src/core/hle/kernel/address_arbiter.h | |||
| @@ -28,7 +28,7 @@ enum class ArbitrationType : u32 { | |||
| 28 | }; | 28 | }; |
| 29 | 29 | ||
| 30 | /// Arbitrate an address | 30 | /// Arbitrate an address |
| 31 | Result ArbitrateAddress(Handle handle, ArbitrationType type, u32 address, s32 value); | 31 | ResultCode ArbitrateAddress(Handle handle, ArbitrationType type, u32 address, s32 value); |
| 32 | 32 | ||
| 33 | /// Create an address arbiter | 33 | /// Create an address arbiter |
| 34 | Handle CreateAddressArbiter(const std::string& name = "Unknown"); | 34 | Handle CreateAddressArbiter(const std::string& name = "Unknown"); |
diff --git a/src/core/hle/kernel/archive.cpp b/src/core/hle/kernel/archive.cpp index 900f484c7..e273444c9 100644 --- a/src/core/hle/kernel/archive.cpp +++ b/src/core/hle/kernel/archive.cpp | |||
| @@ -9,8 +9,9 @@ | |||
| 9 | #include "core/file_sys/archive.h" | 9 | #include "core/file_sys/archive.h" |
| 10 | #include "core/file_sys/archive_sdmc.h" | 10 | #include "core/file_sys/archive_sdmc.h" |
| 11 | #include "core/file_sys/directory.h" | 11 | #include "core/file_sys/directory.h" |
| 12 | #include "core/hle/service/service.h" | ||
| 13 | #include "core/hle/kernel/archive.h" | 12 | #include "core/hle/kernel/archive.h" |
| 13 | #include "core/hle/result.h" | ||
| 14 | #include "core/hle/service/service.h" | ||
| 14 | 15 | ||
| 15 | //////////////////////////////////////////////////////////////////////////////////////////////////// | 16 | //////////////////////////////////////////////////////////////////////////////////////////////////// |
| 16 | // Kernel namespace | 17 | // Kernel namespace |
| @@ -51,12 +52,7 @@ public: | |||
| 51 | std::string name; ///< Name of archive (optional) | 52 | std::string name; ///< Name of archive (optional) |
| 52 | FileSys::Archive* backend; ///< Archive backend interface | 53 | FileSys::Archive* backend; ///< Archive backend interface |
| 53 | 54 | ||
| 54 | /** | 55 | ResultVal<bool> SyncRequest() override { |
| 55 | * Synchronize kernel object | ||
| 56 | * @param wait Boolean wait set if current thread should wait as a result of sync operation | ||
| 57 | * @return Result of operation, 0 on success, otherwise error code | ||
| 58 | */ | ||
| 59 | Result SyncRequest(bool* wait) override { | ||
| 60 | u32* cmd_buff = Service::GetCommandBuffer(); | 56 | u32* cmd_buff = Service::GetCommandBuffer(); |
| 61 | FileCommand cmd = static_cast<FileCommand>(cmd_buff[0]); | 57 | FileCommand cmd = static_cast<FileCommand>(cmd_buff[0]); |
| 62 | 58 | ||
| @@ -106,22 +102,17 @@ public: | |||
| 106 | default: | 102 | default: |
| 107 | { | 103 | { |
| 108 | ERROR_LOG(KERNEL, "Unknown command=0x%08X!", cmd); | 104 | ERROR_LOG(KERNEL, "Unknown command=0x%08X!", cmd); |
| 109 | return -1; | 105 | return UnimplementedFunction(ErrorModule::FS); |
| 110 | } | 106 | } |
| 111 | } | 107 | } |
| 112 | cmd_buff[1] = 0; // No error | 108 | cmd_buff[1] = 0; // No error |
| 113 | return 0; | 109 | return MakeResult<bool>(false); |
| 114 | } | 110 | } |
| 115 | 111 | ||
| 116 | /** | 112 | ResultVal<bool> WaitSynchronization() override { |
| 117 | * Wait for kernel object to synchronize | ||
| 118 | * @param wait Boolean wait set if current thread should wait as a result of sync operation | ||
| 119 | * @return Result of operation, 0 on success, otherwise error code | ||
| 120 | */ | ||
| 121 | Result WaitSynchronization(bool* wait) override { | ||
| 122 | // TODO(bunnei): ImplementMe | 113 | // TODO(bunnei): ImplementMe |
| 123 | ERROR_LOG(OSHLE, "(UNIMPLEMENTED)"); | 114 | ERROR_LOG(OSHLE, "(UNIMPLEMENTED)"); |
| 124 | return 0; | 115 | return UnimplementedFunction(ErrorModule::FS); |
| 125 | } | 116 | } |
| 126 | }; | 117 | }; |
| 127 | 118 | ||
| @@ -136,12 +127,7 @@ public: | |||
| 136 | FileSys::Path path; ///< Path of the file | 127 | FileSys::Path path; ///< Path of the file |
| 137 | std::unique_ptr<FileSys::File> backend; ///< File backend interface | 128 | std::unique_ptr<FileSys::File> backend; ///< File backend interface |
| 138 | 129 | ||
| 139 | /** | 130 | ResultVal<bool> SyncRequest() override { |
| 140 | * Synchronize kernel object | ||
| 141 | * @param wait Boolean wait set if current thread should wait as a result of sync operation | ||
| 142 | * @return Result of operation, 0 on success, otherwise error code | ||
| 143 | */ | ||
| 144 | Result SyncRequest(bool* wait) override { | ||
| 145 | u32* cmd_buff = Service::GetCommandBuffer(); | 131 | u32* cmd_buff = Service::GetCommandBuffer(); |
| 146 | FileCommand cmd = static_cast<FileCommand>(cmd_buff[0]); | 132 | FileCommand cmd = static_cast<FileCommand>(cmd_buff[0]); |
| 147 | switch (cmd) { | 133 | switch (cmd) { |
| @@ -183,7 +169,8 @@ public: | |||
| 183 | case FileCommand::SetSize: | 169 | case FileCommand::SetSize: |
| 184 | { | 170 | { |
| 185 | u64 size = cmd_buff[1] | ((u64)cmd_buff[2] << 32); | 171 | u64 size = cmd_buff[1] | ((u64)cmd_buff[2] << 32); |
| 186 | DEBUG_LOG(KERNEL, "SetSize %s %s size=%llu", GetTypeName().c_str(), GetName().c_str(), size); | 172 | DEBUG_LOG(KERNEL, "SetSize %s %s size=%llu", |
| 173 | GetTypeName().c_str(), GetName().c_str(), size); | ||
| 187 | backend->SetSize(size); | 174 | backend->SetSize(size); |
| 188 | break; | 175 | break; |
| 189 | } | 176 | } |
| @@ -198,22 +185,18 @@ public: | |||
| 198 | // Unknown command... | 185 | // Unknown command... |
| 199 | default: | 186 | default: |
| 200 | ERROR_LOG(KERNEL, "Unknown command=0x%08X!", cmd); | 187 | ERROR_LOG(KERNEL, "Unknown command=0x%08X!", cmd); |
| 201 | cmd_buff[1] = -1; // TODO(Link Mauve): use the correct error code for that. | 188 | ResultCode error = UnimplementedFunction(ErrorModule::FS); |
| 202 | return -1; | 189 | cmd_buff[1] = error.raw; // TODO(Link Mauve): use the correct error code for that. |
| 190 | return error; | ||
| 203 | } | 191 | } |
| 204 | cmd_buff[1] = 0; // No error | 192 | cmd_buff[1] = 0; // No error |
| 205 | return 0; | 193 | return MakeResult<bool>(false); |
| 206 | } | 194 | } |
| 207 | 195 | ||
| 208 | /** | 196 | ResultVal<bool> WaitSynchronization() override { |
| 209 | * Wait for kernel object to synchronize | ||
| 210 | * @param wait Boolean wait set if current thread should wait as a result of sync operation | ||
| 211 | * @return Result of operation, 0 on success, otherwise error code | ||
| 212 | */ | ||
| 213 | Result WaitSynchronization(bool* wait) override { | ||
| 214 | // TODO(bunnei): ImplementMe | 197 | // TODO(bunnei): ImplementMe |
| 215 | ERROR_LOG(OSHLE, "(UNIMPLEMENTED)"); | 198 | ERROR_LOG(OSHLE, "(UNIMPLEMENTED)"); |
| 216 | return 0; | 199 | return UnimplementedFunction(ErrorModule::FS); |
| 217 | } | 200 | } |
| 218 | }; | 201 | }; |
| 219 | 202 | ||
| @@ -228,12 +211,7 @@ public: | |||
| 228 | FileSys::Path path; ///< Path of the directory | 211 | FileSys::Path path; ///< Path of the directory |
| 229 | std::unique_ptr<FileSys::Directory> backend; ///< File backend interface | 212 | std::unique_ptr<FileSys::Directory> backend; ///< File backend interface |
| 230 | 213 | ||
| 231 | /** | 214 | ResultVal<bool> SyncRequest() override { |
| 232 | * Synchronize kernel object | ||
| 233 | * @param wait Boolean wait set if current thread should wait as a result of sync operation | ||
| 234 | * @return Result of operation, 0 on success, otherwise error code | ||
| 235 | */ | ||
| 236 | Result SyncRequest(bool* wait) override { | ||
| 237 | u32* cmd_buff = Service::GetCommandBuffer(); | 215 | u32* cmd_buff = Service::GetCommandBuffer(); |
| 238 | DirectoryCommand cmd = static_cast<DirectoryCommand>(cmd_buff[0]); | 216 | DirectoryCommand cmd = static_cast<DirectoryCommand>(cmd_buff[0]); |
| 239 | switch (cmd) { | 217 | switch (cmd) { |
| @@ -243,8 +221,9 @@ public: | |||
| 243 | { | 221 | { |
| 244 | u32 count = cmd_buff[1]; | 222 | u32 count = cmd_buff[1]; |
| 245 | u32 address = cmd_buff[3]; | 223 | u32 address = cmd_buff[3]; |
| 246 | FileSys::Entry* entries = reinterpret_cast<FileSys::Entry*>(Memory::GetPointer(address)); | 224 | auto entries = reinterpret_cast<FileSys::Entry*>(Memory::GetPointer(address)); |
| 247 | DEBUG_LOG(KERNEL, "Read %s %s: count=%d", GetTypeName().c_str(), GetName().c_str(), count); | 225 | DEBUG_LOG(KERNEL, "Read %s %s: count=%d", |
| 226 | GetTypeName().c_str(), GetName().c_str(), count); | ||
| 248 | 227 | ||
| 249 | // Number of entries actually read | 228 | // Number of entries actually read |
| 250 | cmd_buff[2] = backend->Read(count, entries); | 229 | cmd_buff[2] = backend->Read(count, entries); |
| @@ -261,22 +240,18 @@ public: | |||
| 261 | // Unknown command... | 240 | // Unknown command... |
| 262 | default: | 241 | default: |
| 263 | ERROR_LOG(KERNEL, "Unknown command=0x%08X!", cmd); | 242 | ERROR_LOG(KERNEL, "Unknown command=0x%08X!", cmd); |
| 264 | cmd_buff[1] = -1; // TODO(Link Mauve): use the correct error code for that. | 243 | ResultCode error = UnimplementedFunction(ErrorModule::FS); |
| 265 | return -1; | 244 | cmd_buff[1] = error.raw; // TODO(Link Mauve): use the correct error code for that. |
| 245 | return error; | ||
| 266 | } | 246 | } |
| 267 | cmd_buff[1] = 0; // No error | 247 | cmd_buff[1] = 0; // No error |
| 268 | return 0; | 248 | return MakeResult<bool>(false); |
| 269 | } | 249 | } |
| 270 | 250 | ||
| 271 | /** | 251 | ResultVal<bool> WaitSynchronization() override { |
| 272 | * Wait for kernel object to synchronize | ||
| 273 | * @param wait Boolean wait set if current thread should wait as a result of sync operation | ||
| 274 | * @return Result of operation, 0 on success, otherwise error code | ||
| 275 | */ | ||
| 276 | Result WaitSynchronization(bool* wait) override { | ||
| 277 | // TODO(bunnei): ImplementMe | 252 | // TODO(bunnei): ImplementMe |
| 278 | ERROR_LOG(OSHLE, "(UNIMPLEMENTED)"); | 253 | ERROR_LOG(OSHLE, "(UNIMPLEMENTED)"); |
| 279 | return 0; | 254 | return UnimplementedFunction(ErrorModule::FS); |
| 280 | } | 255 | } |
| 281 | }; | 256 | }; |
| 282 | 257 | ||
| @@ -284,89 +259,58 @@ public: | |||
| 284 | 259 | ||
| 285 | std::map<FileSys::Archive::IdCode, Handle> g_archive_map; ///< Map of file archives by IdCode | 260 | std::map<FileSys::Archive::IdCode, Handle> g_archive_map; ///< Map of file archives by IdCode |
| 286 | 261 | ||
| 287 | /** | 262 | ResultVal<Handle> OpenArchive(FileSys::Archive::IdCode id_code) { |
| 288 | * Opens an archive | ||
| 289 | * @param id_code IdCode of the archive to open | ||
| 290 | * @return Handle to archive if it exists, otherwise a null handle (0) | ||
| 291 | */ | ||
| 292 | Handle OpenArchive(FileSys::Archive::IdCode id_code) { | ||
| 293 | auto itr = g_archive_map.find(id_code); | 263 | auto itr = g_archive_map.find(id_code); |
| 294 | if (itr == g_archive_map.end()) { | 264 | if (itr == g_archive_map.end()) { |
| 295 | return 0; | 265 | return ResultCode(ErrorDescription::NotFound, ErrorModule::FS, |
| 266 | ErrorSummary::NotFound, ErrorLevel::Permanent); | ||
| 296 | } | 267 | } |
| 297 | return itr->second; | 268 | |
| 269 | return MakeResult<Handle>(itr->second); | ||
| 298 | } | 270 | } |
| 299 | 271 | ||
| 300 | /** | 272 | ResultCode CloseArchive(FileSys::Archive::IdCode id_code) { |
| 301 | * Closes an archive | ||
| 302 | * @param id_code IdCode of the archive to open | ||
| 303 | * @return Result of operation, 0 on success, otherwise error code | ||
| 304 | */ | ||
| 305 | Result CloseArchive(FileSys::Archive::IdCode id_code) { | ||
| 306 | auto itr = g_archive_map.find(id_code); | 273 | auto itr = g_archive_map.find(id_code); |
| 307 | if (itr == g_archive_map.end()) { | 274 | if (itr == g_archive_map.end()) { |
| 308 | ERROR_LOG(KERNEL, "Cannot close archive %d, does not exist!", (int)id_code); | 275 | ERROR_LOG(KERNEL, "Cannot close archive %d, does not exist!", (int)id_code); |
| 309 | return -1; | 276 | return InvalidHandle(ErrorModule::FS); |
| 310 | } | 277 | } |
| 311 | 278 | ||
| 312 | INFO_LOG(KERNEL, "Closed archive %d", (int) id_code); | 279 | INFO_LOG(KERNEL, "Closed archive %d", (int) id_code); |
| 313 | return 0; | 280 | return RESULT_SUCCESS; |
| 314 | } | 281 | } |
| 315 | 282 | ||
| 316 | /** | 283 | /** |
| 317 | * Mounts an archive | 284 | * Mounts an archive |
| 318 | * @param archive Pointer to the archive to mount | 285 | * @param archive Pointer to the archive to mount |
| 319 | * @return Result of operation, 0 on success, otherwise error code | ||
| 320 | */ | 286 | */ |
| 321 | Result MountArchive(Archive* archive) { | 287 | ResultCode MountArchive(Archive* archive) { |
| 322 | FileSys::Archive::IdCode id_code = archive->backend->GetIdCode(); | 288 | FileSys::Archive::IdCode id_code = archive->backend->GetIdCode(); |
| 323 | if (0 != OpenArchive(id_code)) { | 289 | ResultVal<Handle> archive_handle = OpenArchive(id_code); |
| 290 | if (archive_handle.Succeeded()) { | ||
| 324 | ERROR_LOG(KERNEL, "Cannot mount two archives with the same ID code! (%d)", (int) id_code); | 291 | ERROR_LOG(KERNEL, "Cannot mount two archives with the same ID code! (%d)", (int) id_code); |
| 325 | return -1; | 292 | return archive_handle.Code(); |
| 326 | } | 293 | } |
| 327 | g_archive_map[id_code] = archive->GetHandle(); | 294 | g_archive_map[id_code] = archive->GetHandle(); |
| 328 | INFO_LOG(KERNEL, "Mounted archive %s", archive->GetName().c_str()); | 295 | INFO_LOG(KERNEL, "Mounted archive %s", archive->GetName().c_str()); |
| 329 | return 0; | 296 | return RESULT_SUCCESS; |
| 330 | } | 297 | } |
| 331 | 298 | ||
| 332 | /** | 299 | ResultCode CreateArchive(FileSys::Archive* backend, const std::string& name) { |
| 333 | * Creates an Archive | ||
| 334 | * @param handle Handle to newly created archive object | ||
| 335 | * @param backend File system backend interface to the archive | ||
| 336 | * @param name Optional name of Archive | ||
| 337 | * @return Newly created Archive object | ||
| 338 | */ | ||
| 339 | Archive* CreateArchive(Handle& handle, FileSys::Archive* backend, const std::string& name) { | ||
| 340 | Archive* archive = new Archive; | 300 | Archive* archive = new Archive; |
| 341 | handle = Kernel::g_object_pool.Create(archive); | 301 | Handle handle = Kernel::g_object_pool.Create(archive); |
| 342 | archive->name = name; | 302 | archive->name = name; |
| 343 | archive->backend = backend; | 303 | archive->backend = backend; |
| 344 | 304 | ||
| 345 | MountArchive(archive); | 305 | ResultCode result = MountArchive(archive); |
| 346 | 306 | if (result.IsError()) { | |
| 347 | return archive; | 307 | return result; |
| 348 | } | 308 | } |
| 349 | 309 | ||
| 350 | /** | 310 | return RESULT_SUCCESS; |
| 351 | * Creates an Archive | ||
| 352 | * @param backend File system backend interface to the archive | ||
| 353 | * @param name Optional name of Archive | ||
| 354 | * @return Handle to newly created Archive object | ||
| 355 | */ | ||
| 356 | Handle CreateArchive(FileSys::Archive* backend, const std::string& name) { | ||
| 357 | Handle handle; | ||
| 358 | CreateArchive(handle, backend, name); | ||
| 359 | return handle; | ||
| 360 | } | 311 | } |
| 361 | 312 | ||
| 362 | /** | 313 | ResultVal<Handle> OpenFileFromArchive(Handle archive_handle, const FileSys::Path& path, const FileSys::Mode mode) { |
| 363 | * Open a File from an Archive | ||
| 364 | * @param archive_handle Handle to an open Archive object | ||
| 365 | * @param path Path to the File inside of the Archive | ||
| 366 | * @param mode Mode under which to open the File | ||
| 367 | * @return Opened File object | ||
| 368 | */ | ||
| 369 | Handle OpenFileFromArchive(Handle archive_handle, const FileSys::Path& path, const FileSys::Mode mode) { | ||
| 370 | // TODO(bunnei): Binary type files get a raw file pointer to the archive. Currently, we create | 314 | // TODO(bunnei): Binary type files get a raw file pointer to the archive. Currently, we create |
| 371 | // the archive file handles at app loading, and then keep them persistent throughout execution. | 315 | // the archive file handles at app loading, and then keep them persistent throughout execution. |
| 372 | // Archives file handles are just reused and not actually freed until emulation shut down. | 316 | // Archives file handles are just reused and not actually freed until emulation shut down. |
| @@ -376,19 +320,24 @@ Handle OpenFileFromArchive(Handle archive_handle, const FileSys::Path& path, con | |||
| 376 | // design. While the functionally of this is OK, our implementation decision to separate | 320 | // design. While the functionally of this is OK, our implementation decision to separate |
| 377 | // normal files from archive file pointers is very likely wrong. | 321 | // normal files from archive file pointers is very likely wrong. |
| 378 | // See https://github.com/citra-emu/citra/issues/205 | 322 | // See https://github.com/citra-emu/citra/issues/205 |
| 379 | return archive_handle; | 323 | return MakeResult<Handle>(archive_handle); |
| 380 | 324 | ||
| 381 | File* file = new File; | 325 | File* file = new File; |
| 382 | Handle handle = Kernel::g_object_pool.Create(file); | 326 | Handle handle = Kernel::g_object_pool.Create(file); |
| 383 | 327 | ||
| 384 | Archive* archive = Kernel::g_object_pool.GetFast<Archive>(archive_handle); | 328 | Archive* archive = Kernel::g_object_pool.Get<Archive>(archive_handle); |
| 329 | if (archive == nullptr) { | ||
| 330 | return InvalidHandle(ErrorModule::FS); | ||
| 331 | } | ||
| 385 | file->path = path; | 332 | file->path = path; |
| 386 | file->backend = archive->backend->OpenFile(path, mode); | 333 | file->backend = archive->backend->OpenFile(path, mode); |
| 387 | 334 | ||
| 388 | if (!file->backend) | 335 | if (!file->backend) { |
| 389 | return 0; | 336 | return ResultCode(ErrorDescription::NotFound, ErrorModule::FS, |
| 337 | ErrorSummary::NotFound, ErrorLevel::Permanent); | ||
| 338 | } | ||
| 390 | 339 | ||
| 391 | return handle; | 340 | return MakeResult<Handle>(handle); |
| 392 | } | 341 | } |
| 393 | 342 | ||
| 394 | /** | 343 | /** |
| @@ -442,15 +391,18 @@ Result CreateDirectoryFromArchive(Handle archive_handle, const FileSys::Path& pa | |||
| 442 | * @param path Path to the Directory inside of the Archive | 391 | * @param path Path to the Directory inside of the Archive |
| 443 | * @return Opened Directory object | 392 | * @return Opened Directory object |
| 444 | */ | 393 | */ |
| 445 | Handle OpenDirectoryFromArchive(Handle archive_handle, const FileSys::Path& path) { | 394 | ResultVal<Handle> OpenDirectoryFromArchive(Handle archive_handle, const FileSys::Path& path) { |
| 446 | Directory* directory = new Directory; | 395 | Directory* directory = new Directory; |
| 447 | Handle handle = Kernel::g_object_pool.Create(directory); | 396 | Handle handle = Kernel::g_object_pool.Create(directory); |
| 448 | 397 | ||
| 449 | Archive* archive = Kernel::g_object_pool.GetFast<Archive>(archive_handle); | 398 | Archive* archive = Kernel::g_object_pool.Get<Archive>(archive_handle); |
| 399 | if (archive == nullptr) { | ||
| 400 | return InvalidHandle(ErrorModule::FS); | ||
| 401 | } | ||
| 450 | directory->path = path; | 402 | directory->path = path; |
| 451 | directory->backend = archive->backend->OpenDirectory(path); | 403 | directory->backend = archive->backend->OpenDirectory(path); |
| 452 | 404 | ||
| 453 | return handle; | 405 | return MakeResult<Handle>(handle); |
| 454 | } | 406 | } |
| 455 | 407 | ||
| 456 | /// Initialize archives | 408 | /// Initialize archives |
diff --git a/src/core/hle/kernel/archive.h b/src/core/hle/kernel/archive.h index 95b3c6656..6fc4f0f25 100644 --- a/src/core/hle/kernel/archive.h +++ b/src/core/hle/kernel/archive.h | |||
| @@ -6,8 +6,9 @@ | |||
| 6 | 6 | ||
| 7 | #include "common/common_types.h" | 7 | #include "common/common_types.h" |
| 8 | 8 | ||
| 9 | #include "core/hle/kernel/kernel.h" | ||
| 10 | #include "core/file_sys/archive.h" | 9 | #include "core/file_sys/archive.h" |
| 10 | #include "core/hle/kernel/kernel.h" | ||
| 11 | #include "core/hle/result.h" | ||
| 11 | 12 | ||
| 12 | //////////////////////////////////////////////////////////////////////////////////////////////////// | 13 | //////////////////////////////////////////////////////////////////////////////////////////////////// |
| 13 | // Kernel namespace | 14 | // Kernel namespace |
| @@ -17,33 +18,31 @@ namespace Kernel { | |||
| 17 | /** | 18 | /** |
| 18 | * Opens an archive | 19 | * Opens an archive |
| 19 | * @param id_code IdCode of the archive to open | 20 | * @param id_code IdCode of the archive to open |
| 20 | * @return Handle to archive if it exists, otherwise a null handle (0) | 21 | * @return Handle to the opened archive |
| 21 | */ | 22 | */ |
| 22 | Handle OpenArchive(FileSys::Archive::IdCode id_code); | 23 | ResultVal<Handle> OpenArchive(FileSys::Archive::IdCode id_code); |
| 23 | 24 | ||
| 24 | /** | 25 | /** |
| 25 | * Closes an archive | 26 | * Closes an archive |
| 26 | * @param id_code IdCode of the archive to open | 27 | * @param id_code IdCode of the archive to open |
| 27 | * @return true if it worked fine | ||
| 28 | */ | 28 | */ |
| 29 | Result CloseArchive(FileSys::Archive::IdCode id_code); | 29 | ResultCode CloseArchive(FileSys::Archive::IdCode id_code); |
| 30 | 30 | ||
| 31 | /** | 31 | /** |
| 32 | * Creates an Archive | 32 | * Creates an Archive |
| 33 | * @param backend File system backend interface to the archive | 33 | * @param backend File system backend interface to the archive |
| 34 | * @param name Optional name of Archive | 34 | * @param name Name of Archive |
| 35 | * @return Handle to newly created Archive object | ||
| 36 | */ | 35 | */ |
| 37 | Handle CreateArchive(FileSys::Archive* backend, const std::string& name); | 36 | ResultCode CreateArchive(FileSys::Archive* backend, const std::string& name); |
| 38 | 37 | ||
| 39 | /** | 38 | /** |
| 40 | * Open a File from an Archive | 39 | * Open a File from an Archive |
| 41 | * @param archive_handle Handle to an open Archive object | 40 | * @param archive_handle Handle to an open Archive object |
| 42 | * @param path Path to the File inside of the Archive | 41 | * @param path Path to the File inside of the Archive |
| 43 | * @param mode Mode under which to open the File | 42 | * @param mode Mode under which to open the File |
| 44 | * @return Opened File object | 43 | * @return Handle to the opened File object |
| 45 | */ | 44 | */ |
| 46 | Handle OpenFileFromArchive(Handle archive_handle, const FileSys::Path& path, const FileSys::Mode mode); | 45 | ResultVal<Handle> OpenFileFromArchive(Handle archive_handle, const FileSys::Path& path, const FileSys::Mode mode); |
| 47 | 46 | ||
| 48 | /** | 47 | /** |
| 49 | * Delete a File from an Archive | 48 | * Delete a File from an Archive |
| @@ -73,9 +72,9 @@ Result CreateDirectoryFromArchive(Handle archive_handle, const FileSys::Path& pa | |||
| 73 | * Open a Directory from an Archive | 72 | * Open a Directory from an Archive |
| 74 | * @param archive_handle Handle to an open Archive object | 73 | * @param archive_handle Handle to an open Archive object |
| 75 | * @param path Path to the Directory inside of the Archive | 74 | * @param path Path to the Directory inside of the Archive |
| 76 | * @return Opened Directory object | 75 | * @return Handle to the opened File object |
| 77 | */ | 76 | */ |
| 78 | Handle OpenDirectoryFromArchive(Handle archive_handle, const FileSys::Path& path); | 77 | ResultVal<Handle> OpenDirectoryFromArchive(Handle archive_handle, const FileSys::Path& path); |
| 79 | 78 | ||
| 80 | /// Initialize archives | 79 | /// Initialize archives |
| 81 | void ArchiveInit(); | 80 | void ArchiveInit(); |
diff --git a/src/core/hle/kernel/event.cpp b/src/core/hle/kernel/event.cpp index e0117c0bc..288080209 100644 --- a/src/core/hle/kernel/event.cpp +++ b/src/core/hle/kernel/event.cpp | |||
| @@ -30,13 +30,8 @@ public: | |||
| 30 | std::vector<Handle> waiting_threads; ///< Threads that are waiting for the event | 30 | std::vector<Handle> waiting_threads; ///< Threads that are waiting for the event |
| 31 | std::string name; ///< Name of event (optional) | 31 | std::string name; ///< Name of event (optional) |
| 32 | 32 | ||
| 33 | /** | 33 | ResultVal<bool> WaitSynchronization() override { |
| 34 | * Wait for kernel object to synchronize | 34 | bool wait = locked; |
| 35 | * @param wait Boolean wait set if current thread should wait as a result of sync operation | ||
| 36 | * @return Result of operation, 0 on success, otherwise error code | ||
| 37 | */ | ||
| 38 | Result WaitSynchronization(bool* wait) override { | ||
| 39 | *wait = locked; | ||
| 40 | if (locked) { | 35 | if (locked) { |
| 41 | Handle thread = GetCurrentThreadHandle(); | 36 | Handle thread = GetCurrentThreadHandle(); |
| 42 | if (std::find(waiting_threads.begin(), waiting_threads.end(), thread) == waiting_threads.end()) { | 37 | if (std::find(waiting_threads.begin(), waiting_threads.end(), thread) == waiting_threads.end()) { |
| @@ -47,7 +42,7 @@ public: | |||
| 47 | if (reset_type != RESETTYPE_STICKY && !permanent_locked) { | 42 | if (reset_type != RESETTYPE_STICKY && !permanent_locked) { |
| 48 | locked = true; | 43 | locked = true; |
| 49 | } | 44 | } |
| 50 | return 0; | 45 | return MakeResult<bool>(wait); |
| 51 | } | 46 | } |
| 52 | }; | 47 | }; |
| 53 | 48 | ||
| @@ -57,12 +52,12 @@ public: | |||
| 57 | * @param permanent_locked Boolean permanent locked value to set event | 52 | * @param permanent_locked Boolean permanent locked value to set event |
| 58 | * @return Result of operation, 0 on success, otherwise error code | 53 | * @return Result of operation, 0 on success, otherwise error code |
| 59 | */ | 54 | */ |
| 60 | Result SetPermanentLock(Handle handle, const bool permanent_locked) { | 55 | ResultCode SetPermanentLock(Handle handle, const bool permanent_locked) { |
| 61 | Event* evt = g_object_pool.GetFast<Event>(handle); | 56 | Event* evt = g_object_pool.Get<Event>(handle); |
| 62 | _assert_msg_(KERNEL, (evt != nullptr), "called, but event is nullptr!"); | 57 | if (evt == nullptr) return InvalidHandle(ErrorModule::Kernel); |
| 63 | 58 | ||
| 64 | evt->permanent_locked = permanent_locked; | 59 | evt->permanent_locked = permanent_locked; |
| 65 | return 0; | 60 | return RESULT_SUCCESS; |
| 66 | } | 61 | } |
| 67 | 62 | ||
| 68 | /** | 63 | /** |
| @@ -71,14 +66,14 @@ Result SetPermanentLock(Handle handle, const bool permanent_locked) { | |||
| 71 | * @param locked Boolean locked value to set event | 66 | * @param locked Boolean locked value to set event |
| 72 | * @return Result of operation, 0 on success, otherwise error code | 67 | * @return Result of operation, 0 on success, otherwise error code |
| 73 | */ | 68 | */ |
| 74 | Result SetEventLocked(const Handle handle, const bool locked) { | 69 | ResultCode SetEventLocked(const Handle handle, const bool locked) { |
| 75 | Event* evt = g_object_pool.GetFast<Event>(handle); | 70 | Event* evt = g_object_pool.Get<Event>(handle); |
| 76 | _assert_msg_(KERNEL, (evt != nullptr), "called, but event is nullptr!"); | 71 | if (evt == nullptr) return InvalidHandle(ErrorModule::Kernel); |
| 77 | 72 | ||
| 78 | if (!evt->permanent_locked) { | 73 | if (!evt->permanent_locked) { |
| 79 | evt->locked = locked; | 74 | evt->locked = locked; |
| 80 | } | 75 | } |
| 81 | return 0; | 76 | return RESULT_SUCCESS; |
| 82 | } | 77 | } |
| 83 | 78 | ||
| 84 | /** | 79 | /** |
| @@ -86,9 +81,9 @@ Result SetEventLocked(const Handle handle, const bool locked) { | |||
| 86 | * @param handle Handle to event to signal | 81 | * @param handle Handle to event to signal |
| 87 | * @return Result of operation, 0 on success, otherwise error code | 82 | * @return Result of operation, 0 on success, otherwise error code |
| 88 | */ | 83 | */ |
| 89 | Result SignalEvent(const Handle handle) { | 84 | ResultCode SignalEvent(const Handle handle) { |
| 90 | Event* evt = g_object_pool.GetFast<Event>(handle); | 85 | Event* evt = g_object_pool.Get<Event>(handle); |
| 91 | _assert_msg_(KERNEL, (evt != nullptr), "called, but event is nullptr!"); | 86 | if (evt == nullptr) return InvalidHandle(ErrorModule::Kernel); |
| 92 | 87 | ||
| 93 | // Resume threads waiting for event to signal | 88 | // Resume threads waiting for event to signal |
| 94 | bool event_caught = false; | 89 | bool event_caught = false; |
| @@ -106,7 +101,7 @@ Result SignalEvent(const Handle handle) { | |||
| 106 | if (!evt->permanent_locked) { | 101 | if (!evt->permanent_locked) { |
| 107 | evt->locked = event_caught; | 102 | evt->locked = event_caught; |
| 108 | } | 103 | } |
| 109 | return 0; | 104 | return RESULT_SUCCESS; |
| 110 | } | 105 | } |
| 111 | 106 | ||
| 112 | /** | 107 | /** |
| @@ -114,14 +109,14 @@ Result SignalEvent(const Handle handle) { | |||
| 114 | * @param handle Handle to event to clear | 109 | * @param handle Handle to event to clear |
| 115 | * @return Result of operation, 0 on success, otherwise error code | 110 | * @return Result of operation, 0 on success, otherwise error code |
| 116 | */ | 111 | */ |
| 117 | Result ClearEvent(Handle handle) { | 112 | ResultCode ClearEvent(Handle handle) { |
| 118 | Event* evt = g_object_pool.GetFast<Event>(handle); | 113 | Event* evt = g_object_pool.Get<Event>(handle); |
| 119 | _assert_msg_(KERNEL, (evt != nullptr), "called, but event is nullptr!"); | 114 | if (evt == nullptr) return InvalidHandle(ErrorModule::Kernel); |
| 120 | 115 | ||
| 121 | if (!evt->permanent_locked) { | 116 | if (!evt->permanent_locked) { |
| 122 | evt->locked = true; | 117 | evt->locked = true; |
| 123 | } | 118 | } |
| 124 | return 0; | 119 | return RESULT_SUCCESS; |
| 125 | } | 120 | } |
| 126 | 121 | ||
| 127 | /** | 122 | /** |
diff --git a/src/core/hle/kernel/event.h b/src/core/hle/kernel/event.h index 6add72897..73aec4e79 100644 --- a/src/core/hle/kernel/event.h +++ b/src/core/hle/kernel/event.h | |||
| @@ -15,31 +15,27 @@ namespace Kernel { | |||
| 15 | * Changes whether an event is locked or not | 15 | * Changes whether an event is locked or not |
| 16 | * @param handle Handle to event to change | 16 | * @param handle Handle to event to change |
| 17 | * @param locked Boolean locked value to set event | 17 | * @param locked Boolean locked value to set event |
| 18 | * @return Result of operation, 0 on success, otherwise error code | ||
| 19 | */ | 18 | */ |
| 20 | Result SetEventLocked(const Handle handle, const bool locked); | 19 | ResultCode SetEventLocked(const Handle handle, const bool locked); |
| 21 | 20 | ||
| 22 | /** | 21 | /** |
| 23 | * Hackish function to set an events permanent lock state, used to pass through synch blocks | 22 | * Hackish function to set an events permanent lock state, used to pass through synch blocks |
| 24 | * @param handle Handle to event to change | 23 | * @param handle Handle to event to change |
| 25 | * @param permanent_locked Boolean permanent locked value to set event | 24 | * @param permanent_locked Boolean permanent locked value to set event |
| 26 | * @return Result of operation, 0 on success, otherwise error code | ||
| 27 | */ | 25 | */ |
| 28 | Result SetPermanentLock(Handle handle, const bool permanent_locked); | 26 | ResultCode SetPermanentLock(Handle handle, const bool permanent_locked); |
| 29 | 27 | ||
| 30 | /** | 28 | /** |
| 31 | * Signals an event | 29 | * Signals an event |
| 32 | * @param handle Handle to event to signal | 30 | * @param handle Handle to event to signal |
| 33 | * @return Result of operation, 0 on success, otherwise error code | ||
| 34 | */ | 31 | */ |
| 35 | Result SignalEvent(const Handle handle); | 32 | ResultCode SignalEvent(const Handle handle); |
| 36 | 33 | ||
| 37 | /** | 34 | /** |
| 38 | * Clears an event | 35 | * Clears an event |
| 39 | * @param handle Handle to event to clear | 36 | * @param handle Handle to event to clear |
| 40 | * @return Result of operation, 0 on success, otherwise error code | ||
| 41 | */ | 37 | */ |
| 42 | Result ClearEvent(Handle handle); | 38 | ResultCode ClearEvent(Handle handle); |
| 43 | 39 | ||
| 44 | /** | 40 | /** |
| 45 | * Creates an event | 41 | * Creates an event |
diff --git a/src/core/hle/kernel/kernel.h b/src/core/hle/kernel/kernel.h index e0c94f186..8d3937ce8 100644 --- a/src/core/hle/kernel/kernel.h +++ b/src/core/hle/kernel/kernel.h | |||
| @@ -7,6 +7,7 @@ | |||
| 7 | #include <array> | 7 | #include <array> |
| 8 | #include <string> | 8 | #include <string> |
| 9 | #include "common/common.h" | 9 | #include "common/common.h" |
| 10 | #include "core/hle/result.h" | ||
| 10 | 11 | ||
| 11 | typedef u32 Handle; | 12 | typedef u32 Handle; |
| 12 | typedef s32 Result; | 13 | typedef s32 Result; |
| @@ -52,21 +53,19 @@ public: | |||
| 52 | virtual Kernel::HandleType GetHandleType() const = 0; | 53 | virtual Kernel::HandleType GetHandleType() const = 0; |
| 53 | 54 | ||
| 54 | /** | 55 | /** |
| 55 | * Synchronize kernel object | 56 | * Synchronize kernel object. |
| 56 | * @param wait Boolean wait set if current thread should wait as a result of sync operation | 57 | * @return True if the current thread should wait as a result of the sync |
| 57 | * @return Result of operation, 0 on success, otherwise error code | ||
| 58 | */ | 58 | */ |
| 59 | virtual Result SyncRequest(bool* wait) { | 59 | virtual ResultVal<bool> SyncRequest() { |
| 60 | ERROR_LOG(KERNEL, "(UNIMPLEMENTED)"); | 60 | ERROR_LOG(KERNEL, "(UNIMPLEMENTED)"); |
| 61 | return -1; | 61 | return UnimplementedFunction(ErrorModule::Kernel); |
| 62 | } | 62 | } |
| 63 | 63 | ||
| 64 | /** | 64 | /** |
| 65 | * Wait for kernel object to synchronize | 65 | * Wait for kernel object to synchronize. |
| 66 | * @param wait Boolean wait set if current thread should wait as a result of sync operation | 66 | * @return True if the current thread should wait as a result of the wait |
| 67 | * @return Result of operation, 0 on success, otherwise error code | ||
| 68 | */ | 67 | */ |
| 69 | virtual Result WaitSynchronization(bool* wait) = 0; | 68 | virtual ResultVal<bool> WaitSynchronization() = 0; |
| 70 | }; | 69 | }; |
| 71 | 70 | ||
| 72 | class ObjectPool : NonCopyable { | 71 | class ObjectPool : NonCopyable { |
| @@ -80,38 +79,29 @@ public: | |||
| 80 | static Object* CreateByIDType(int type); | 79 | static Object* CreateByIDType(int type); |
| 81 | 80 | ||
| 82 | template <class T> | 81 | template <class T> |
| 83 | u32 Destroy(Handle handle) { | 82 | void Destroy(Handle handle) { |
| 84 | u32 error; | 83 | if (Get<T>(handle)) { |
| 85 | if (Get<T>(handle, error)) { | ||
| 86 | occupied[handle - HANDLE_OFFSET] = false; | 84 | occupied[handle - HANDLE_OFFSET] = false; |
| 87 | delete pool[handle - HANDLE_OFFSET]; | 85 | delete pool[handle - HANDLE_OFFSET]; |
| 88 | } | 86 | } |
| 89 | return error; | ||
| 90 | } | 87 | } |
| 91 | 88 | ||
| 92 | bool IsValid(Handle handle); | 89 | bool IsValid(Handle handle); |
| 93 | 90 | ||
| 94 | template <class T> | 91 | template <class T> |
| 95 | T* Get(Handle handle, u32& outError) { | 92 | T* Get(Handle handle) { |
| 96 | if (handle < HANDLE_OFFSET || handle >= HANDLE_OFFSET + MAX_COUNT || !occupied[handle - HANDLE_OFFSET]) { | 93 | if (handle < HANDLE_OFFSET || handle >= HANDLE_OFFSET + MAX_COUNT || !occupied[handle - HANDLE_OFFSET]) { |
| 97 | // Tekken 6 spams 0x80020001 gets wrong with no ill effects, also on the real PSP | 94 | if (handle != 0) { |
| 98 | if (handle != 0 && (u32)handle != 0x80020001) { | ||
| 99 | WARN_LOG(KERNEL, "Kernel: Bad object handle %i (%08x)", handle, handle); | 95 | WARN_LOG(KERNEL, "Kernel: Bad object handle %i (%08x)", handle, handle); |
| 100 | } | 96 | } |
| 101 | outError = 0;//T::GetMissingErrorCode(); | 97 | return nullptr; |
| 102 | return 0; | ||
| 103 | } else { | 98 | } else { |
| 104 | // Previously we had a dynamic_cast here, but since RTTI was disabled traditionally, | 99 | Object* t = pool[handle - HANDLE_OFFSET]; |
| 105 | // it just acted as a static case and everything worked. This means that we will never | 100 | if (t->GetHandleType() != T::GetStaticHandleType()) { |
| 106 | // see the Wrong type object error below, but we'll just have to live with that danger. | ||
| 107 | T* t = static_cast<T*>(pool[handle - HANDLE_OFFSET]); | ||
| 108 | if (t == 0 || t->GetHandleType() != T::GetStaticHandleType()) { | ||
| 109 | WARN_LOG(KERNEL, "Kernel: Wrong object type for %i (%08x)", handle, handle); | 101 | WARN_LOG(KERNEL, "Kernel: Wrong object type for %i (%08x)", handle, handle); |
| 110 | outError = 0;//T::GetMissingErrorCode(); | 102 | return nullptr; |
| 111 | return 0; | ||
| 112 | } | 103 | } |
| 113 | outError = 0;//SCE_KERNEL_ERROR_OK; | 104 | return static_cast<T*>(t); |
| 114 | return t; | ||
| 115 | } | 105 | } |
| 116 | } | 106 | } |
| 117 | 107 | ||
diff --git a/src/core/hle/kernel/mutex.cpp b/src/core/hle/kernel/mutex.cpp index 31129fd86..b303ba128 100644 --- a/src/core/hle/kernel/mutex.cpp +++ b/src/core/hle/kernel/mutex.cpp | |||
| @@ -27,31 +27,20 @@ public: | |||
| 27 | std::vector<Handle> waiting_threads; ///< Threads that are waiting for the mutex | 27 | std::vector<Handle> waiting_threads; ///< Threads that are waiting for the mutex |
| 28 | std::string name; ///< Name of mutex (optional) | 28 | std::string name; ///< Name of mutex (optional) |
| 29 | 29 | ||
| 30 | /** | 30 | ResultVal<bool> SyncRequest() override { |
| 31 | * Synchronize kernel object | ||
| 32 | * @param wait Boolean wait set if current thread should wait as a result of sync operation | ||
| 33 | * @return Result of operation, 0 on success, otherwise error code | ||
| 34 | */ | ||
| 35 | Result SyncRequest(bool* wait) override { | ||
| 36 | // TODO(bunnei): ImplementMe | 31 | // TODO(bunnei): ImplementMe |
| 37 | locked = true; | 32 | locked = true; |
| 38 | return 0; | 33 | return MakeResult<bool>(false); |
| 39 | } | 34 | } |
| 40 | 35 | ||
| 41 | /** | 36 | ResultVal<bool> WaitSynchronization() override { |
| 42 | * Wait for kernel object to synchronize | ||
| 43 | * @param wait Boolean wait set if current thread should wait as a result of sync operation | ||
| 44 | * @return Result of operation, 0 on success, otherwise error code | ||
| 45 | */ | ||
| 46 | Result WaitSynchronization(bool* wait) override { | ||
| 47 | // TODO(bunnei): ImplementMe | 37 | // TODO(bunnei): ImplementMe |
| 48 | *wait = locked; | 38 | bool wait = locked; |
| 49 | |||
| 50 | if (locked) { | 39 | if (locked) { |
| 51 | Kernel::WaitCurrentThread(WAITTYPE_MUTEX, GetHandle()); | 40 | Kernel::WaitCurrentThread(WAITTYPE_MUTEX, GetHandle()); |
| 52 | } | 41 | } |
| 53 | 42 | ||
| 54 | return 0; | 43 | return MakeResult<bool>(wait); |
| 55 | } | 44 | } |
| 56 | }; | 45 | }; |
| 57 | 46 | ||
| @@ -119,15 +108,17 @@ bool ReleaseMutex(Mutex* mutex) { | |||
| 119 | * Releases a mutex | 108 | * Releases a mutex |
| 120 | * @param handle Handle to mutex to release | 109 | * @param handle Handle to mutex to release |
| 121 | */ | 110 | */ |
| 122 | Result ReleaseMutex(Handle handle) { | 111 | ResultCode ReleaseMutex(Handle handle) { |
| 123 | Mutex* mutex = Kernel::g_object_pool.GetFast<Mutex>(handle); | 112 | Mutex* mutex = Kernel::g_object_pool.Get<Mutex>(handle); |
| 124 | 113 | if (mutex == nullptr) return InvalidHandle(ErrorModule::Kernel); | |
| 125 | _assert_msg_(KERNEL, (mutex != nullptr), "ReleaseMutex tried to release a nullptr mutex!"); | ||
| 126 | 114 | ||
| 127 | if (!ReleaseMutex(mutex)) { | 115 | if (!ReleaseMutex(mutex)) { |
| 128 | return -1; | 116 | // TODO(yuriks): Verify error code, this one was pulled out of thin air. I'm not even sure |
| 117 | // what error condition this is supposed to be signaling. | ||
| 118 | return ResultCode(ErrorDescription::AlreadyDone, ErrorModule::Kernel, | ||
| 119 | ErrorSummary::NothingHappened, ErrorLevel::Temporary); | ||
| 129 | } | 120 | } |
| 130 | return 0; | 121 | return RESULT_SUCCESS; |
| 131 | } | 122 | } |
| 132 | 123 | ||
| 133 | /** | 124 | /** |
diff --git a/src/core/hle/kernel/mutex.h b/src/core/hle/kernel/mutex.h index 313ba6fee..155449f95 100644 --- a/src/core/hle/kernel/mutex.h +++ b/src/core/hle/kernel/mutex.h | |||
| @@ -13,9 +13,8 @@ namespace Kernel { | |||
| 13 | /** | 13 | /** |
| 14 | * Releases a mutex | 14 | * Releases a mutex |
| 15 | * @param handle Handle to mutex to release | 15 | * @param handle Handle to mutex to release |
| 16 | * @return Result of operation, 0 on success, otherwise error code | ||
| 17 | */ | 16 | */ |
| 18 | Result ReleaseMutex(Handle handle); | 17 | ResultCode ReleaseMutex(Handle handle); |
| 19 | 18 | ||
| 20 | /** | 19 | /** |
| 21 | * Creates a mutex | 20 | * Creates a mutex |
diff --git a/src/core/hle/kernel/shared_memory.cpp b/src/core/hle/kernel/shared_memory.cpp index 7ef3e54cc..cfcc0e0b7 100644 --- a/src/core/hle/kernel/shared_memory.cpp +++ b/src/core/hle/kernel/shared_memory.cpp | |||
| @@ -16,15 +16,10 @@ public: | |||
| 16 | static Kernel::HandleType GetStaticHandleType() { return Kernel::HandleType::SharedMemory; } | 16 | static Kernel::HandleType GetStaticHandleType() { return Kernel::HandleType::SharedMemory; } |
| 17 | Kernel::HandleType GetHandleType() const override { return Kernel::HandleType::SharedMemory; } | 17 | Kernel::HandleType GetHandleType() const override { return Kernel::HandleType::SharedMemory; } |
| 18 | 18 | ||
| 19 | /** | 19 | ResultVal<bool> WaitSynchronization() override { |
| 20 | * Wait for kernel object to synchronize | ||
| 21 | * @param wait Boolean wait set if current thread should wait as a result of sync operation | ||
| 22 | * @return Result of operation, 0 on success, otherwise error code | ||
| 23 | */ | ||
| 24 | Result WaitSynchronization(bool* wait) override { | ||
| 25 | // TODO(bunnei): ImplementMe | 20 | // TODO(bunnei): ImplementMe |
| 26 | ERROR_LOG(OSHLE, "(UNIMPLEMENTED)"); | 21 | ERROR_LOG(OSHLE, "(UNIMPLEMENTED)"); |
| 27 | return 0; | 22 | return UnimplementedFunction(ErrorModule::OS); |
| 28 | } | 23 | } |
| 29 | 24 | ||
| 30 | u32 base_address; ///< Address of shared memory block in RAM | 25 | u32 base_address; ///< Address of shared memory block in RAM |
| @@ -48,11 +43,6 @@ SharedMemory* CreateSharedMemory(Handle& handle, const std::string& name) { | |||
| 48 | return shared_memory; | 43 | return shared_memory; |
| 49 | } | 44 | } |
| 50 | 45 | ||
| 51 | /** | ||
| 52 | * Creates a shared memory object | ||
| 53 | * @param name Optional name of shared memory object | ||
| 54 | * @return Handle of newly created shared memory object | ||
| 55 | */ | ||
| 56 | Handle CreateSharedMemory(const std::string& name) { | 46 | Handle CreateSharedMemory(const std::string& name) { |
| 57 | Handle handle; | 47 | Handle handle; |
| 58 | CreateSharedMemory(handle, name); | 48 | CreateSharedMemory(handle, name); |
| @@ -67,39 +57,36 @@ Handle CreateSharedMemory(const std::string& name) { | |||
| 67 | * @param other_permissions Memory block map other permissions (specified by SVC field) | 57 | * @param other_permissions Memory block map other permissions (specified by SVC field) |
| 68 | * @return Result of operation, 0 on success, otherwise error code | 58 | * @return Result of operation, 0 on success, otherwise error code |
| 69 | */ | 59 | */ |
| 70 | Result MapSharedMemory(u32 handle, u32 address, MemoryPermission permissions, | 60 | ResultCode MapSharedMemory(u32 handle, u32 address, MemoryPermission permissions, |
| 71 | MemoryPermission other_permissions) { | 61 | MemoryPermission other_permissions) { |
| 72 | 62 | ||
| 73 | if (address < Memory::SHARED_MEMORY_VADDR || address >= Memory::SHARED_MEMORY_VADDR_END) { | 63 | if (address < Memory::SHARED_MEMORY_VADDR || address >= Memory::SHARED_MEMORY_VADDR_END) { |
| 74 | ERROR_LOG(KERNEL, "cannot map handle=0x%08X, address=0x%08X outside of shared mem bounds!", | 64 | ERROR_LOG(KERNEL, "cannot map handle=0x%08X, address=0x%08X outside of shared mem bounds!", |
| 75 | handle, address); | 65 | handle, address); |
| 76 | return -1; | 66 | return ResultCode(ErrorDescription::InvalidAddress, ErrorModule::Kernel, |
| 67 | ErrorSummary::InvalidArgument, ErrorLevel::Permanent); | ||
| 77 | } | 68 | } |
| 78 | SharedMemory* shared_memory = Kernel::g_object_pool.GetFast<SharedMemory>(handle); | 69 | SharedMemory* shared_memory = Kernel::g_object_pool.Get<SharedMemory>(handle); |
| 79 | _assert_msg_(KERNEL, (shared_memory != nullptr), "handle 0x%08X is not valid!", handle); | 70 | if (shared_memory == nullptr) return InvalidHandle(ErrorModule::Kernel); |
| 80 | 71 | ||
| 81 | shared_memory->base_address = address; | 72 | shared_memory->base_address = address; |
| 82 | shared_memory->permissions = permissions; | 73 | shared_memory->permissions = permissions; |
| 83 | shared_memory->other_permissions = other_permissions; | 74 | shared_memory->other_permissions = other_permissions; |
| 84 | 75 | ||
| 85 | return 0; | 76 | return RESULT_SUCCESS; |
| 86 | } | 77 | } |
| 87 | 78 | ||
| 88 | /** | 79 | ResultVal<u8*> GetSharedMemoryPointer(Handle handle, u32 offset) { |
| 89 | * Gets a pointer to the shared memory block | 80 | SharedMemory* shared_memory = Kernel::g_object_pool.Get<SharedMemory>(handle); |
| 90 | * @param handle Shared memory block handle | 81 | if (shared_memory == nullptr) return InvalidHandle(ErrorModule::Kernel); |
| 91 | * @param offset Offset from the start of the shared memory block to get pointer | ||
| 92 | * @return Pointer to the shared memory block from the specified offset | ||
| 93 | */ | ||
| 94 | u8* GetSharedMemoryPointer(Handle handle, u32 offset) { | ||
| 95 | SharedMemory* shared_memory = Kernel::g_object_pool.GetFast<SharedMemory>(handle); | ||
| 96 | _assert_msg_(KERNEL, (shared_memory != nullptr), "handle 0x%08X is not valid!", handle); | ||
| 97 | 82 | ||
| 98 | if (0 != shared_memory->base_address) | 83 | if (0 != shared_memory->base_address) |
| 99 | return Memory::GetPointer(shared_memory->base_address + offset); | 84 | return MakeResult<u8*>(Memory::GetPointer(shared_memory->base_address + offset)); |
| 100 | 85 | ||
| 101 | ERROR_LOG(KERNEL, "memory block handle=0x%08X not mapped!", handle); | 86 | ERROR_LOG(KERNEL, "memory block handle=0x%08X not mapped!", handle); |
| 102 | return nullptr; | 87 | // TODO(yuriks): Verify error code. |
| 88 | return ResultCode(ErrorDescription::InvalidAddress, ErrorModule::Kernel, | ||
| 89 | ErrorSummary::InvalidState, ErrorLevel::Permanent); | ||
| 103 | } | 90 | } |
| 104 | 91 | ||
| 105 | } // namespace | 92 | } // namespace |
diff --git a/src/core/hle/kernel/shared_memory.h b/src/core/hle/kernel/shared_memory.h index 0aec03538..304cf5b67 100644 --- a/src/core/hle/kernel/shared_memory.h +++ b/src/core/hle/kernel/shared_memory.h | |||
| @@ -32,9 +32,8 @@ Handle CreateSharedMemory(const std::string& name="Unknown"); | |||
| 32 | * @param address Address in system memory to map shared memory block to | 32 | * @param address Address in system memory to map shared memory block to |
| 33 | * @param permissions Memory block map permissions (specified by SVC field) | 33 | * @param permissions Memory block map permissions (specified by SVC field) |
| 34 | * @param other_permissions Memory block map other permissions (specified by SVC field) | 34 | * @param other_permissions Memory block map other permissions (specified by SVC field) |
| 35 | * @return Result of operation, 0 on success, otherwise error code | ||
| 36 | */ | 35 | */ |
| 37 | Result MapSharedMemory(u32 handle, u32 address, MemoryPermission permissions, | 36 | ResultCode MapSharedMemory(Handle handle, u32 address, MemoryPermission permissions, |
| 38 | MemoryPermission other_permissions); | 37 | MemoryPermission other_permissions); |
| 39 | 38 | ||
| 40 | /** | 39 | /** |
| @@ -43,6 +42,6 @@ Result MapSharedMemory(u32 handle, u32 address, MemoryPermission permissions, | |||
| 43 | * @param offset Offset from the start of the shared memory block to get pointer | 42 | * @param offset Offset from the start of the shared memory block to get pointer |
| 44 | * @return Pointer to the shared memory block from the specified offset | 43 | * @return Pointer to the shared memory block from the specified offset |
| 45 | */ | 44 | */ |
| 46 | u8* GetSharedMemoryPointer(Handle handle, u32 offset); | 45 | ResultVal<u8*> GetSharedMemoryPointer(Handle handle, u32 offset); |
| 47 | 46 | ||
| 48 | } // namespace | 47 | } // namespace |
diff --git a/src/core/hle/kernel/thread.cpp b/src/core/hle/kernel/thread.cpp index cc70cbca7..f3f54a4e9 100644 --- a/src/core/hle/kernel/thread.cpp +++ b/src/core/hle/kernel/thread.cpp | |||
| @@ -11,10 +11,11 @@ | |||
| 11 | #include "common/thread_queue_list.h" | 11 | #include "common/thread_queue_list.h" |
| 12 | 12 | ||
| 13 | #include "core/core.h" | 13 | #include "core/core.h" |
| 14 | #include "core/mem_map.h" | ||
| 15 | #include "core/hle/hle.h" | 14 | #include "core/hle/hle.h" |
| 16 | #include "core/hle/kernel/kernel.h" | 15 | #include "core/hle/kernel/kernel.h" |
| 17 | #include "core/hle/kernel/thread.h" | 16 | #include "core/hle/kernel/thread.h" |
| 17 | #include "core/hle/result.h" | ||
| 18 | #include "core/mem_map.h" | ||
| 18 | 19 | ||
| 19 | namespace Kernel { | 20 | namespace Kernel { |
| 20 | 21 | ||
| @@ -33,21 +34,17 @@ public: | |||
| 33 | inline bool IsWaiting() const { return (status & THREADSTATUS_WAIT) != 0; } | 34 | inline bool IsWaiting() const { return (status & THREADSTATUS_WAIT) != 0; } |
| 34 | inline bool IsSuspended() const { return (status & THREADSTATUS_SUSPEND) != 0; } | 35 | inline bool IsSuspended() const { return (status & THREADSTATUS_SUSPEND) != 0; } |
| 35 | 36 | ||
| 36 | /** | 37 | ResultVal<bool> WaitSynchronization() override { |
| 37 | * Wait for kernel object to synchronize | 38 | const bool wait = status != THREADSTATUS_DORMANT; |
| 38 | * @param wait Boolean wait set if current thread should wait as a result of sync operation | 39 | if (wait) { |
| 39 | * @return Result of operation, 0 on success, otherwise error code | ||
| 40 | */ | ||
| 41 | Result WaitSynchronization(bool* wait) override { | ||
| 42 | if (status != THREADSTATUS_DORMANT) { | ||
| 43 | Handle thread = GetCurrentThreadHandle(); | 40 | Handle thread = GetCurrentThreadHandle(); |
| 44 | if (std::find(waiting_threads.begin(), waiting_threads.end(), thread) == waiting_threads.end()) { | 41 | if (std::find(waiting_threads.begin(), waiting_threads.end(), thread) == waiting_threads.end()) { |
| 45 | waiting_threads.push_back(thread); | 42 | waiting_threads.push_back(thread); |
| 46 | } | 43 | } |
| 47 | WaitCurrentThread(WAITTYPE_THREADEND, this->GetHandle()); | 44 | WaitCurrentThread(WAITTYPE_THREADEND, this->GetHandle()); |
| 48 | *wait = true; | ||
| 49 | } | 45 | } |
| 50 | return 0; | 46 | |
| 47 | return MakeResult<bool>(wait); | ||
| 51 | } | 48 | } |
| 52 | 49 | ||
| 53 | ThreadContext context; | 50 | ThreadContext context; |
| @@ -144,27 +141,22 @@ void ChangeReadyState(Thread* t, bool ready) { | |||
| 144 | } | 141 | } |
| 145 | 142 | ||
| 146 | /// Verify that a thread has not been released from waiting | 143 | /// Verify that a thread has not been released from waiting |
| 147 | inline bool VerifyWait(const Handle& handle, WaitType type, Handle wait_handle) { | 144 | inline bool VerifyWait(const Thread* thread, WaitType type, Handle wait_handle) { |
| 148 | Thread* thread = g_object_pool.GetFast<Thread>(handle); | 145 | _dbg_assert_(KERNEL, thread != nullptr); |
| 149 | _assert_msg_(KERNEL, (thread != nullptr), "called, but thread is nullptr!"); | 146 | return type == thread->wait_type && wait_handle == thread->wait_handle; |
| 150 | |||
| 151 | if (type != thread->wait_type || wait_handle != thread->wait_handle) | ||
| 152 | return false; | ||
| 153 | |||
| 154 | return true; | ||
| 155 | } | 147 | } |
| 156 | 148 | ||
| 157 | /// Stops the current thread | 149 | /// Stops the current thread |
| 158 | void StopThread(Handle handle, const char* reason) { | 150 | ResultCode StopThread(Handle handle, const char* reason) { |
| 159 | Thread* thread = g_object_pool.GetFast<Thread>(handle); | 151 | Thread* thread = g_object_pool.Get<Thread>(handle); |
| 160 | _assert_msg_(KERNEL, (thread != nullptr), "called, but thread is nullptr!"); | 152 | if (thread == nullptr) return InvalidHandle(ErrorModule::Kernel); |
| 161 | 153 | ||
| 162 | ChangeReadyState(thread, false); | 154 | ChangeReadyState(thread, false); |
| 163 | thread->status = THREADSTATUS_DORMANT; | 155 | thread->status = THREADSTATUS_DORMANT; |
| 164 | for (size_t i = 0; i < thread->waiting_threads.size(); ++i) { | 156 | for (Handle waiting_handle : thread->waiting_threads) { |
| 165 | const Handle waiting_thread = thread->waiting_threads[i]; | 157 | Thread* waiting_thread = g_object_pool.Get<Thread>(waiting_handle); |
| 166 | if (VerifyWait(waiting_thread, WAITTYPE_THREADEND, handle)) { | 158 | if (VerifyWait(waiting_thread, WAITTYPE_THREADEND, handle)) { |
| 167 | ResumeThreadFromWait(waiting_thread); | 159 | ResumeThreadFromWait(waiting_handle); |
| 168 | } | 160 | } |
| 169 | } | 161 | } |
| 170 | thread->waiting_threads.clear(); | 162 | thread->waiting_threads.clear(); |
| @@ -172,6 +164,8 @@ void StopThread(Handle handle, const char* reason) { | |||
| 172 | // Stopped threads are never waiting. | 164 | // Stopped threads are never waiting. |
| 173 | thread->wait_type = WAITTYPE_NONE; | 165 | thread->wait_type = WAITTYPE_NONE; |
| 174 | thread->wait_handle = 0; | 166 | thread->wait_handle = 0; |
| 167 | |||
| 168 | return RESULT_SUCCESS; | ||
| 175 | } | 169 | } |
| 176 | 170 | ||
| 177 | /// Changes a threads state | 171 | /// Changes a threads state |
| @@ -195,13 +189,15 @@ Handle ArbitrateHighestPriorityThread(u32 arbiter, u32 address) { | |||
| 195 | s32 priority = THREADPRIO_LOWEST; | 189 | s32 priority = THREADPRIO_LOWEST; |
| 196 | 190 | ||
| 197 | // Iterate through threads, find highest priority thread that is waiting to be arbitrated... | 191 | // Iterate through threads, find highest priority thread that is waiting to be arbitrated... |
| 198 | for (const auto& handle : thread_queue) { | 192 | for (Handle handle : thread_queue) { |
| 193 | Thread* thread = g_object_pool.Get<Thread>(handle); | ||
| 199 | 194 | ||
| 200 | // TODO(bunnei): Verify arbiter address... | 195 | // TODO(bunnei): Verify arbiter address... |
| 201 | if (!VerifyWait(handle, WAITTYPE_ARB, arbiter)) | 196 | if (!VerifyWait(thread, WAITTYPE_ARB, arbiter)) |
| 202 | continue; | 197 | continue; |
| 203 | 198 | ||
| 204 | Thread* thread = g_object_pool.GetFast<Thread>(handle); | 199 | if (thread == nullptr) |
| 200 | continue; // TODO(yuriks): Thread handle will hang around forever. Should clean up. | ||
| 205 | if(thread->current_priority <= priority) { | 201 | if(thread->current_priority <= priority) { |
| 206 | highest_priority_thread = handle; | 202 | highest_priority_thread = handle; |
| 207 | priority = thread->current_priority; | 203 | priority = thread->current_priority; |
| @@ -218,10 +214,11 @@ Handle ArbitrateHighestPriorityThread(u32 arbiter, u32 address) { | |||
| 218 | void ArbitrateAllThreads(u32 arbiter, u32 address) { | 214 | void ArbitrateAllThreads(u32 arbiter, u32 address) { |
| 219 | 215 | ||
| 220 | // Iterate through threads, find highest priority thread that is waiting to be arbitrated... | 216 | // Iterate through threads, find highest priority thread that is waiting to be arbitrated... |
| 221 | for (const auto& handle : thread_queue) { | 217 | for (Handle handle : thread_queue) { |
| 218 | Thread* thread = g_object_pool.Get<Thread>(handle); | ||
| 222 | 219 | ||
| 223 | // TODO(bunnei): Verify arbiter address... | 220 | // TODO(bunnei): Verify arbiter address... |
| 224 | if (VerifyWait(handle, WAITTYPE_ARB, arbiter)) | 221 | if (VerifyWait(thread, WAITTYPE_ARB, arbiter)) |
| 225 | ResumeThreadFromWait(handle); | 222 | ResumeThreadFromWait(handle); |
| 226 | } | 223 | } |
| 227 | } | 224 | } |
| @@ -272,7 +269,7 @@ Thread* NextThread() { | |||
| 272 | if (next == 0) { | 269 | if (next == 0) { |
| 273 | return nullptr; | 270 | return nullptr; |
| 274 | } | 271 | } |
| 275 | return Kernel::g_object_pool.GetFast<Thread>(next); | 272 | return Kernel::g_object_pool.Get<Thread>(next); |
| 276 | } | 273 | } |
| 277 | 274 | ||
| 278 | /** | 275 | /** |
| @@ -289,8 +286,7 @@ void WaitCurrentThread(WaitType wait_type, Handle wait_handle) { | |||
| 289 | 286 | ||
| 290 | /// Resumes a thread from waiting by marking it as "ready" | 287 | /// Resumes a thread from waiting by marking it as "ready" |
| 291 | void ResumeThreadFromWait(Handle handle) { | 288 | void ResumeThreadFromWait(Handle handle) { |
| 292 | u32 error; | 289 | Thread* thread = Kernel::g_object_pool.Get<Thread>(handle); |
| 293 | Thread* thread = Kernel::g_object_pool.Get<Thread>(handle, error); | ||
| 294 | if (thread) { | 290 | if (thread) { |
| 295 | thread->status &= ~THREADSTATUS_WAIT; | 291 | thread->status &= ~THREADSTATUS_WAIT; |
| 296 | if (!(thread->status & (THREADSTATUS_WAITSUSPEND | THREADSTATUS_DORMANT | THREADSTATUS_DEAD))) { | 292 | if (!(thread->status & (THREADSTATUS_WAITSUSPEND | THREADSTATUS_DORMANT | THREADSTATUS_DEAD))) { |
| @@ -378,19 +374,23 @@ Handle CreateThread(const char* name, u32 entry_point, s32 priority, u32 arg, s3 | |||
| 378 | } | 374 | } |
| 379 | 375 | ||
| 380 | /// Get the priority of the thread specified by handle | 376 | /// Get the priority of the thread specified by handle |
| 381 | u32 GetThreadPriority(const Handle handle) { | 377 | ResultVal<u32> GetThreadPriority(const Handle handle) { |
| 382 | Thread* thread = g_object_pool.GetFast<Thread>(handle); | 378 | Thread* thread = g_object_pool.Get<Thread>(handle); |
| 383 | _assert_msg_(KERNEL, (thread != nullptr), "called, but thread is nullptr!"); | 379 | if (thread == nullptr) return InvalidHandle(ErrorModule::Kernel); |
| 384 | return thread->current_priority; | 380 | |
| 381 | return MakeResult<u32>(thread->current_priority); | ||
| 385 | } | 382 | } |
| 386 | 383 | ||
| 387 | /// Set the priority of the thread specified by handle | 384 | /// Set the priority of the thread specified by handle |
| 388 | Result SetThreadPriority(Handle handle, s32 priority) { | 385 | ResultCode SetThreadPriority(Handle handle, s32 priority) { |
| 389 | Thread* thread = nullptr; | 386 | Thread* thread = nullptr; |
| 390 | if (!handle) { | 387 | if (!handle) { |
| 391 | thread = GetCurrentThread(); // TODO(bunnei): Is this correct behavior? | 388 | thread = GetCurrentThread(); // TODO(bunnei): Is this correct behavior? |
| 392 | } else { | 389 | } else { |
| 393 | thread = g_object_pool.GetFast<Thread>(handle); | 390 | thread = g_object_pool.Get<Thread>(handle); |
| 391 | if (thread == nullptr) { | ||
| 392 | return InvalidHandle(ErrorModule::Kernel); | ||
| 393 | } | ||
| 394 | } | 394 | } |
| 395 | _assert_msg_(KERNEL, (thread != nullptr), "called, but thread is nullptr!"); | 395 | _assert_msg_(KERNEL, (thread != nullptr), "called, but thread is nullptr!"); |
| 396 | 396 | ||
| @@ -417,7 +417,7 @@ Result SetThreadPriority(Handle handle, s32 priority) { | |||
| 417 | thread_ready_queue.push_back(thread->current_priority, handle); | 417 | thread_ready_queue.push_back(thread->current_priority, handle); |
| 418 | } | 418 | } |
| 419 | 419 | ||
| 420 | return 0; | 420 | return RESULT_SUCCESS; |
| 421 | } | 421 | } |
| 422 | 422 | ||
| 423 | /// Sets up the primary application thread | 423 | /// Sets up the primary application thread |
diff --git a/src/core/hle/kernel/thread.h b/src/core/hle/kernel/thread.h index 2a43797ee..ce63a70d3 100644 --- a/src/core/hle/kernel/thread.h +++ b/src/core/hle/kernel/thread.h | |||
| @@ -6,6 +6,7 @@ | |||
| 6 | 6 | ||
| 7 | #include "common/common_types.h" | 7 | #include "common/common_types.h" |
| 8 | #include "core/hle/kernel/kernel.h" | 8 | #include "core/hle/kernel/kernel.h" |
| 9 | #include "core/hle/result.h" | ||
| 9 | 10 | ||
| 10 | enum ThreadPriority { | 11 | enum ThreadPriority { |
| 11 | THREADPRIO_HIGHEST = 0, ///< Highest thread priority | 12 | THREADPRIO_HIGHEST = 0, ///< Highest thread priority |
| @@ -55,7 +56,7 @@ Handle SetupMainThread(s32 priority, int stack_size=Kernel::DEFAULT_STACK_SIZE); | |||
| 55 | void Reschedule(); | 56 | void Reschedule(); |
| 56 | 57 | ||
| 57 | /// Stops the current thread | 58 | /// Stops the current thread |
| 58 | void StopThread(Handle thread, const char* reason); | 59 | ResultCode StopThread(Handle thread, const char* reason); |
| 59 | 60 | ||
| 60 | /// Resumes a thread from waiting by marking it as "ready" | 61 | /// Resumes a thread from waiting by marking it as "ready" |
| 61 | void ResumeThreadFromWait(Handle handle); | 62 | void ResumeThreadFromWait(Handle handle); |
| @@ -80,10 +81,10 @@ void WaitCurrentThread(WaitType wait_type, Handle wait_handle=GetCurrentThreadHa | |||
| 80 | void WaitThread_Synchronization(); | 81 | void WaitThread_Synchronization(); |
| 81 | 82 | ||
| 82 | /// Get the priority of the thread specified by handle | 83 | /// Get the priority of the thread specified by handle |
| 83 | u32 GetThreadPriority(const Handle handle); | 84 | ResultVal<u32> GetThreadPriority(const Handle handle); |
| 84 | 85 | ||
| 85 | /// Set the priority of the thread specified by handle | 86 | /// Set the priority of the thread specified by handle |
| 86 | Result SetThreadPriority(Handle handle, s32 priority); | 87 | ResultCode SetThreadPriority(Handle handle, s32 priority); |
| 87 | 88 | ||
| 88 | /// Initialize threading | 89 | /// Initialize threading |
| 89 | void ThreadingInit(); | 90 | void ThreadingInit(); |