svc: Refactor LockMutex code to use WaitSynchronization1.

This commit is contained in:
bunnei 2018-01-06 14:19:28 -05:00
parent d083c07c46
commit 57f42e5887

View File

@ -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())) { return WaitSynchronization1(mutex, 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;
} }
/// Unlock a mutex /// Unlock a mutex