diff options
| author | 2014-05-27 22:41:09 -0400 | |
|---|---|---|
| committer | 2014-05-27 22:41:09 -0400 | |
| commit | 47e781e80a4bc0f37eb431a89aa36b27224185e7 (patch) | |
| tree | e152bda4fa900f205122da669cdb4e64171babc7 /src/core/hle/svc.cpp | |
| parent | APT_U: added event creation to Initialize method (diff) | |
| download | yuzu-47e781e80a4bc0f37eb431a89aa36b27224185e7.tar.gz yuzu-47e781e80a4bc0f37eb431a89aa36b27224185e7.tar.xz yuzu-47e781e80a4bc0f37eb431a89aa36b27224185e7.zip | |
svc: implemented WaitSynchronization1, WaitSynchronizationN, and CreateEvent
Diffstat (limited to 'src/core/hle/svc.cpp')
| -rw-r--r-- | src/core/hle/svc.cpp | 68 |
1 files changed, 54 insertions, 14 deletions
diff --git a/src/core/hle/svc.cpp b/src/core/hle/svc.cpp index e566036e5..8468c4fab 100644 --- a/src/core/hle/svc.cpp +++ b/src/core/hle/svc.cpp | |||
| @@ -9,6 +9,7 @@ | |||
| 9 | 9 | ||
| 10 | #include "core/mem_map.h" | 10 | #include "core/mem_map.h" |
| 11 | 11 | ||
| 12 | #include "core/hle/kernel/event.h" | ||
| 12 | #include "core/hle/kernel/kernel.h" | 13 | #include "core/hle/kernel/kernel.h" |
| 13 | #include "core/hle/kernel/mutex.h" | 14 | #include "core/hle/kernel/mutex.h" |
| 14 | #include "core/hle/kernel/thread.h" | 15 | #include "core/hle/kernel/thread.h" |
| @@ -16,7 +17,6 @@ | |||
| 16 | #include "core/hle/function_wrappers.h" | 17 | #include "core/hle/function_wrappers.h" |
| 17 | #include "core/hle/svc.h" | 18 | #include "core/hle/svc.h" |
| 18 | #include "core/hle/service/service.h" | 19 | #include "core/hle/service/service.h" |
| 19 | #include "core/hle/kernel/thread.h" | ||
| 20 | 20 | ||
| 21 | //////////////////////////////////////////////////////////////////////////////////////////////////// | 21 | //////////////////////////////////////////////////////////////////////////////////////////////////// |
| 22 | // Namespace SVC | 22 | // Namespace SVC |
| @@ -95,7 +95,7 @@ Result SendSyncRequest(Handle handle) { | |||
| 95 | bool wait = false; | 95 | bool wait = false; |
| 96 | Kernel::Object* object = Kernel::g_object_pool.GetFast<Kernel::Object>(handle); | 96 | Kernel::Object* object = Kernel::g_object_pool.GetFast<Kernel::Object>(handle); |
| 97 | 97 | ||
| 98 | DEBUG_LOG(SVC, "SendSyncRequest called handle=0x%08X"); | 98 | DEBUG_LOG(SVC, "SendSyncRequest called handle=0x%08X", handle); |
| 99 | _assert_msg_(KERNEL, object, "SendSyncRequest called, but kernel object is NULL!"); | 99 | _assert_msg_(KERNEL, object, "SendSyncRequest called, but kernel object is NULL!"); |
| 100 | 100 | ||
| 101 | Result res = object->SyncRequest(&wait); | 101 | Result res = object->SyncRequest(&wait); |
| @@ -115,24 +115,62 @@ Result CloseHandle(Handle handle) { | |||
| 115 | 115 | ||
| 116 | /// Wait for a handle to synchronize, timeout after the specified nanoseconds | 116 | /// Wait for a handle to synchronize, timeout after the specified nanoseconds |
| 117 | Result WaitSynchronization1(Handle handle, s64 nano_seconds) { | 117 | Result WaitSynchronization1(Handle handle, s64 nano_seconds) { |
| 118 | DEBUG_LOG(SVC, "(UNIMPLEMENTED) WaitSynchronization1 called handle=0x%08X, nanoseconds=%d", | 118 | // TODO(bunnei): Do something with nano_seconds, currently ignoring this |
| 119 | handle, nano_seconds); | 119 | bool wait = false; |
| 120 | Kernel::WaitCurrentThread(WAITTYPE_SYNCH); // TODO(bunnei): Is this correct? | 120 | |
| 121 | return 0; | 121 | Kernel::Object* object = Kernel::g_object_pool.GetFast<Kernel::Object>(handle); |
| 122 | |||
| 123 | DEBUG_LOG(SVC, "WaitSynchronization1 called handle=0x%08X, nanoseconds=%d", handle, | ||
| 124 | nano_seconds); | ||
| 125 | _assert_msg_(KERNEL, object, "WaitSynchronization1 called, but kernel object is NULL!"); | ||
| 126 | |||
| 127 | Result res = object->WaitSynchronization(&wait); | ||
| 128 | |||
| 129 | if (wait) { | ||
| 130 | Kernel::WaitCurrentThread(WAITTYPE_SYNCH); // TODO(bunnei): Is this correct? | ||
| 131 | } | ||
| 132 | |||
| 133 | return res; | ||
| 122 | } | 134 | } |
| 123 | 135 | ||
| 124 | /// Wait for the given handles to synchronize, timeout after the specified nanoseconds | 136 | /// Wait for the given handles to synchronize, timeout after the specified nanoseconds |
| 125 | Result WaitSynchronizationN(void* _out, void* _handles, u32 handle_count, u32 wait_all, s64 nano_seconds) { | 137 | Result WaitSynchronizationN(void* _out, void* _handles, u32 handle_count, u32 wait_all, |
| 138 | s64 nano_seconds) { | ||
| 139 | // TODO(bunnei): Do something with nano_seconds, currently ignoring this | ||
| 140 | |||
| 126 | s32* out = (s32*)_out; | 141 | s32* out = (s32*)_out; |
| 127 | Handle* handles = (Handle*)_handles; | 142 | Handle* handles = (Handle*)_handles; |
| 143 | bool unlock_all = true; | ||
| 128 | 144 | ||
| 129 | DEBUG_LOG(SVC, "(UNIMPLEMENTED) WaitSynchronizationN called handle_count=%d, wait_all=%s, nanoseconds=%d %s", | 145 | DEBUG_LOG(SVC, "WaitSynchronizationN called handle_count=%d, wait_all=%s, nanoseconds=%d", |
| 130 | handle_count, (wait_all ? "true" : "false"), nano_seconds); | 146 | handle_count, (wait_all ? "true" : "false"), nano_seconds); |
| 131 | 147 | ||
| 148 | // Iterate through each handle, synchronize kernel object | ||
| 132 | for (u32 i = 0; i < handle_count; i++) { | 149 | for (u32 i = 0; i < handle_count; i++) { |
| 133 | DEBUG_LOG(SVC, "\thandle[%d]=0x%08X", i, handles[i]); | 150 | bool wait = false; |
| 151 | Kernel::Object* object = Kernel::g_object_pool.GetFast<Kernel::Object>(handles[i]); // 0 handle | ||
| 152 | |||
| 153 | _assert_msg_(KERNEL, object, "WaitSynchronizationN called handle=0x%08X, but kernel object " | ||
| 154 | "is NULL!", handles[i]); | ||
| 155 | |||
| 156 | Result res = object->WaitSynchronization(&wait); | ||
| 157 | |||
| 158 | if (!wait && !wait_all) { | ||
| 159 | Core::g_app_core->SetReg(1, i); | ||
| 160 | return 0; | ||
| 161 | } else { | ||
| 162 | unlock_all = false; | ||
| 163 | } | ||
| 164 | } | ||
| 165 | |||
| 166 | if (wait_all && unlock_all) { | ||
| 167 | Core::g_app_core->SetReg(1, handle_count); | ||
| 168 | return 0; | ||
| 134 | } | 169 | } |
| 170 | |||
| 171 | // Set current thread to wait state if not all handles were unlocked | ||
| 135 | Kernel::WaitCurrentThread(WAITTYPE_SYNCH); // TODO(bunnei): Is this correct? | 172 | Kernel::WaitCurrentThread(WAITTYPE_SYNCH); // TODO(bunnei): Is this correct? |
| 173 | |||
| 136 | return 0; | 174 | return 0; |
| 137 | } | 175 | } |
| 138 | 176 | ||
| @@ -195,16 +233,17 @@ Result CreateThread(u32 priority, u32 entry_point, u32 arg, u32 stack_top, u32 p | |||
| 195 | /// Create a mutex | 233 | /// Create a mutex |
| 196 | Result CreateMutex(void* _mutex, u32 initial_locked) { | 234 | Result CreateMutex(void* _mutex, u32 initial_locked) { |
| 197 | Handle* mutex = (Handle*)_mutex; | 235 | Handle* mutex = (Handle*)_mutex; |
| 198 | *mutex = Kernel::CreateMutex((initial_locked != 0)); | ||
| 199 | Core::g_app_core->SetReg(1, *mutex); | ||
| 200 | DEBUG_LOG(SVC, "CreateMutex called initial_locked=%s : created handle 0x%08X", | 236 | DEBUG_LOG(SVC, "CreateMutex called initial_locked=%s : created handle 0x%08X", |
| 201 | initial_locked ? "true" : "false", *mutex); | 237 | initial_locked ? "true" : "false", *mutex); |
| 238 | *mutex = Kernel::CreateMutex((initial_locked != 0)); | ||
| 239 | Core::g_app_core->SetReg(1, *mutex); | ||
| 202 | return 0; | 240 | return 0; |
| 203 | } | 241 | } |
| 204 | 242 | ||
| 205 | /// Release a mutex | 243 | /// Release a mutex |
| 206 | Result ReleaseMutex(Handle handle) { | 244 | Result ReleaseMutex(Handle handle) { |
| 207 | DEBUG_LOG(SVC, "ReleaseMutex called handle=0x%08X", handle); | 245 | DEBUG_LOG(SVC, "ReleaseMutex called handle=0x%08X", handle); |
| 246 | _assert_msg_(KERNEL, handle, "ReleaseMutex called, but handle is NULL!"); | ||
| 208 | Kernel::ReleaseMutex(handle); | 247 | Kernel::ReleaseMutex(handle); |
| 209 | return 0; | 248 | return 0; |
| 210 | } | 249 | } |
| @@ -225,9 +264,10 @@ Result QueryMemory(void *_info, void *_out, u32 addr) { | |||
| 225 | 264 | ||
| 226 | /// Create an event | 265 | /// Create an event |
| 227 | Result CreateEvent(void* _event, u32 reset_type) { | 266 | Result CreateEvent(void* _event, u32 reset_type) { |
| 228 | Handle* event = (Handle*)_event; | 267 | Handle* evt = (Handle*)_event; |
| 229 | DEBUG_LOG(SVC, "(UNIMPLEMENTED) CreateEvent called reset_type=0x%08X", reset_type); | 268 | DEBUG_LOG(SVC, "CreateEvent called reset_type=0x%08X", reset_type); |
| 230 | Core::g_app_core->SetReg(1, 0xBADC0DE0); | 269 | *evt = Kernel::CreateEvent((ResetType)reset_type); |
| 270 | Core::g_app_core->SetReg(1, *evt); | ||
| 231 | return 0; | 271 | return 0; |
| 232 | } | 272 | } |
| 233 | 273 | ||