diff options
| author | 2018-01-01 14:02:26 -0500 | |
|---|---|---|
| committer | 2018-01-01 14:02:26 -0500 | |
| commit | b9950cd4b0cf414ca97daa5f7578f4ca22b2669d (patch) | |
| tree | 194c711f7f02e68e5137f3f7287dbd21ab834d5b /src/core/hle/svc.cpp | |
| parent | kernel: Add ObjectAddressTable class. (diff) | |
| download | yuzu-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.cpp | 40 |
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 | ||
| 126 | static 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 |
| 126 | static void Break(u64 unk_0, u64 unk_1, u64 unk_2) { | 164 | static 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"}, |