summaryrefslogtreecommitdiff
path: root/src/core/hle/kernel/svc.cpp
diff options
context:
space:
mode:
authorGravatar bunnei2018-01-06 14:19:28 -0500
committerGravatar bunnei2018-01-06 14:19:28 -0500
commit57f42e588742dd5429d357ab9a12251abc557708 (patch)
tree5bc6f62b88c91f594bb5546ad7d43536bf90860d /src/core/hle/kernel/svc.cpp
parentlm: Improve Log() to format a useful string. (diff)
downloadyuzu-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.cpp58
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
122static 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
136static 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
122static ResultCode WaitSynchronization(VAddr handles_address, u64 handle_count, s64 nano_seconds) { 166static 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