summaryrefslogtreecommitdiff
path: root/src/core
diff options
context:
space:
mode:
Diffstat (limited to 'src/core')
-rw-r--r--src/core/hle/kernel/mutex.cpp28
-rw-r--r--src/core/hle/kernel/thread.cpp3
-rw-r--r--src/core/hle/kernel/thread.h10
3 files changed, 18 insertions, 23 deletions
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 @@
5#include <map> 5#include <map>
6#include <vector> 6#include <vector>
7 7
8#include <boost/range/algorithm_ext/erase.hpp>
9
8#include "common/common.h" 10#include "common/common.h"
9 11
10#include "core/hle/kernel/kernel.h" 12#include "core/hle/kernel/kernel.h"
@@ -13,9 +15,6 @@
13 15
14namespace Kernel { 16namespace Kernel {
15 17
16typedef std::multimap<SharedPtr<Thread>, SharedPtr<Mutex>> MutexMap;
17static MutexMap g_mutex_held_locks;
18
19/** 18/**
20 * Resumes a thread waiting for the specified mutex 19 * Resumes a thread waiting for the specified mutex
21 * @param mutex The mutex that some thread is waiting on 20 * @param mutex The mutex that some thread is waiting on
@@ -33,15 +32,10 @@ static void ResumeWaitingThread(Mutex* mutex) {
33} 32}
34 33
35void ReleaseThreadMutexes(Thread* thread) { 34void ReleaseThreadMutexes(Thread* thread) {
36 auto locked_range = g_mutex_held_locks.equal_range(thread); 35 for (auto& mtx : thread->held_mutexes) {
37 36 ResumeWaitingThread(mtx.get());
38 // Release every mutex that the thread holds, and resume execution on the waiting threads
39 for (auto iter = locked_range.first; iter != locked_range.second; ++iter) {
40 ResumeWaitingThread(iter->second.get());
41 } 37 }
42 38 thread->held_mutexes.clear();
43 // Erase all the locks that this thread holds
44 g_mutex_held_locks.erase(thread);
45} 39}
46 40
47ResultVal<SharedPtr<Mutex>> Mutex::Create(bool initial_locked, std::string name) { 41ResultVal<SharedPtr<Mutex>> Mutex::Create(bool initial_locked, std::string name) {
@@ -76,7 +70,7 @@ void Mutex::Acquire(Thread* thread) {
76 70
77 locked = true; 71 locked = true;
78 72
79 g_mutex_held_locks.insert(std::make_pair(thread, this)); 73 thread->held_mutexes.insert(this);
80 holding_thread = thread; 74 holding_thread = thread;
81} 75}
82 76
@@ -84,15 +78,7 @@ void Mutex::Release() {
84 if (!locked) 78 if (!locked)
85 return; 79 return;
86 80
87 auto locked_range = g_mutex_held_locks.equal_range(holding_thread); 81 holding_thread->held_mutexes.erase(this);
88
89 for (MutexMap::iterator iter = locked_range.first; iter != locked_range.second; ++iter) {
90 if (iter->second == this) {
91 g_mutex_held_locks.erase(iter);
92 break;
93 }
94 }
95
96 ResumeWaitingThread(this); 82 ResumeWaitingThread(this);
97} 83}
98 84
diff --git a/src/core/hle/kernel/thread.cpp b/src/core/hle/kernel/thread.cpp
index 2fae1b3bc..3c6669ca2 100644
--- a/src/core/hle/kernel/thread.cpp
+++ b/src/core/hle/kernel/thread.cpp
@@ -40,6 +40,9 @@ static Thread* current_thread;
40static const u32 INITIAL_THREAD_ID = 1; ///< The first available thread id at startup 40static const u32 INITIAL_THREAD_ID = 1; ///< The first available thread id at startup
41static u32 next_thread_id; ///< The next available thread id 41static u32 next_thread_id; ///< The next available thread id
42 42
43Thread::Thread() {
44}
45
43Thread* GetCurrentThread() { 46Thread* GetCurrentThread() {
44 return current_thread; 47 return current_thread;
45} 48}
diff --git a/src/core/hle/kernel/thread.h b/src/core/hle/kernel/thread.h
index 9a4a00fe8..f29897ae8 100644
--- a/src/core/hle/kernel/thread.h
+++ b/src/core/hle/kernel/thread.h
@@ -7,6 +7,8 @@
7#include <string> 7#include <string>
8#include <vector> 8#include <vector>
9 9
10#include <boost/container/flat_set.hpp>
11
10#include "common/common_types.h" 12#include "common/common_types.h"
11 13
12#include "core/core.h" 14#include "core/core.h"
@@ -40,6 +42,8 @@ enum ThreadStatus {
40 42
41namespace Kernel { 43namespace Kernel {
42 44
45class Mutex;
46
43class Thread final : public WaitObject { 47class Thread final : public WaitObject {
44public: 48public:
45 static ResultVal<SharedPtr<Thread>> Create(std::string name, VAddr entry_point, s32 priority, 49 static ResultVal<SharedPtr<Thread>> Create(std::string name, VAddr entry_point, s32 priority,
@@ -109,8 +113,10 @@ public:
109 113
110 s32 processor_id; 114 s32 processor_id;
111 115
112 std::vector<SharedPtr<WaitObject>> wait_objects; ///< Objects that the thread is waiting on 116 /// Mutexes currently held by this thread, which will be released when it exits.
117 boost::container::flat_set<SharedPtr<Mutex>> held_mutexes;
113 118
119 std::vector<SharedPtr<WaitObject>> wait_objects; ///< Objects that the thread is waiting on
114 VAddr wait_address; ///< If waiting on an AddressArbiter, this is the arbitration address 120 VAddr wait_address; ///< If waiting on an AddressArbiter, this is the arbitration address
115 bool wait_all; ///< True if the thread is waiting on all objects before resuming 121 bool wait_all; ///< True if the thread is waiting on all objects before resuming
116 bool wait_set_output; ///< True if the output parameter should be set on thread wakeup 122 bool wait_set_output; ///< True if the output parameter should be set on thread wakeup
@@ -121,7 +127,7 @@ public:
121 bool idle = false; 127 bool idle = false;
122 128
123private: 129private:
124 Thread() = default; 130 Thread();
125 131
126 /// Handle used as userdata to reference this object when inserting into the CoreTiming queue. 132 /// Handle used as userdata to reference this object when inserting into the CoreTiming queue.
127 Handle callback_handle; 133 Handle callback_handle;