summaryrefslogtreecommitdiff
path: root/src/core/hle/kernel/svc.cpp
diff options
context:
space:
mode:
authorGravatar Subv2018-04-20 12:01:14 -0500
committerGravatar Subv2018-04-20 21:04:25 -0500
commite81a2080ebf9712231dd29c081141780ffd46cfb (patch)
treeb93d23dde3c3a0e86edeb44a1c1f1e18ac839bd6 /src/core/hle/kernel/svc.cpp
parentMerge pull request #367 from lioncash/clamp (diff)
downloadyuzu-e81a2080ebf9712231dd29c081141780ffd46cfb.tar.gz
yuzu-e81a2080ebf9712231dd29c081141780ffd46cfb.tar.xz
yuzu-e81a2080ebf9712231dd29c081141780ffd46cfb.zip
Kernel: Corrected the implementation of svcArbitrateLock and svcArbitrateUnlock.
Switch mutexes are no longer kernel objects, they are managed in userland and only use the kernel to handle the contention case. Mutex addresses store a special flag value (0x40000000) to notify the guest code that there are still some threads waiting for the mutex to be released. This flag is updated when a thread calls ArbitrateUnlock. TODO: * Fix svcWaitProcessWideKey * Fix svcSignalProcessWideKey * Remove the Mutex class.
Diffstat (limited to 'src/core/hle/kernel/svc.cpp')
-rw-r--r--src/core/hle/kernel/svc.cpp22
1 files changed, 2 insertions, 20 deletions
diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp
index 6204bcaaa..92273b488 100644
--- a/src/core/hle/kernel/svc.cpp
+++ b/src/core/hle/kernel/svc.cpp
@@ -262,32 +262,14 @@ static ResultCode ArbitrateLock(Handle holding_thread_handle, VAddr mutex_addr,
262 "requesting_current_thread_handle=0x%08X", 262 "requesting_current_thread_handle=0x%08X",
263 holding_thread_handle, mutex_addr, requesting_thread_handle); 263 holding_thread_handle, mutex_addr, requesting_thread_handle);
264 264
265 SharedPtr<Thread> holding_thread = g_handle_table.Get<Thread>(holding_thread_handle); 265 return Mutex::TryAcquire(mutex_addr, holding_thread_handle, requesting_thread_handle);
266 SharedPtr<Thread> requesting_thread = g_handle_table.Get<Thread>(requesting_thread_handle);
267
268 ASSERT(requesting_thread);
269 ASSERT(requesting_thread == GetCurrentThread());
270
271 SharedPtr<Mutex> mutex = g_object_address_table.Get<Mutex>(mutex_addr);
272 if (!mutex) {
273 // Create a new mutex for the specified address if one does not already exist
274 mutex = Mutex::Create(holding_thread, mutex_addr);
275 mutex->name = Common::StringFromFormat("mutex-%llx", mutex_addr);
276 }
277
278 ASSERT(holding_thread == mutex->GetHoldingThread());
279
280 return WaitSynchronization1(mutex, requesting_thread.get());
281} 266}
282 267
283/// Unlock a mutex 268/// Unlock a mutex
284static ResultCode ArbitrateUnlock(VAddr mutex_addr) { 269static ResultCode ArbitrateUnlock(VAddr mutex_addr) {
285 LOG_TRACE(Kernel_SVC, "called mutex_addr=0x%llx", mutex_addr); 270 LOG_TRACE(Kernel_SVC, "called mutex_addr=0x%llx", mutex_addr);
286 271
287 SharedPtr<Mutex> mutex = g_object_address_table.Get<Mutex>(mutex_addr); 272 return Mutex::Release(mutex_addr);
288 ASSERT(mutex);
289
290 return mutex->Release(GetCurrentThread());
291} 273}
292 274
293/// Break program execution 275/// Break program execution