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 +++++++--------------------- 1 file changed, 7 insertions(+), 21 deletions(-) (limited to 'src/core/hle/kernel/mutex.cpp') diff --git a/src/core/hle/kernel/mutex.cpp b/src/core/hle/kernel/mutex.cpp index acf484659..6fdcc97ee 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); } -- cgit v1.2.3 From 7725256f649719dcce2c50ea84e79d6199dd9a50 Mon Sep 17 00:00:00 2001 From: Yuri Kunde Schlesner Date: Sat, 31 Jan 2015 22:56:59 -0200 Subject: Explicitly instantiate constructors/destructors for Kernel objects This should speed up compile times a bit, as well as enable more liberal use of forward declarations. (Due to SharedPtr not trying to emit the destructor anymore.) --- src/core/hle/kernel/mutex.cpp | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src/core/hle/kernel/mutex.cpp') diff --git a/src/core/hle/kernel/mutex.cpp b/src/core/hle/kernel/mutex.cpp index 6fdcc97ee..c6ad5ca91 100644 --- a/src/core/hle/kernel/mutex.cpp +++ b/src/core/hle/kernel/mutex.cpp @@ -38,6 +38,9 @@ void ReleaseThreadMutexes(Thread* thread) { thread->held_mutexes.clear(); } +Mutex::Mutex() {} +Mutex::~Mutex() {} + ResultVal> Mutex::Create(bool initial_locked, std::string name) { SharedPtr mutex(new Mutex); // TOOD(yuriks): Don't create Handle (see Thread::Create()) -- cgit v1.2.3 From 52f58e64efbf43c114f701eb8f39fb463138ffb8 Mon Sep 17 00:00:00 2001 From: Yuri Kunde Schlesner Date: Sat, 31 Jan 2015 23:26:16 -0200 Subject: Kernel: Make WaitObjects share ownership of Threads waiting on them During normal operation, a thread waiting on an WaitObject and the object hold mutual references to each other for the duration of the wait. If a process is forcefully terminated (The CTR kernel has a SVC to do this, TerminateProcess, though no equivalent exists for threads.) its threads would also be stopped and destroyed, leaving dangling pointers in the WaitObjects. The solution is to simply have the Thread remove itself from WaitObjects when it is stopped. The vector of Threads in WaitObject has also been changed to hold SharedPtrs, just in case. (Better to have a reference cycle than a crash.) --- src/core/hle/kernel/mutex.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/core/hle/kernel/mutex.cpp') diff --git a/src/core/hle/kernel/mutex.cpp b/src/core/hle/kernel/mutex.cpp index c6ad5ca91..7c634f9bd 100644 --- a/src/core/hle/kernel/mutex.cpp +++ b/src/core/hle/kernel/mutex.cpp @@ -66,7 +66,7 @@ void Mutex::Acquire() { Acquire(GetCurrentThread()); } -void Mutex::Acquire(Thread* thread) { +void Mutex::Acquire(SharedPtr thread) { _assert_msg_(Kernel, !ShouldWait(), "object unavailable!"); if (locked) return; @@ -74,7 +74,7 @@ void Mutex::Acquire(Thread* thread) { locked = true; thread->held_mutexes.insert(this); - holding_thread = thread; + holding_thread = std::move(thread); } void Mutex::Release() { -- cgit v1.2.3 From 88a4a808c688eeabb136e9b45223a0e9c95896bc Mon Sep 17 00:00:00 2001 From: Yuri Kunde Schlesner Date: Sun, 1 Feb 2015 00:14:40 -0200 Subject: Kernel: Stop creating useless Handles during object creation They're finally unnecessary, and will stop cluttering the application's handle table. --- src/core/hle/kernel/mutex.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'src/core/hle/kernel/mutex.cpp') diff --git a/src/core/hle/kernel/mutex.cpp b/src/core/hle/kernel/mutex.cpp index 7c634f9bd..9f7166ca4 100644 --- a/src/core/hle/kernel/mutex.cpp +++ b/src/core/hle/kernel/mutex.cpp @@ -41,10 +41,8 @@ void ReleaseThreadMutexes(Thread* thread) { Mutex::Mutex() {} Mutex::~Mutex() {} -ResultVal> Mutex::Create(bool initial_locked, std::string name) { +SharedPtr Mutex::Create(bool initial_locked, std::string name) { SharedPtr mutex(new Mutex); - // TOOD(yuriks): Don't create Handle (see Thread::Create()) - CASCADE_RESULT(auto unused, Kernel::g_handle_table.Create(mutex)); mutex->initial_locked = initial_locked; mutex->locked = false; @@ -55,7 +53,7 @@ ResultVal> Mutex::Create(bool initial_locked, std::string name) if (initial_locked) mutex->Acquire(); - return MakeResult>(mutex); + return mutex; } bool Mutex::ShouldWait() { -- cgit v1.2.3