From e81a2080ebf9712231dd29c081141780ffd46cfb Mon Sep 17 00:00:00 2001 From: Subv Date: Fri, 20 Apr 2018 12:01:14 -0500 Subject: 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. --- src/core/hle/kernel/svc.cpp | 22 ++-------------------- 1 file changed, 2 insertions(+), 20 deletions(-) (limited to 'src/core/hle/kernel/svc.cpp') 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, "requesting_current_thread_handle=0x%08X", holding_thread_handle, mutex_addr, requesting_thread_handle); - SharedPtr holding_thread = g_handle_table.Get(holding_thread_handle); - SharedPtr requesting_thread = g_handle_table.Get(requesting_thread_handle); - - ASSERT(requesting_thread); - ASSERT(requesting_thread == GetCurrentThread()); - - SharedPtr mutex = g_object_address_table.Get(mutex_addr); - if (!mutex) { - // Create a new mutex for the specified address if one does not already exist - mutex = Mutex::Create(holding_thread, mutex_addr); - mutex->name = Common::StringFromFormat("mutex-%llx", mutex_addr); - } - - ASSERT(holding_thread == mutex->GetHoldingThread()); - - return WaitSynchronization1(mutex, requesting_thread.get()); + return Mutex::TryAcquire(mutex_addr, holding_thread_handle, requesting_thread_handle); } /// Unlock a mutex static ResultCode ArbitrateUnlock(VAddr mutex_addr) { LOG_TRACE(Kernel_SVC, "called mutex_addr=0x%llx", mutex_addr); - SharedPtr mutex = g_object_address_table.Get(mutex_addr); - ASSERT(mutex); - - return mutex->Release(GetCurrentThread()); + return Mutex::Release(mutex_addr); } /// Break program execution -- cgit v1.2.3