summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/core/hle/kernel/thread.cpp34
1 files changed, 15 insertions, 19 deletions
diff --git a/src/core/hle/kernel/thread.cpp b/src/core/hle/kernel/thread.cpp
index 2521f883d..f3f54a4e9 100644
--- a/src/core/hle/kernel/thread.cpp
+++ b/src/core/hle/kernel/thread.cpp
@@ -35,16 +35,16 @@ public:
35 inline bool IsSuspended() const { return (status & THREADSTATUS_SUSPEND) != 0; } 35 inline bool IsSuspended() const { return (status & THREADSTATUS_SUSPEND) != 0; }
36 36
37 ResultVal<bool> WaitSynchronization() override { 37 ResultVal<bool> WaitSynchronization() override {
38 if (status != THREADSTATUS_DORMANT) { 38 const bool wait = status != THREADSTATUS_DORMANT;
39 if (wait) {
39 Handle thread = GetCurrentThreadHandle(); 40 Handle thread = GetCurrentThreadHandle();
40 if (std::find(waiting_threads.begin(), waiting_threads.end(), thread) == waiting_threads.end()) { 41 if (std::find(waiting_threads.begin(), waiting_threads.end(), thread) == waiting_threads.end()) {
41 waiting_threads.push_back(thread); 42 waiting_threads.push_back(thread);
42 } 43 }
43 WaitCurrentThread(WAITTYPE_THREADEND, this->GetHandle()); 44 WaitCurrentThread(WAITTYPE_THREADEND, this->GetHandle());
44 return MakeResult<bool>(true);
45 } else {
46 return MakeResult<bool>(false);
47 } 45 }
46
47 return MakeResult<bool>(wait);
48 } 48 }
49 49
50 ThreadContext context; 50 ThreadContext context;
@@ -141,14 +141,9 @@ void ChangeReadyState(Thread* t, bool ready) {
141} 141}
142 142
143/// Verify that a thread has not been released from waiting 143/// Verify that a thread has not been released from waiting
144inline bool VerifyWait(Handle handle, WaitType type, Handle wait_handle) { 144inline bool VerifyWait(const Thread* thread, WaitType type, Handle wait_handle) {
145 Thread* thread = g_object_pool.Get<Thread>(handle);
146 _dbg_assert_(KERNEL, thread != nullptr); 145 _dbg_assert_(KERNEL, thread != nullptr);
147 146 return type == thread->wait_type && wait_handle == thread->wait_handle;
148 if (type != thread->wait_type || wait_handle != thread->wait_handle)
149 return false;
150
151 return true;
152} 147}
153 148
154/// Stops the current thread 149/// Stops the current thread
@@ -158,10 +153,10 @@ ResultCode StopThread(Handle handle, const char* reason) {
158 153
159 ChangeReadyState(thread, false); 154 ChangeReadyState(thread, false);
160 thread->status = THREADSTATUS_DORMANT; 155 thread->status = THREADSTATUS_DORMANT;
161 for (size_t i = 0; i < thread->waiting_threads.size(); ++i) { 156 for (Handle waiting_handle : thread->waiting_threads) {
162 const Handle waiting_thread = thread->waiting_threads[i]; 157 Thread* waiting_thread = g_object_pool.Get<Thread>(waiting_handle);
163 if (VerifyWait(waiting_thread, WAITTYPE_THREADEND, handle)) { 158 if (VerifyWait(waiting_thread, WAITTYPE_THREADEND, handle)) {
164 ResumeThreadFromWait(waiting_thread); 159 ResumeThreadFromWait(waiting_handle);
165 } 160 }
166 } 161 }
167 thread->waiting_threads.clear(); 162 thread->waiting_threads.clear();
@@ -194,13 +189,13 @@ Handle ArbitrateHighestPriorityThread(u32 arbiter, u32 address) {
194 s32 priority = THREADPRIO_LOWEST; 189 s32 priority = THREADPRIO_LOWEST;
195 190
196 // Iterate through threads, find highest priority thread that is waiting to be arbitrated... 191 // Iterate through threads, find highest priority thread that is waiting to be arbitrated...
197 for (const auto& handle : thread_queue) { 192 for (Handle handle : thread_queue) {
193 Thread* thread = g_object_pool.Get<Thread>(handle);
198 194
199 // TODO(bunnei): Verify arbiter address... 195 // TODO(bunnei): Verify arbiter address...
200 if (!VerifyWait(handle, WAITTYPE_ARB, arbiter)) 196 if (!VerifyWait(thread, WAITTYPE_ARB, arbiter))
201 continue; 197 continue;
202 198
203 Thread* thread = g_object_pool.Get<Thread>(handle);
204 if (thread == nullptr) 199 if (thread == nullptr)
205 continue; // TODO(yuriks): Thread handle will hang around forever. Should clean up. 200 continue; // TODO(yuriks): Thread handle will hang around forever. Should clean up.
206 if(thread->current_priority <= priority) { 201 if(thread->current_priority <= priority) {
@@ -219,10 +214,11 @@ Handle ArbitrateHighestPriorityThread(u32 arbiter, u32 address) {
219void ArbitrateAllThreads(u32 arbiter, u32 address) { 214void ArbitrateAllThreads(u32 arbiter, u32 address) {
220 215
221 // Iterate through threads, find highest priority thread that is waiting to be arbitrated... 216 // Iterate through threads, find highest priority thread that is waiting to be arbitrated...
222 for (const auto& handle : thread_queue) { 217 for (Handle handle : thread_queue) {
218 Thread* thread = g_object_pool.Get<Thread>(handle);
223 219
224 // TODO(bunnei): Verify arbiter address... 220 // TODO(bunnei): Verify arbiter address...
225 if (VerifyWait(handle, WAITTYPE_ARB, arbiter)) 221 if (VerifyWait(thread, WAITTYPE_ARB, arbiter))
226 ResumeThreadFromWait(handle); 222 ResumeThreadFromWait(handle);
227 } 223 }
228} 224}