mirror of
https://github.com/yuzu-emu/yuzu.git
synced 2024-07-04 23:31:19 +01:00
svc: Refactor LockMutex code to use WaitSynchronization1.
This commit is contained in:
parent
d083c07c46
commit
57f42e5887
1 changed files with 45 additions and 13 deletions
|
@ -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
|
||||||
|
|
Loading…
Reference in a new issue