diff options
| author | 2015-02-02 13:04:04 -0500 | |
|---|---|---|
| committer | 2015-02-02 13:04:04 -0500 | |
| commit | 7f730ed158bc9bba064100b9644b318134ef0bb3 (patch) | |
| tree | c4181a69ff882e1af1b7d65bf3596a6cb3dd88b9 /src/core/hle/svc.cpp | |
| parent | Merge pull request #517 from bunnei/blend-factors (diff) | |
| parent | Kernel: Stop creating useless Handles during object creation (diff) | |
| download | yuzu-7f730ed158bc9bba064100b9644b318134ef0bb3.tar.gz yuzu-7f730ed158bc9bba064100b9644b318134ef0bb3.tar.xz yuzu-7f730ed158bc9bba064100b9644b318134ef0bb3.zip | |
Merge pull request #523 from yuriks/kernel-lifetime5
Kernel Lifetime Reform Pt. 5: The Reckoning
Diffstat (limited to 'src/core/hle/svc.cpp')
| -rw-r--r-- | src/core/hle/svc.cpp | 58 |
1 files changed, 35 insertions, 23 deletions
diff --git a/src/core/hle/svc.cpp b/src/core/hle/svc.cpp index 88813c2ce..34a27917f 100644 --- a/src/core/hle/svc.cpp +++ b/src/core/hle/svc.cpp | |||
| @@ -30,6 +30,11 @@ using Kernel::ERR_INVALID_HANDLE; | |||
| 30 | 30 | ||
| 31 | namespace SVC { | 31 | namespace SVC { |
| 32 | 32 | ||
| 33 | const ResultCode ERR_NOT_FOUND(ErrorDescription::NotFound, ErrorModule::Kernel, | ||
| 34 | ErrorSummary::NotFound, ErrorLevel::Permanent); // 0xD88007FA | ||
| 35 | const ResultCode ERR_PORT_NAME_TOO_LONG(ErrorDescription(30), ErrorModule::OS, | ||
| 36 | ErrorSummary::InvalidArgument, ErrorLevel::Usage); // 0xE0E0181E | ||
| 37 | |||
| 33 | /// An invalid result code that is meant to be overwritten when a thread resumes from waiting | 38 | /// An invalid result code that is meant to be overwritten when a thread resumes from waiting |
| 34 | const ResultCode RESULT_INVALID(0xDEADC0DE); | 39 | const ResultCode RESULT_INVALID(0xDEADC0DE); |
| 35 | 40 | ||
| @@ -94,14 +99,21 @@ static ResultCode MapMemoryBlock(Handle handle, u32 addr, u32 permissions, u32 o | |||
| 94 | } | 99 | } |
| 95 | 100 | ||
| 96 | /// Connect to an OS service given the port name, returns the handle to the port to out | 101 | /// Connect to an OS service given the port name, returns the handle to the port to out |
| 97 | static ResultCode ConnectToPort(Handle* out, const char* port_name) { | 102 | static ResultCode ConnectToPort(Handle* out_handle, const char* port_name) { |
| 98 | Service::Interface* service = Service::g_manager->FetchFromPortName(port_name); | 103 | if (port_name == nullptr) |
| 104 | return ERR_NOT_FOUND; | ||
| 105 | if (std::strlen(port_name) > 11) | ||
| 106 | return ERR_PORT_NAME_TOO_LONG; | ||
| 99 | 107 | ||
| 100 | LOG_TRACE(Kernel_SVC, "called port_name=%s", port_name); | 108 | LOG_TRACE(Kernel_SVC, "called port_name=%s", port_name); |
| 101 | _assert_msg_(KERNEL, (service != nullptr), "called, but service is not implemented!"); | ||
| 102 | 109 | ||
| 103 | *out = service->GetHandle(); | 110 | auto it = Service::g_kernel_named_ports.find(port_name); |
| 111 | if (it == Service::g_kernel_named_ports.end()) { | ||
| 112 | LOG_WARNING(Kernel_SVC, "tried to connect to unknown port: %s", port_name); | ||
| 113 | return ERR_NOT_FOUND; | ||
| 114 | } | ||
| 104 | 115 | ||
| 116 | CASCADE_RESULT(*out_handle, Kernel::g_handle_table.Create(it->second)); | ||
| 105 | return RESULT_SUCCESS; | 117 | return RESULT_SUCCESS; |
| 106 | } | 118 | } |
| 107 | 119 | ||
| @@ -119,9 +131,8 @@ static ResultCode SendSyncRequest(Handle handle) { | |||
| 119 | 131 | ||
| 120 | /// Close a handle | 132 | /// Close a handle |
| 121 | static ResultCode CloseHandle(Handle handle) { | 133 | static ResultCode CloseHandle(Handle handle) { |
| 122 | // ImplementMe | 134 | LOG_TRACE(Kernel_SVC, "Closing handle 0x%08X", handle); |
| 123 | LOG_ERROR(Kernel_SVC, "(UNIMPLEMENTED) called handle=0x%08X", handle); | 135 | return Kernel::g_handle_table.Close(handle); |
| 124 | return RESULT_SUCCESS; | ||
| 125 | } | 136 | } |
| 126 | 137 | ||
| 127 | /// Wait for a handle to synchronize, timeout after the specified nanoseconds | 138 | /// Wait for a handle to synchronize, timeout after the specified nanoseconds |
| @@ -140,7 +151,7 @@ static ResultCode WaitSynchronization1(Handle handle, s64 nano_seconds) { | |||
| 140 | Kernel::WaitCurrentThread_WaitSynchronization(object, false, false); | 151 | Kernel::WaitCurrentThread_WaitSynchronization(object, false, false); |
| 141 | 152 | ||
| 142 | // Create an event to wake the thread up after the specified nanosecond delay has passed | 153 | // Create an event to wake the thread up after the specified nanosecond delay has passed |
| 143 | Kernel::WakeThreadAfterDelay(Kernel::GetCurrentThread(), nano_seconds); | 154 | Kernel::GetCurrentThread()->WakeAfterDelay(nano_seconds); |
| 144 | 155 | ||
| 145 | HLE::Reschedule(__func__); | 156 | HLE::Reschedule(__func__); |
| 146 | 157 | ||
| @@ -216,7 +227,7 @@ static ResultCode WaitSynchronizationN(s32* out, Handle* handles, s32 handle_cou | |||
| 216 | } | 227 | } |
| 217 | 228 | ||
| 218 | // Create an event to wake the thread up after the specified nanosecond delay has passed | 229 | // Create an event to wake the thread up after the specified nanosecond delay has passed |
| 219 | Kernel::WakeThreadAfterDelay(Kernel::GetCurrentThread(), nano_seconds); | 230 | Kernel::GetCurrentThread()->WakeAfterDelay(nano_seconds); |
| 220 | 231 | ||
| 221 | HLE::Reschedule(__func__); | 232 | HLE::Reschedule(__func__); |
| 222 | 233 | ||
| @@ -250,7 +261,7 @@ static ResultCode WaitSynchronizationN(s32* out, Handle* handles, s32 handle_cou | |||
| 250 | static ResultCode CreateAddressArbiter(Handle* out_handle) { | 261 | static ResultCode CreateAddressArbiter(Handle* out_handle) { |
| 251 | using Kernel::AddressArbiter; | 262 | using Kernel::AddressArbiter; |
| 252 | 263 | ||
| 253 | CASCADE_RESULT(SharedPtr<AddressArbiter> arbiter, AddressArbiter::Create()); | 264 | SharedPtr<AddressArbiter> arbiter = AddressArbiter::Create(); |
| 254 | CASCADE_RESULT(*out_handle, Kernel::g_handle_table.Create(std::move(arbiter))); | 265 | CASCADE_RESULT(*out_handle, Kernel::g_handle_table.Create(std::move(arbiter))); |
| 255 | LOG_TRACE(Kernel_SVC, "returned handle=0x%08X", *out_handle); | 266 | LOG_TRACE(Kernel_SVC, "returned handle=0x%08X", *out_handle); |
| 256 | return RESULT_SUCCESS; | 267 | return RESULT_SUCCESS; |
| @@ -355,7 +366,7 @@ static ResultCode SetThreadPriority(Handle handle, s32 priority) { | |||
| 355 | static ResultCode CreateMutex(Handle* out_handle, u32 initial_locked) { | 366 | static ResultCode CreateMutex(Handle* out_handle, u32 initial_locked) { |
| 356 | using Kernel::Mutex; | 367 | using Kernel::Mutex; |
| 357 | 368 | ||
| 358 | CASCADE_RESULT(SharedPtr<Mutex> mutex, Mutex::Create(initial_locked != 0)); | 369 | SharedPtr<Mutex> mutex = Mutex::Create(initial_locked != 0); |
| 359 | CASCADE_RESULT(*out_handle, Kernel::g_handle_table.Create(std::move(mutex))); | 370 | CASCADE_RESULT(*out_handle, Kernel::g_handle_table.Create(std::move(mutex))); |
| 360 | 371 | ||
| 361 | LOG_TRACE(Kernel_SVC, "called initial_locked=%s : created handle=0x%08X", | 372 | LOG_TRACE(Kernel_SVC, "called initial_locked=%s : created handle=0x%08X", |
| @@ -423,7 +434,9 @@ static ResultCode QueryMemory(void* info, void* out, u32 addr) { | |||
| 423 | 434 | ||
| 424 | /// Create an event | 435 | /// Create an event |
| 425 | static ResultCode CreateEvent(Handle* out_handle, u32 reset_type) { | 436 | static ResultCode CreateEvent(Handle* out_handle, u32 reset_type) { |
| 426 | CASCADE_RESULT(auto evt, Kernel::Event::Create(static_cast<ResetType>(reset_type))); | 437 | using Kernel::Event; |
| 438 | |||
| 439 | SharedPtr<Event> evt = Kernel::Event::Create(static_cast<ResetType>(reset_type)); | ||
| 427 | CASCADE_RESULT(*out_handle, Kernel::g_handle_table.Create(std::move(evt))); | 440 | CASCADE_RESULT(*out_handle, Kernel::g_handle_table.Create(std::move(evt))); |
| 428 | 441 | ||
| 429 | LOG_TRACE(Kernel_SVC, "called reset_type=0x%08X : created handle=0x%08X", | 442 | LOG_TRACE(Kernel_SVC, "called reset_type=0x%08X : created handle=0x%08X", |
| @@ -433,19 +446,17 @@ static ResultCode CreateEvent(Handle* out_handle, u32 reset_type) { | |||
| 433 | 446 | ||
| 434 | /// Duplicates a kernel handle | 447 | /// Duplicates a kernel handle |
| 435 | static ResultCode DuplicateHandle(Handle* out, Handle handle) { | 448 | static ResultCode DuplicateHandle(Handle* out, Handle handle) { |
| 436 | ResultVal<Handle> out_h = Kernel::g_handle_table.Duplicate(handle); | 449 | CASCADE_RESULT(*out, Kernel::g_handle_table.Duplicate(handle)); |
| 437 | if (out_h.Succeeded()) { | 450 | LOG_TRACE(Kernel_SVC, "duplicated 0x%08X to 0x%08X", handle, *out); |
| 438 | *out = *out_h; | 451 | return RESULT_SUCCESS; |
| 439 | LOG_TRACE(Kernel_SVC, "duplicated 0x%08X to 0x%08X", handle, *out); | ||
| 440 | } | ||
| 441 | return out_h.Code(); | ||
| 442 | } | 452 | } |
| 443 | 453 | ||
| 444 | /// Signals an event | 454 | /// Signals an event |
| 445 | static ResultCode SignalEvent(Handle handle) { | 455 | static ResultCode SignalEvent(Handle handle) { |
| 456 | using Kernel::Event; | ||
| 446 | LOG_TRACE(Kernel_SVC, "called event=0x%08X", handle); | 457 | LOG_TRACE(Kernel_SVC, "called event=0x%08X", handle); |
| 447 | 458 | ||
| 448 | auto evt = Kernel::g_handle_table.Get<Kernel::Event>(handle); | 459 | SharedPtr<Event> evt = Kernel::g_handle_table.Get<Kernel::Event>(handle); |
| 449 | if (evt == nullptr) | 460 | if (evt == nullptr) |
| 450 | return ERR_INVALID_HANDLE; | 461 | return ERR_INVALID_HANDLE; |
| 451 | 462 | ||
| @@ -456,9 +467,10 @@ static ResultCode SignalEvent(Handle handle) { | |||
| 456 | 467 | ||
| 457 | /// Clears an event | 468 | /// Clears an event |
| 458 | static ResultCode ClearEvent(Handle handle) { | 469 | static ResultCode ClearEvent(Handle handle) { |
| 470 | using Kernel::Event; | ||
| 459 | LOG_TRACE(Kernel_SVC, "called event=0x%08X", handle); | 471 | LOG_TRACE(Kernel_SVC, "called event=0x%08X", handle); |
| 460 | 472 | ||
| 461 | auto evt = Kernel::g_handle_table.Get<Kernel::Event>(handle); | 473 | SharedPtr<Event> evt = Kernel::g_handle_table.Get<Kernel::Event>(handle); |
| 462 | if (evt == nullptr) | 474 | if (evt == nullptr) |
| 463 | return ERR_INVALID_HANDLE; | 475 | return ERR_INVALID_HANDLE; |
| 464 | 476 | ||
| @@ -470,7 +482,7 @@ static ResultCode ClearEvent(Handle handle) { | |||
| 470 | static ResultCode CreateTimer(Handle* out_handle, u32 reset_type) { | 482 | static ResultCode CreateTimer(Handle* out_handle, u32 reset_type) { |
| 471 | using Kernel::Timer; | 483 | using Kernel::Timer; |
| 472 | 484 | ||
| 473 | CASCADE_RESULT(auto timer, Timer::Create(static_cast<ResetType>(reset_type))); | 485 | SharedPtr<Timer> timer = Timer::Create(static_cast<ResetType>(reset_type)); |
| 474 | CASCADE_RESULT(*out_handle, Kernel::g_handle_table.Create(std::move(timer))); | 486 | CASCADE_RESULT(*out_handle, Kernel::g_handle_table.Create(std::move(timer))); |
| 475 | 487 | ||
| 476 | LOG_TRACE(Kernel_SVC, "called reset_type=0x%08X : created handle=0x%08X", | 488 | LOG_TRACE(Kernel_SVC, "called reset_type=0x%08X : created handle=0x%08X", |
| @@ -528,7 +540,7 @@ static void SleepThread(s64 nanoseconds) { | |||
| 528 | Kernel::WaitCurrentThread_Sleep(); | 540 | Kernel::WaitCurrentThread_Sleep(); |
| 529 | 541 | ||
| 530 | // Create an event to wake the thread up after the specified nanosecond delay has passed | 542 | // Create an event to wake the thread up after the specified nanosecond delay has passed |
| 531 | Kernel::WakeThreadAfterDelay(Kernel::GetCurrentThread(), nanoseconds); | 543 | Kernel::GetCurrentThread()->WakeAfterDelay(nanoseconds); |
| 532 | 544 | ||
| 533 | HLE::Reschedule(__func__); | 545 | HLE::Reschedule(__func__); |
| 534 | } | 546 | } |
| @@ -544,7 +556,7 @@ static ResultCode CreateMemoryBlock(Handle* out_handle, u32 addr, u32 size, u32 | |||
| 544 | using Kernel::SharedMemory; | 556 | using Kernel::SharedMemory; |
| 545 | // TODO(Subv): Implement this function | 557 | // TODO(Subv): Implement this function |
| 546 | 558 | ||
| 547 | CASCADE_RESULT(auto shared_memory, SharedMemory::Create()); | 559 | SharedPtr<SharedMemory> shared_memory = SharedMemory::Create(); |
| 548 | CASCADE_RESULT(*out_handle, Kernel::g_handle_table.Create(std::move(shared_memory))); | 560 | CASCADE_RESULT(*out_handle, Kernel::g_handle_table.Create(std::move(shared_memory))); |
| 549 | 561 | ||
| 550 | LOG_WARNING(Kernel_SVC, "(STUBBED) called addr=0x%08X", addr); | 562 | LOG_WARNING(Kernel_SVC, "(STUBBED) called addr=0x%08X", addr); |