summaryrefslogtreecommitdiff
path: root/src/core/hle/svc.cpp
diff options
context:
space:
mode:
authorGravatar bunnei2018-01-01 14:02:26 -0500
committerGravatar bunnei2018-01-01 14:02:26 -0500
commitb9950cd4b0cf414ca97daa5f7578f4ca22b2669d (patch)
tree194c711f7f02e68e5137f3f7287dbd21ab834d5b /src/core/hle/svc.cpp
parentkernel: Add ObjectAddressTable class. (diff)
downloadyuzu-b9950cd4b0cf414ca97daa5f7578f4ca22b2669d.tar.gz
yuzu-b9950cd4b0cf414ca97daa5f7578f4ca22b2669d.tar.xz
yuzu-b9950cd4b0cf414ca97daa5f7578f4ca22b2669d.zip
svc: Implement svcLockMutex.
Diffstat (limited to 'src/core/hle/svc.cpp')
-rw-r--r--src/core/hle/svc.cpp40
1 files changed, 39 insertions, 1 deletions
diff --git a/src/core/hle/svc.cpp b/src/core/hle/svc.cpp
index 133b868f2..c0e3200d4 100644
--- a/src/core/hle/svc.cpp
+++ b/src/core/hle/svc.cpp
@@ -122,6 +122,44 @@ static ResultCode GetProcessId(u32* process_id, Kernel::Handle process_handle) {
122 return RESULT_SUCCESS; 122 return RESULT_SUCCESS;
123} 123}
124 124
125/// Attempts to locks a mutex, creating it if it does not already exist
126static ResultCode LockMutex(Handle holding_thread_handle, VAddr mutex_addr,
127 Handle requesting_thread_handle) {
128 LOG_TRACE(Kernel_SVC,
129 "called holding_thread_handle=0x%08X, mutex_addr=0x%llx, "
130 "requesting_current_thread_handle=0x%08X",
131 holding_thread_handle, mutex_addr, requesting_thread_handle);
132
133 SharedPtr<Kernel::Thread> holding_thread =
134 Kernel::g_handle_table.Get<Kernel::Thread>(holding_thread_handle);
135 SharedPtr<Kernel::Thread> requesting_thread =
136 Kernel::g_handle_table.Get<Kernel::Thread>(requesting_thread_handle);
137
138 ASSERT(holding_thread);
139 ASSERT(requesting_thread);
140
141 SharedPtr<Kernel::Mutex> mutex = Kernel::g_object_address_table.Get<Kernel::Mutex>(mutex_addr);
142 if (!mutex) {
143 // Create a new mutex for the specified address if one does not already exist
144 mutex = Kernel::Mutex::Create(holding_thread, mutex_addr);
145 mutex->name = Common::StringFromFormat("mutex-%llx", mutex_addr);
146 }
147
148 if (mutex->ShouldWait(requesting_thread.get())) {
149 // If we cannot lock the mutex, then put the thread too sleep and trigger a reschedule
150 requesting_thread->wait_objects = {mutex};
151 mutex->AddWaitingThread(requesting_thread);
152 requesting_thread->status = THREADSTATUS_WAIT_SYNCH_ANY;
153
154 Core::System::GetInstance().PrepareReschedule();
155 } else {
156 // The mutex is available, lock it
157 mutex->Acquire(requesting_thread.get());
158 }
159
160 return RESULT_SUCCESS;
161}
162
125/// Break program execution 163/// Break program execution
126static void Break(u64 unk_0, u64 unk_1, u64 unk_2) { 164static void Break(u64 unk_0, u64 unk_1, u64 unk_2) {
127 LOG_CRITICAL(Debug_Emulated, "Emulated program broke execution!"); 165 LOG_CRITICAL(Debug_Emulated, "Emulated program broke execution!");
@@ -371,8 +409,8 @@ static const FunctionDef SVC_Table[] = {
371 {0x17, nullptr, "svcResetSignal"}, 409 {0x17, nullptr, "svcResetSignal"},
372 {0x18, nullptr, "svcWaitSynchronization"}, 410 {0x18, nullptr, "svcWaitSynchronization"},
373 {0x19, nullptr, "svcCancelSynchronization"}, 411 {0x19, nullptr, "svcCancelSynchronization"},
374 {0x1A, nullptr, "svcLockMutex"},
375 {0x1B, nullptr, "svcUnlockMutex"}, 412 {0x1B, nullptr, "svcUnlockMutex"},
413 {0x1A, HLE::Wrap<LockMutex>, "svcLockMutex"},
376 {0x1C, nullptr, "svcWaitProcessWideKeyAtomic"}, 414 {0x1C, nullptr, "svcWaitProcessWideKeyAtomic"},
377 {0x1D, HLE::Wrap<SignalProcessWideKey>, "svcSignalProcessWideKey"}, 415 {0x1D, HLE::Wrap<SignalProcessWideKey>, "svcSignalProcessWideKey"},
378 {0x1E, nullptr, "svcGetSystemTick"}, 416 {0x1E, nullptr, "svcGetSystemTick"},