Просмотр исходного кода

svc: Refactor LockMutex code to use WaitSynchronization1.

bunnei 8 лет назад
Родитель
Сommit
57f42e5887
1 измененных файлов с 45 добавлено и 13 удалено
  1. 45 13
      src/core/hle/kernel/svc.cpp

+ 45 - 13
src/core/hle/kernel/svc.cpp

@@ -118,6 +118,50 @@ static ResultCode GetProcessId(u32* process_id, Handle process_handle) {
     return RESULT_SUCCESS;
     return RESULT_SUCCESS;
 }
 }
 
 
+/// Default thread wakeup callback for WaitSynchronization
+static void DefaultThreadWakeupCallback(ThreadWakeupReason reason, SharedPtr<Thread> thread,
+                                        SharedPtr<WaitObject> object) {
+    ASSERT(thread->status == THREADSTATUS_WAIT_SYNCH_ANY);
+
+    if (reason == ThreadWakeupReason::Timeout) {
+        thread->SetWaitSynchronizationResult(RESULT_TIMEOUT);
+        return;
+    }
+
+    ASSERT(reason == ThreadWakeupReason::Signal);
+    thread->SetWaitSynchronizationResult(RESULT_SUCCESS);
+};
+
+/// Wait for a kernel object to synchronize, timeout after the specified nanoseconds
+static ResultCode WaitSynchronization1(
+    SharedPtr<WaitObject> object, Thread* thread, s64 nano_seconds = -1,
+    std::function<Thread::WakeupCallback> wakeup_callback = DefaultThreadWakeupCallback) {
+
+    if (!object) {
+        return ERR_INVALID_HANDLE;
+    }
+
+    if (object->ShouldWait(thread)) {
+        if (nano_seconds == 0) {
+            return RESULT_TIMEOUT;
+        }
+
+        thread->wait_objects = {object};
+        object->AddWaitingThread(thread);
+        thread->status = THREADSTATUS_WAIT_SYNCH_ANY;
+
+        // Create an event to wake the thread up after the specified nanosecond delay has passed
+        thread->WakeAfterDelay(nano_seconds);
+        thread->wakeup_callback = wakeup_callback;
+
+        Core::System::GetInstance().PrepareReschedule();
+    } else {
+        object->Acquire(thread);
+    }
+
+    return RESULT_SUCCESS;
+}
+
 /// Wait for the given handles to synchronize, timeout after the specified nanoseconds
 /// Wait for the given handles to synchronize, timeout after the specified nanoseconds
 static ResultCode WaitSynchronization(VAddr handles_address, u64 handle_count, s64 nano_seconds) {
 static ResultCode WaitSynchronization(VAddr handles_address, u64 handle_count, s64 nano_seconds) {
     LOG_WARNING(Kernel_SVC,
     LOG_WARNING(Kernel_SVC,
@@ -147,19 +191,7 @@ static ResultCode LockMutex(Handle holding_thread_handle, VAddr mutex_addr,
         mutex->name = Common::StringFromFormat("mutex-%llx", mutex_addr);
         mutex->name = Common::StringFromFormat("mutex-%llx", mutex_addr);
     }
     }
 
 
-    if (mutex->ShouldWait(requesting_thread.get())) {
-        // If we cannot lock the mutex, then put the thread too sleep and trigger a reschedule
-        requesting_thread->wait_objects = {mutex};
-        mutex->AddWaitingThread(requesting_thread);
-        requesting_thread->status = THREADSTATUS_WAIT_SYNCH_ANY;
-
-        Core::System::GetInstance().PrepareReschedule();
-    } else {
-        // The mutex is available, lock it
-        mutex->Acquire(requesting_thread.get());
-    }
-
-    return RESULT_SUCCESS;
+    return WaitSynchronization1(mutex, requesting_thread.get());
 }
 }
 
 
 /// Unlock a mutex
 /// Unlock a mutex