summaryrefslogtreecommitdiff
path: root/src/core/hle/svc.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/hle/svc.cpp')
-rw-r--r--src/core/hle/svc.cpp30
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
122static Result WaitSynchronization1(Handle handle, s64 nano_seconds) { 122static 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);