diff options
| author | 2018-01-06 14:19:28 -0500 | |
|---|---|---|
| committer | 2018-01-06 14:19:28 -0500 | |
| commit | 57f42e588742dd5429d357ab9a12251abc557708 (patch) | |
| tree | 5bc6f62b88c91f594bb5546ad7d43536bf90860d /src/core/hle/kernel/svc.cpp | |
| parent | lm: Improve Log() to format a useful string. (diff) | |
| download | yuzu-57f42e588742dd5429d357ab9a12251abc557708.tar.gz yuzu-57f42e588742dd5429d357ab9a12251abc557708.tar.xz yuzu-57f42e588742dd5429d357ab9a12251abc557708.zip | |
svc: Refactor LockMutex code to use WaitSynchronization1.
Diffstat (limited to 'src/core/hle/kernel/svc.cpp')
| -rw-r--r-- | src/core/hle/kernel/svc.cpp | 58 |
1 files changed, 45 insertions, 13 deletions
diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp index be9743d9f..a24641399 100644 --- a/src/core/hle/kernel/svc.cpp +++ b/src/core/hle/kernel/svc.cpp | |||
| @@ -118,6 +118,50 @@ static ResultCode GetProcessId(u32* process_id, Handle process_handle) { | |||
| 118 | return RESULT_SUCCESS; | 118 | return RESULT_SUCCESS; |
| 119 | } | 119 | } |
| 120 | 120 | ||
| 121 | /// Default thread wakeup callback for WaitSynchronization | ||
| 122 | static void DefaultThreadWakeupCallback(ThreadWakeupReason reason, SharedPtr<Thread> thread, | ||
| 123 | SharedPtr<WaitObject> object) { | ||
| 124 | ASSERT(thread->status == THREADSTATUS_WAIT_SYNCH_ANY); | ||
| 125 | |||
| 126 | if (reason == ThreadWakeupReason::Timeout) { | ||
| 127 | thread->SetWaitSynchronizationResult(RESULT_TIMEOUT); | ||
| 128 | return; | ||
| 129 | } | ||
| 130 | |||
| 131 | ASSERT(reason == ThreadWakeupReason::Signal); | ||
| 132 | thread->SetWaitSynchronizationResult(RESULT_SUCCESS); | ||
| 133 | }; | ||
| 134 | |||
| 135 | /// Wait for a kernel object to synchronize, timeout after the specified nanoseconds | ||
| 136 | static ResultCode WaitSynchronization1( | ||
| 137 | SharedPtr<WaitObject> object, Thread* thread, s64 nano_seconds = -1, | ||
| 138 | std::function<Thread::WakeupCallback> wakeup_callback = DefaultThreadWakeupCallback) { | ||
| 139 | |||
| 140 | if (!object) { | ||
| 141 | return ERR_INVALID_HANDLE; | ||
| 142 | } | ||
| 143 | |||
| 144 | if (object->ShouldWait(thread)) { | ||
| 145 | if (nano_seconds == 0) { | ||
| 146 | return RESULT_TIMEOUT; | ||
| 147 | } | ||
| 148 | |||
| 149 | thread->wait_objects = {object}; | ||
| 150 | object->AddWaitingThread(thread); | ||
| 151 | thread->status = THREADSTATUS_WAIT_SYNCH_ANY; | ||
| 152 | |||
| 153 | // Create an event to wake the thread up after the specified nanosecond delay has passed | ||
| 154 | thread->WakeAfterDelay(nano_seconds); | ||
| 155 | thread->wakeup_callback = wakeup_callback; | ||
| 156 | |||
| 157 | Core::System::GetInstance().PrepareReschedule(); | ||
| 158 | } else { | ||
| 159 | object->Acquire(thread); | ||
| 160 | } | ||
| 161 | |||
| 162 | return RESULT_SUCCESS; | ||
| 163 | } | ||
| 164 | |||
| 121 | /// Wait for the given handles to synchronize, timeout after the specified nanoseconds | 165 | /// Wait for the given handles to synchronize, timeout after the specified nanoseconds |
| 122 | static ResultCode WaitSynchronization(VAddr handles_address, u64 handle_count, s64 nano_seconds) { | 166 | static ResultCode WaitSynchronization(VAddr handles_address, u64 handle_count, s64 nano_seconds) { |
| 123 | LOG_WARNING(Kernel_SVC, | 167 | LOG_WARNING(Kernel_SVC, |
| @@ -147,19 +191,7 @@ static ResultCode LockMutex(Handle holding_thread_handle, VAddr mutex_addr, | |||
| 147 | mutex->name = Common::StringFromFormat("mutex-%llx", mutex_addr); | 191 | mutex->name = Common::StringFromFormat("mutex-%llx", mutex_addr); |
| 148 | } | 192 | } |
| 149 | 193 | ||
| 150 | if (mutex->ShouldWait(requesting_thread.get())) { | 194 | return WaitSynchronization1(mutex, requesting_thread.get()); |
| 151 | // If we cannot lock the mutex, then put the thread too sleep and trigger a reschedule | ||
| 152 | requesting_thread->wait_objects = {mutex}; | ||
| 153 | mutex->AddWaitingThread(requesting_thread); | ||
| 154 | requesting_thread->status = THREADSTATUS_WAIT_SYNCH_ANY; | ||
| 155 | |||
| 156 | Core::System::GetInstance().PrepareReschedule(); | ||
| 157 | } else { | ||
| 158 | // The mutex is available, lock it | ||
| 159 | mutex->Acquire(requesting_thread.get()); | ||
| 160 | } | ||
| 161 | |||
| 162 | return RESULT_SUCCESS; | ||
| 163 | } | 195 | } |
| 164 | 196 | ||
| 165 | /// Unlock a mutex | 197 | /// Unlock a mutex |