summaryrefslogtreecommitdiff
path: root/src/core/hle/svc.cpp
diff options
context:
space:
mode:
authorGravatar bunnei2015-02-02 13:04:04 -0500
committerGravatar bunnei2015-02-02 13:04:04 -0500
commit7f730ed158bc9bba064100b9644b318134ef0bb3 (patch)
treec4181a69ff882e1af1b7d65bf3596a6cb3dd88b9 /src/core/hle/svc.cpp
parentMerge pull request #517 from bunnei/blend-factors (diff)
parentKernel: Stop creating useless Handles during object creation (diff)
downloadyuzu-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.cpp58
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
31namespace SVC { 31namespace SVC {
32 32
33const ResultCode ERR_NOT_FOUND(ErrorDescription::NotFound, ErrorModule::Kernel,
34 ErrorSummary::NotFound, ErrorLevel::Permanent); // 0xD88007FA
35const 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
34const ResultCode RESULT_INVALID(0xDEADC0DE); 39const 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
97static ResultCode ConnectToPort(Handle* out, const char* port_name) { 102static 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
121static ResultCode CloseHandle(Handle handle) { 133static 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
250static ResultCode CreateAddressArbiter(Handle* out_handle) { 261static 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) {
355static ResultCode CreateMutex(Handle* out_handle, u32 initial_locked) { 366static 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
425static ResultCode CreateEvent(Handle* out_handle, u32 reset_type) { 436static 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
435static ResultCode DuplicateHandle(Handle* out, Handle handle) { 448static 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
445static ResultCode SignalEvent(Handle handle) { 455static 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
458static ResultCode ClearEvent(Handle handle) { 469static 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) {
470static ResultCode CreateTimer(Handle* out_handle, u32 reset_type) { 482static 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);