summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/core/hle/kernel/mutex.cpp72
-rw-r--r--src/core/hle/kernel/mutex.h2
-rw-r--r--src/core/hle/kernel/thread.cpp2
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;