|
|
@ -5,6 +5,8 @@ |
|
|
#include <map>
|
|
|
#include <map>
|
|
|
#include <vector>
|
|
|
#include <vector>
|
|
|
|
|
|
|
|
|
|
|
|
#include <boost/range/algorithm_ext/erase.hpp>
|
|
|
|
|
|
|
|
|
#include "common/common.h"
|
|
|
#include "common/common.h"
|
|
|
|
|
|
|
|
|
#include "core/hle/kernel/kernel.h"
|
|
|
#include "core/hle/kernel/kernel.h"
|
|
|
@ -13,9 +15,6 @@ |
|
|
|
|
|
|
|
|
namespace Kernel { |
|
|
namespace Kernel { |
|
|
|
|
|
|
|
|
typedef std::multimap<SharedPtr<Thread>, SharedPtr<Mutex>> MutexMap; |
|
|
|
|
|
static MutexMap g_mutex_held_locks; |
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
/**
|
|
|
* Resumes a thread waiting for the specified mutex |
|
|
* Resumes a thread waiting for the specified mutex |
|
|
* @param mutex The mutex that some thread is waiting on |
|
|
* @param mutex The mutex that some thread is waiting on |
|
|
@ -33,15 +32,10 @@ static void ResumeWaitingThread(Mutex* mutex) { |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
void ReleaseThreadMutexes(Thread* thread) { |
|
|
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<SharedPtr<Mutex>> Mutex::Create(bool initial_locked, std::string name) { |
|
|
ResultVal<SharedPtr<Mutex>> Mutex::Create(bool initial_locked, std::string name) { |
|
|
@ -76,7 +70,7 @@ void Mutex::Acquire(Thread* thread) { |
|
|
|
|
|
|
|
|
locked = true; |
|
|
locked = true; |
|
|
|
|
|
|
|
|
g_mutex_held_locks.insert(std::make_pair(thread, this)); |
|
|
|
|
|
|
|
|
thread->held_mutexes.insert(this); |
|
|
holding_thread = thread; |
|
|
holding_thread = thread; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
@ -84,15 +78,7 @@ void Mutex::Release() { |
|
|
if (!locked) |
|
|
if (!locked) |
|
|
return; |
|
|
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); |
|
|
ResumeWaitingThread(this); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|