diff options
-rw-r--r-- | src/core/hle/kernel/mutex.cpp | 72 | ||||
-rw-r--r-- | src/core/hle/kernel/mutex.h | 2 | ||||
-rw-r--r-- | src/core/hle/kernel/thread.cpp | 2 |
3 files changed, 29 insertions, 47 deletions
diff --git a/src/core/hle/kernel/mutex.cpp b/src/core/hle/kernel/mutex.cpp index c170e55ff..cd05a1397 100644 --- a/src/core/hle/kernel/mutex.cpp +++ b/src/core/hle/kernel/mutex.cpp @@ -23,9 +23,8 @@ public: bool initial_locked; ///< Initial lock state when mutex was created bool locked; ///< Current locked state - Handle lock_thread; ///< Handle to thread that currently has mutex std::string name; ///< Name of mutex (optional) - SharedPtr<Thread> current_thread; ///< Thread that has acquired the mutex + SharedPtr<Thread> holding_thread; ///< Thread that has acquired the mutex bool ShouldWait() override; void Acquire() override; @@ -33,18 +32,17 @@ public: //////////////////////////////////////////////////////////////////////////////////////////////////// -typedef std::multimap<Handle, Handle> MutexMap; +typedef std::multimap<SharedPtr<Thread>, SharedPtr<Mutex>> MutexMap; static MutexMap g_mutex_held_locks; /** * Acquires the specified mutex for the specified thread * @param mutex Mutex that is to be acquired - * @param thread Thread that will acquired + * @param thread Thread that will acquire the mutex */ -void MutexAcquireLock(Mutex* mutex, Handle thread = GetCurrentThread()->GetHandle()) { - g_mutex_held_locks.insert(std::make_pair(thread, mutex->GetHandle())); - mutex->lock_thread = thread; - mutex->current_thread = Kernel::g_handle_table.Get<Thread>(thread); +void MutexAcquireLock(Mutex* mutex, Thread* thread) { + g_mutex_held_locks.insert(std::make_pair(thread, mutex)); + mutex->holding_thread = thread; } /** @@ -55,51 +53,39 @@ void ResumeWaitingThread(Mutex* mutex) { // Find the next waiting thread for the mutex... auto next_thread = mutex->WakeupNextThread(); if (next_thread != nullptr) { - MutexAcquireLock(mutex, next_thread->GetHandle()); + MutexAcquireLock(mutex, next_thread); } else { // Reset mutex lock thread handle, nothing is waiting mutex->locked = false; - mutex->lock_thread = -1; + mutex->holding_thread = nullptr; } } -void MutexEraseLock(Mutex* mutex) { - Handle handle = mutex->GetHandle(); - auto locked = g_mutex_held_locks.equal_range(mutex->lock_thread); - for (MutexMap::iterator iter = locked.first; iter != locked.second; ++iter) { - if (iter->second == handle) { - g_mutex_held_locks.erase(iter); - break; - } - } - mutex->lock_thread = -1; -} - -void ReleaseThreadMutexes(Handle thread) { +void ReleaseThreadMutexes(Thread* thread) { auto locked = g_mutex_held_locks.equal_range(thread); // Release every mutex that the thread holds, and resume execution on the waiting threads - for (MutexMap::iterator iter = locked.first; iter != locked.second; ++iter) { - Mutex* mutex = g_handle_table.Get<Mutex>(iter->second).get(); - ResumeWaitingThread(mutex); + for (auto iter = locked.first; iter != locked.second; ++iter) { + ResumeWaitingThread(iter->second.get()); } // Erase all the locks that this thread holds g_mutex_held_locks.erase(thread); } -bool LockMutex(Mutex* mutex) { - // Mutex alread locked? +bool ReleaseMutex(Mutex* mutex) { if (mutex->locked) { - return false; - } - MutexAcquireLock(mutex); - return true; -} + auto locked = g_mutex_held_locks.equal_range(mutex->holding_thread); -bool ReleaseMutex(Mutex* mutex) { - MutexEraseLock(mutex); - ResumeWaitingThread(mutex); + for (MutexMap::iterator iter = locked.first; iter != locked.second; ++iter) { + if (iter->second == mutex) { + g_mutex_held_locks.erase(iter); + break; + } + } + + ResumeWaitingThread(mutex); + } return true; } @@ -134,16 +120,12 @@ Mutex* CreateMutex(Handle& handle, bool initial_locked, const std::string& name) mutex->locked = mutex->initial_locked = initial_locked; mutex->name = name; - mutex->current_thread = nullptr; + mutex->holding_thread = nullptr; // Acquire mutex with current thread if initialized as locked... - if (mutex->locked) { - MutexAcquireLock(mutex); + if (mutex->locked) + MutexAcquireLock(mutex, GetCurrentThread()); - // Otherwise, reset lock thread handle - } else { - mutex->lock_thread = -1; - } return mutex; } @@ -160,13 +142,13 @@ Handle CreateMutex(bool initial_locked, const std::string& name) { } bool Mutex::ShouldWait() { - return locked && current_thread != GetCurrentThread(); + return locked && holding_thread != GetCurrentThread(); } void Mutex::Acquire() { _assert_msg_(Kernel, !ShouldWait(), "object unavailable!"); locked = true; - MutexAcquireLock(this); + MutexAcquireLock(this, GetCurrentThread()); } } // namespace diff --git a/src/core/hle/kernel/mutex.h b/src/core/hle/kernel/mutex.h index a8ca97014..bb8778c98 100644 --- a/src/core/hle/kernel/mutex.h +++ b/src/core/hle/kernel/mutex.h @@ -28,6 +28,6 @@ Handle CreateMutex(bool initial_locked, const std::string& name="Unknown"); * Releases all the mutexes held by the specified thread * @param thread Thread that is holding the mutexes */ -void ReleaseThreadMutexes(Handle thread); +void ReleaseThreadMutexes(Thread* thread); } // namespace diff --git a/src/core/hle/kernel/thread.cpp b/src/core/hle/kernel/thread.cpp index ab1126a36..3ca9603c2 100644 --- a/src/core/hle/kernel/thread.cpp +++ b/src/core/hle/kernel/thread.cpp @@ -100,7 +100,7 @@ static bool CheckWait_AddressArbiter(const Thread* thread, VAddr wait_address) { /// Stops the current thread void Thread::Stop(const char* reason) { // Release all the mutexes that this thread holds - ReleaseThreadMutexes(GetHandle()); + ReleaseThreadMutexes(this); ChangeReadyState(this, false); status = THREADSTATUS_DORMANT; |