mirror of
https://github.com/citra-emu/citra.git
synced 2024-11-15 06:30:05 +00:00
Mutex: Replace g_mutex_held_locks with a set inside Thread
This commit is contained in:
parent
0f69668fc6
commit
4e84df8be3
@ -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);
|
for (auto& mtx : thread->held_mutexes) {
|
||||||
|
ResumeWaitingThread(mtx.get());
|
||||||
// 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());
|
|
||||||
}
|
}
|
||||||
|
thread->held_mutexes.clear();
|
||||||
// Erase all the locks that this thread holds
|
|
||||||
g_mutex_held_locks.erase(thread);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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);
|
holding_thread->held_mutexes.erase(this);
|
||||||
|
|
||||||
for (MutexMap::iterator iter = locked_range.first; iter != locked_range.second; ++iter) {
|
|
||||||
if (iter->second == this) {
|
|
||||||
g_mutex_held_locks.erase(iter);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ResumeWaitingThread(this);
|
ResumeWaitingThread(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -40,6 +40,9 @@ static Thread* current_thread;
|
|||||||
static const u32 INITIAL_THREAD_ID = 1; ///< The first available thread id at startup
|
static const u32 INITIAL_THREAD_ID = 1; ///< The first available thread id at startup
|
||||||
static u32 next_thread_id; ///< The next available thread id
|
static u32 next_thread_id; ///< The next available thread id
|
||||||
|
|
||||||
|
Thread::Thread() {
|
||||||
|
}
|
||||||
|
|
||||||
Thread* GetCurrentThread() {
|
Thread* GetCurrentThread() {
|
||||||
return current_thread;
|
return current_thread;
|
||||||
}
|
}
|
||||||
|
@ -7,6 +7,8 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
#include <boost/container/flat_set.hpp>
|
||||||
|
|
||||||
#include "common/common_types.h"
|
#include "common/common_types.h"
|
||||||
|
|
||||||
#include "core/core.h"
|
#include "core/core.h"
|
||||||
@ -40,6 +42,8 @@ enum ThreadStatus {
|
|||||||
|
|
||||||
namespace Kernel {
|
namespace Kernel {
|
||||||
|
|
||||||
|
class Mutex;
|
||||||
|
|
||||||
class Thread final : public WaitObject {
|
class Thread final : public WaitObject {
|
||||||
public:
|
public:
|
||||||
static ResultVal<SharedPtr<Thread>> Create(std::string name, VAddr entry_point, s32 priority,
|
static ResultVal<SharedPtr<Thread>> Create(std::string name, VAddr entry_point, s32 priority,
|
||||||
@ -109,8 +113,10 @@ public:
|
|||||||
|
|
||||||
s32 processor_id;
|
s32 processor_id;
|
||||||
|
|
||||||
std::vector<SharedPtr<WaitObject>> 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<SharedPtr<Mutex>> held_mutexes;
|
||||||
|
|
||||||
|
std::vector<SharedPtr<WaitObject>> wait_objects; ///< Objects that the thread is waiting on
|
||||||
VAddr wait_address; ///< If waiting on an AddressArbiter, this is the arbitration address
|
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_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
|
bool wait_set_output; ///< True if the output parameter should be set on thread wakeup
|
||||||
@ -121,7 +127,7 @@ public:
|
|||||||
bool idle = false;
|
bool idle = false;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Thread() = default;
|
Thread();
|
||||||
|
|
||||||
/// Handle used as userdata to reference this object when inserting into the CoreTiming queue.
|
/// Handle used as userdata to reference this object when inserting into the CoreTiming queue.
|
||||||
Handle callback_handle;
|
Handle callback_handle;
|
||||||
|
Loading…
Reference in New Issue
Block a user