diff options
Diffstat (limited to 'src/core/hle/svc.cpp')
| -rw-r--r-- | src/core/hle/svc.cpp | 30 |
1 files changed, 20 insertions, 10 deletions
diff --git a/src/core/hle/svc.cpp b/src/core/hle/svc.cpp index 01b536084..2d5f41af6 100644 --- a/src/core/hle/svc.cpp +++ b/src/core/hle/svc.cpp | |||
| @@ -105,7 +105,7 @@ static Result SendSyncRequest(Handle handle) { | |||
| 105 | 105 | ||
| 106 | ResultVal<bool> wait = session->SyncRequest(); | 106 | ResultVal<bool> wait = session->SyncRequest(); |
| 107 | if (wait.Succeeded() && *wait) { | 107 | if (wait.Succeeded() && *wait) { |
| 108 | Kernel::WaitCurrentThread(WAITTYPE_SYNCH); // TODO(bunnei): Is this correct? | 108 | Kernel::WaitCurrentThread(); // TODO(bunnei): Is this correct? |
| 109 | } | 109 | } |
| 110 | 110 | ||
| 111 | return wait.Code().raw; | 111 | return wait.Code().raw; |
| @@ -120,22 +120,24 @@ static Result CloseHandle(Handle handle) { | |||
| 120 | 120 | ||
| 121 | /// Wait for a handle to synchronize, timeout after the specified nanoseconds | 121 | /// Wait for a handle to synchronize, timeout after the specified nanoseconds |
| 122 | static Result WaitSynchronization1(Handle handle, s64 nano_seconds) { | 122 | static Result WaitSynchronization1(Handle handle, s64 nano_seconds) { |
| 123 | SharedPtr<Kernel::Object> object = Kernel::g_handle_table.GetGeneric(handle); | 123 | Kernel::WaitObject* object = static_cast<Kernel::WaitObject*>(Kernel::g_handle_table.GetGeneric(handle).get()); |
| 124 | if (object == nullptr) | 124 | if (object == nullptr) |
| 125 | return InvalidHandle(ErrorModule::Kernel).raw; | 125 | return InvalidHandle(ErrorModule::Kernel).raw; |
| 126 | 126 | ||
| 127 | LOG_TRACE(Kernel_SVC, "called handle=0x%08X(%s:%s), nanoseconds=%lld", handle, | 127 | LOG_TRACE(Kernel_SVC, "called handle=0x%08X(%s:%s), nanoseconds=%lld", handle, |
| 128 | object->GetTypeName().c_str(), object->GetName().c_str(), nano_seconds); | 128 | object->GetTypeName().c_str(), object->GetName().c_str(), nano_seconds); |
| 129 | 129 | ||
| 130 | ResultVal<bool> wait = object->Wait(true); | 130 | ResultVal<bool> wait = object->Wait(); |
| 131 | 131 | ||
| 132 | // Check for next thread to schedule | 132 | // Check for next thread to schedule |
| 133 | if (wait.Succeeded() && *wait) { | 133 | if (wait.Succeeded() && *wait) { |
| 134 | |||
| 135 | object->AddWaitingThread(Kernel::GetCurrentThread()); | ||
| 136 | Kernel::WaitCurrentThread_WaitSynchronization(object); | ||
| 137 | |||
| 134 | // Create an event to wake the thread up after the specified nanosecond delay has passed | 138 | // Create an event to wake the thread up after the specified nanosecond delay has passed |
| 135 | Kernel::WakeThreadAfterDelay(Kernel::GetCurrentThread(), nano_seconds); | 139 | Kernel::WakeThreadAfterDelay(Kernel::GetCurrentThread(), nano_seconds); |
| 136 | 140 | ||
| 137 | Kernel::GetCurrentThread()->SetWaitAll(false); | ||
| 138 | |||
| 139 | HLE::Reschedule(__func__); | 141 | HLE::Reschedule(__func__); |
| 140 | } else { | 142 | } else { |
| 141 | object->Acquire(); | 143 | object->Acquire(); |
| @@ -166,14 +168,15 @@ static Result WaitSynchronizationN(s32* out, Handle* handles, s32 handle_count, | |||
| 166 | if (handle_count != 0) { | 168 | if (handle_count != 0) { |
| 167 | bool selected = false; // True once an object has been selected | 169 | bool selected = false; // True once an object has been selected |
| 168 | for (int i = 0; i < handle_count; ++i) { | 170 | for (int i = 0; i < handle_count; ++i) { |
| 169 | SharedPtr<Kernel::Object> object = Kernel::g_handle_table.GetGeneric(handles[i]); | 171 | Kernel::WaitObject* object = static_cast<Kernel::WaitObject*>(Kernel::g_handle_table.GetGeneric(handles[i]).get()); |
| 170 | if (object == nullptr) | 172 | if (object == nullptr) |
| 171 | return InvalidHandle(ErrorModule::Kernel).raw; | 173 | return InvalidHandle(ErrorModule::Kernel).raw; |
| 172 | 174 | ||
| 173 | ResultVal<bool> wait = object->Wait(true); | 175 | ResultVal<bool> wait = object->Wait(); |
| 174 | 176 | ||
| 175 | // Check if the current thread should wait on this object... | 177 | // Check if the current thread should wait on this object... |
| 176 | if (wait.Succeeded() && *wait) { | 178 | if (wait.Succeeded() && *wait) { |
| 179 | |||
| 177 | // Check we are waiting on all objects... | 180 | // Check we are waiting on all objects... |
| 178 | if (wait_all) | 181 | if (wait_all) |
| 179 | // Wait the thread | 182 | // Wait the thread |
| @@ -193,15 +196,22 @@ static Result WaitSynchronizationN(s32* out, Handle* handles, s32 handle_count, | |||
| 193 | // NOTE: This should deadlock the current thread if no timeout was specified | 196 | // NOTE: This should deadlock the current thread if no timeout was specified |
| 194 | if (!wait_all) { | 197 | if (!wait_all) { |
| 195 | wait_thread = true; | 198 | wait_thread = true; |
| 196 | Kernel::WaitCurrentThread(WAITTYPE_SLEEP); | 199 | Kernel::WaitCurrentThread(); |
| 197 | } | 200 | } |
| 198 | } | 201 | } |
| 199 | 202 | ||
| 200 | // If thread should wait, then set its state to waiting and then reschedule... | 203 | // If thread should wait, then set its state to waiting and then reschedule... |
| 201 | if (wait_thread) { | 204 | if (wait_thread) { |
| 205 | |||
| 206 | // Actually wait the current thread on each object if we decided to wait... | ||
| 207 | for (int i = 0; i < handle_count; ++i) { | ||
| 208 | auto object = Kernel::g_handle_table.GetWaitObject(handles[i]); | ||
| 209 | object->AddWaitingThread(Kernel::GetCurrentThread()); | ||
| 210 | Kernel::WaitCurrentThread_WaitSynchronization(object, wait_all); | ||
| 211 | } | ||
| 212 | |||
| 202 | // Create an event to wake the thread up after the specified nanosecond delay has passed | 213 | // Create an event to wake the thread up after the specified nanosecond delay has passed |
| 203 | Kernel::WakeThreadAfterDelay(Kernel::GetCurrentThread(), nano_seconds); | 214 | Kernel::WakeThreadAfterDelay(Kernel::GetCurrentThread(), nano_seconds); |
| 204 | Kernel::GetCurrentThread()->SetWaitAll(wait_all); | ||
| 205 | 215 | ||
| 206 | HLE::Reschedule(__func__); | 216 | HLE::Reschedule(__func__); |
| 207 | 217 | ||
| @@ -440,7 +450,7 @@ static void SleepThread(s64 nanoseconds) { | |||
| 440 | LOG_TRACE(Kernel_SVC, "called nanoseconds=%lld", nanoseconds); | 450 | LOG_TRACE(Kernel_SVC, "called nanoseconds=%lld", nanoseconds); |
| 441 | 451 | ||
| 442 | // Sleep current thread and check for next thread to schedule | 452 | // Sleep current thread and check for next thread to schedule |
| 443 | Kernel::WaitCurrentThread(WAITTYPE_SLEEP); | 453 | Kernel::WaitCurrentThread(); |
| 444 | 454 | ||
| 445 | // Create an event to wake the thread up after the specified nanosecond delay has passed | 455 | // Create an event to wake the thread up after the specified nanosecond delay has passed |
| 446 | Kernel::WakeThreadAfterDelay(Kernel::GetCurrentThread(), nanoseconds); | 456 | Kernel::WakeThreadAfterDelay(Kernel::GetCurrentThread(), nanoseconds); |