summaryrefslogtreecommitdiff
path: root/src/core/hle/kernel/thread.h
diff options
context:
space:
mode:
authorGravatar Sebastian Valle2017-01-05 12:55:01 -0500
committerGravatar GitHub2017-01-05 12:55:01 -0500
commitf20d872643654c574f73a263f032613046900f07 (patch)
tree021284c18034d053c81928fa19d2efb6658451fb /src/core/hle/kernel/thread.h
parentMerge pull request #2407 from jroweboy/nightly-deploy (diff)
parentKernel: Add some asserts to enforce the invariants in the scheduler. (diff)
downloadyuzu-f20d872643654c574f73a263f032613046900f07.tar.gz
yuzu-f20d872643654c574f73a263f032613046900f07.tar.xz
yuzu-f20d872643654c574f73a263f032613046900f07.zip
Merge pull request #2393 from Subv/synch
Kernel: Mutex priority inheritance and synchronization improvements.
Diffstat (limited to 'src/core/hle/kernel/thread.h')
-rw-r--r--src/core/hle/kernel/thread.h48
1 files changed, 28 insertions, 20 deletions
diff --git a/src/core/hle/kernel/thread.h b/src/core/hle/kernel/thread.h
index c77ac644d..af72b76ea 100644
--- a/src/core/hle/kernel/thread.h
+++ b/src/core/hle/kernel/thread.h
@@ -31,13 +31,14 @@ enum ThreadProcessorId : s32 {
31}; 31};
32 32
33enum ThreadStatus { 33enum ThreadStatus {
34 THREADSTATUS_RUNNING, ///< Currently running 34 THREADSTATUS_RUNNING, ///< Currently running
35 THREADSTATUS_READY, ///< Ready to run 35 THREADSTATUS_READY, ///< Ready to run
36 THREADSTATUS_WAIT_ARB, ///< Waiting on an address arbiter 36 THREADSTATUS_WAIT_ARB, ///< Waiting on an address arbiter
37 THREADSTATUS_WAIT_SLEEP, ///< Waiting due to a SleepThread SVC 37 THREADSTATUS_WAIT_SLEEP, ///< Waiting due to a SleepThread SVC
38 THREADSTATUS_WAIT_SYNCH, ///< Waiting due to a WaitSynchronization SVC 38 THREADSTATUS_WAIT_SYNCH_ANY, ///< Waiting due to WaitSynch1 or WaitSynchN with wait_all = false
39 THREADSTATUS_DORMANT, ///< Created but not yet made ready 39 THREADSTATUS_WAIT_SYNCH_ALL, ///< Waiting due to WaitSynchronizationN with wait_all = true
40 THREADSTATUS_DEAD ///< Run to completion, or forcefully terminated 40 THREADSTATUS_DORMANT, ///< Created but not yet made ready
41 THREADSTATUS_DEAD ///< Run to completion, or forcefully terminated
41}; 42};
42 43
43namespace Kernel { 44namespace Kernel {
@@ -72,8 +73,8 @@ public:
72 return HANDLE_TYPE; 73 return HANDLE_TYPE;
73 } 74 }
74 75
75 bool ShouldWait() override; 76 bool ShouldWait(Thread* thread) const override;
76 void Acquire() override; 77 void Acquire(Thread* thread) override;
77 78
78 /** 79 /**
79 * Gets the thread's current priority 80 * Gets the thread's current priority
@@ -90,6 +91,12 @@ public:
90 void SetPriority(s32 priority); 91 void SetPriority(s32 priority);
91 92
92 /** 93 /**
94 * Boost's a thread's priority to the best priority among the thread's held mutexes.
95 * This prevents priority inversion via priority inheritance.
96 */
97 void UpdatePriority();
98
99 /**
93 * Temporarily boosts the thread's priority until the next time it is scheduled 100 * Temporarily boosts the thread's priority until the next time it is scheduled
94 * @param priority The new priority 101 * @param priority The new priority
95 */ 102 */
@@ -128,13 +135,14 @@ public:
128 135
129 /** 136 /**
130 * Retrieves the index that this particular object occupies in the list of objects 137 * Retrieves the index that this particular object occupies in the list of objects
131 * that the thread passed to WaitSynchronizationN. 138 * that the thread passed to WaitSynchronizationN, starting the search from the last element.
132 * It is used to set the output value of WaitSynchronizationN when the thread is awakened. 139 * It is used to set the output value of WaitSynchronizationN when the thread is awakened.
140 * When a thread wakes up due to an object signal, the kernel will use the index of the last
141 * matching object in the wait objects list in case of having multiple instances of the same
142 * object in the list.
133 * @param object Object to query the index of. 143 * @param object Object to query the index of.
134 */ 144 */
135 s32 GetWaitObjectIndex(const WaitObject* object) const { 145 s32 GetWaitObjectIndex(WaitObject* object) const;
136 return wait_objects_index.at(object->GetObjectId());
137 }
138 146
139 /** 147 /**
140 * Stops a thread, invalidating it from further use 148 * Stops a thread, invalidating it from further use
@@ -152,10 +160,10 @@ public:
152 /** 160 /**
153 * Returns whether this thread is waiting for all the objects in 161 * Returns whether this thread is waiting for all the objects in
154 * its wait list to become ready, as a result of a WaitSynchronizationN call 162 * its wait list to become ready, as a result of a WaitSynchronizationN call
155 * with wait_all = true, or a ReplyAndReceive call. 163 * with wait_all = true.
156 */ 164 */
157 bool IsSleepingOnWaitAll() const { 165 bool IsSleepingOnWaitAll() const {
158 return !wait_objects.empty(); 166 return status == THREADSTATUS_WAIT_SYNCH_ALL;
159 } 167 }
160 168
161 ARM_Interface::ThreadContext context; 169 ARM_Interface::ThreadContext context;
@@ -178,15 +186,15 @@ public:
178 /// Mutexes currently held by this thread, which will be released when it exits. 186 /// Mutexes currently held by this thread, which will be released when it exits.
179 boost::container::flat_set<SharedPtr<Mutex>> held_mutexes; 187 boost::container::flat_set<SharedPtr<Mutex>> held_mutexes;
180 188
189 /// Mutexes that this thread is currently waiting for.
190 boost::container::flat_set<SharedPtr<Mutex>> pending_mutexes;
191
181 SharedPtr<Process> owner_process; ///< Process that owns this thread 192 SharedPtr<Process> owner_process; ///< Process that owns this thread
182 193
183 /// Objects that the thread is waiting on. 194 /// Objects that the thread is waiting on, in the same order as they were
184 /// This is only populated when the thread should wait for all the objects to become ready. 195 // passed to WaitSynchronization1/N.
185 std::vector<SharedPtr<WaitObject>> wait_objects; 196 std::vector<SharedPtr<WaitObject>> wait_objects;
186 197
187 /// Mapping of Object ids to their position in the last waitlist that this object waited on.
188 boost::container::flat_map<int, s32> wait_objects_index;
189
190 VAddr wait_address; ///< If waiting on an AddressArbiter, this is the arbitration address 198 VAddr wait_address; ///< If waiting on an AddressArbiter, this is the arbitration address
191 199
192 /// True if the WaitSynchronizationN output parameter should be set on thread wakeup. 200 /// True if the WaitSynchronizationN output parameter should be set on thread wakeup.