From 4e84df8be30c5bac65e4c4e9faf07bf0fc3fb33a Mon Sep 17 00:00:00 2001 From: Yuri Kunde Schlesner Date: Sat, 31 Jan 2015 19:22:40 -0200 Subject: Mutex: Replace g_mutex_held_locks with a set inside Thread --- src/core/hle/kernel/mutex.cpp | 28 +++++++--------------------- src/core/hle/kernel/thread.cpp | 3 +++ src/core/hle/kernel/thread.h | 10 ++++++++-- 3 files changed, 18 insertions(+), 23 deletions(-) diff --git a/src/core/hle/kernel/mutex.cpp b/src/core/hle/kernel/mutex.cpp index acf48465..6fdcc97e 100644 --- a/src/core/hle/kernel/mutex.cpp +++ b/src/core/hle/kernel/mutex.cpp @@ -5,6 +5,8 @@ #include #include +#include + #include "common/common.h" #include "core/hle/kernel/kernel.h" @@ -13,9 +15,6 @@ namespace Kernel { -typedef std::multimap, SharedPtr> MutexMap; -static MutexMap g_mutex_held_locks; - /** * Resumes a thread waiting for the specified mutex * @param mutex The mutex that some thread is waiting on @@ -33,15 +32,10 @@ static void ResumeWaitingThread(Mutex* mutex) { } void ReleaseThreadMutexes(Thread* thread) { - auto locked_range = g_mutex_held_locks.equal_range(thread); - - // Release every mutex that the thread holds, and resume execution on the waiting threads - for (auto iter = locked_range.first; iter != locked_range.second; ++iter) { - ResumeWaitingThread(iter->second.get()); + for (auto& mtx : thread->held_mutexes) { + ResumeWaitingThread(mtx.get()); } - - // Erase all the locks that this thread holds - g_mutex_held_locks.erase(thread); + thread->held_mutexes.clear(); } ResultVal> Mutex::Create(bool initial_locked, std::string name) { @@ -76,7 +70,7 @@ void Mutex::Acquire(Thread* thread) { locked = true; - g_mutex_held_locks.insert(std::make_pair(thread, this)); + thread->held_mutexes.insert(this); holding_thread = thread; } @@ -84,15 +78,7 @@ void Mutex::Release() { if (!locked) return; - auto locked_range = g_mutex_held_locks.equal_range(holding_thread); - - for (MutexMap::iterator iter = locked_range.first; iter != locked_range.second; ++iter) { - if (iter->second == this) { - g_mutex_held_locks.erase(iter); - break; - } - } - + holding_thread->held_mutexes.erase(this); ResumeWaitingThread(this); } diff --git a/src/core/hle/kernel/thread.cpp b/src/core/hle/kernel/thread.cpp index 2fae1b3b..3c6669ca 100644 --- a/src/core/hle/kernel/thread.cpp +++ b/src/core/hle/kernel/thread.cpp @@ -40,6 +40,9 @@ static Thread* current_thread; static const u32 INITIAL_THREAD_ID = 1; ///< The first available thread id at startup static u32 next_thread_id; ///< The next available thread id +Thread::Thread() { +} + Thread* GetCurrentThread() { return current_thread; } diff --git a/src/core/hle/kernel/thread.h b/src/core/hle/kernel/thread.h index 9a4a00fe..f29897ae 100644 --- a/src/core/hle/kernel/thread.h +++ b/src/core/hle/kernel/thread.h @@ -7,6 +7,8 @@ #include #include +#include + #include "common/common_types.h" #include "core/core.h" @@ -40,6 +42,8 @@ enum ThreadStatus { namespace Kernel { +class Mutex; + class Thread final : public WaitObject { public: static ResultVal> Create(std::string name, VAddr entry_point, s32 priority, @@ -109,8 +113,10 @@ public: s32 processor_id; - std::vector> wait_objects; ///< Objects that the thread is waiting on + /// Mutexes currently held by this thread, which will be released when it exits. + boost::container::flat_set> held_mutexes; + std::vector> wait_objects; ///< Objects that the thread is waiting on VAddr wait_address; ///< If waiting on an AddressArbiter, this is the arbitration address bool wait_all; ///< True if the thread is waiting on all objects before resuming bool wait_set_output; ///< True if the output parameter should be set on thread wakeup @@ -121,7 +127,7 @@ public: bool idle = false; private: - Thread() = default; + Thread(); /// Handle used as userdata to reference this object when inserting into the CoreTiming queue. Handle callback_handle; -- cgit v1.2.3