summaryrefslogtreecommitdiff
path: root/src/core/hle/kernel/thread.cpp
diff options
context:
space:
mode:
authorGravatar bunnei2014-11-24 15:31:53 -0500
committerGravatar bunnei2014-11-24 15:31:53 -0500
commitbb730855e58d18d8964d158a55822c40503d548f (patch)
tree9c3ff113839583d1deca837e9888d81f25d485a0 /src/core/hle/kernel/thread.cpp
parentMerge pull request #191 from archshift/deletexyz (diff)
parentUse pointers instead of passing handles around in some functions. (diff)
downloadyuzu-bb730855e58d18d8964d158a55822c40503d548f.tar.gz
yuzu-bb730855e58d18d8964d158a55822c40503d548f.tar.xz
yuzu-bb730855e58d18d8964d158a55822c40503d548f.zip
Merge pull request #147 from yuriks/error-codes
Error codes
Diffstat (limited to 'src/core/hle/kernel/thread.cpp')
-rw-r--r--src/core/hle/kernel/thread.cpp78
1 files changed, 39 insertions, 39 deletions
diff --git a/src/core/hle/kernel/thread.cpp b/src/core/hle/kernel/thread.cpp
index cc70cbca7..f3f54a4e9 100644
--- a/src/core/hle/kernel/thread.cpp
+++ b/src/core/hle/kernel/thread.cpp
@@ -11,10 +11,11 @@
11#include "common/thread_queue_list.h" 11#include "common/thread_queue_list.h"
12 12
13#include "core/core.h" 13#include "core/core.h"
14#include "core/mem_map.h"
15#include "core/hle/hle.h" 14#include "core/hle/hle.h"
16#include "core/hle/kernel/kernel.h" 15#include "core/hle/kernel/kernel.h"
17#include "core/hle/kernel/thread.h" 16#include "core/hle/kernel/thread.h"
17#include "core/hle/result.h"
18#include "core/mem_map.h"
18 19
19namespace Kernel { 20namespace Kernel {
20 21
@@ -33,21 +34,17 @@ public:
33 inline bool IsWaiting() const { return (status & THREADSTATUS_WAIT) != 0; } 34 inline bool IsWaiting() const { return (status & THREADSTATUS_WAIT) != 0; }
34 inline bool IsSuspended() const { return (status & THREADSTATUS_SUSPEND) != 0; } 35 inline bool IsSuspended() const { return (status & THREADSTATUS_SUSPEND) != 0; }
35 36
36 /** 37 ResultVal<bool> WaitSynchronization() override {
37 * Wait for kernel object to synchronize 38 const bool wait = status != THREADSTATUS_DORMANT;
38 * @param wait Boolean wait set if current thread should wait as a result of sync operation 39 if (wait) {
39 * @return Result of operation, 0 on success, otherwise error code
40 */
41 Result WaitSynchronization(bool* wait) override {
42 if (status != THREADSTATUS_DORMANT) {
43 Handle thread = GetCurrentThreadHandle(); 40 Handle thread = GetCurrentThreadHandle();
44 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()) {
45 waiting_threads.push_back(thread); 42 waiting_threads.push_back(thread);
46 } 43 }
47 WaitCurrentThread(WAITTYPE_THREADEND, this->GetHandle()); 44 WaitCurrentThread(WAITTYPE_THREADEND, this->GetHandle());
48 *wait = true;
49 } 45 }
50 return 0; 46
47 return MakeResult<bool>(wait);
51 } 48 }
52 49
53 ThreadContext context; 50 ThreadContext context;
@@ -144,27 +141,22 @@ void ChangeReadyState(Thread* t, bool ready) {
144} 141}
145 142
146/// Verify that a thread has not been released from waiting 143/// Verify that a thread has not been released from waiting
147inline bool VerifyWait(const Handle& handle, WaitType type, Handle wait_handle) { 144inline bool VerifyWait(const Thread* thread, WaitType type, Handle wait_handle) {
148 Thread* thread = g_object_pool.GetFast<Thread>(handle); 145 _dbg_assert_(KERNEL, thread != nullptr);
149 _assert_msg_(KERNEL, (thread != nullptr), "called, but thread is nullptr!"); 146 return type == thread->wait_type && wait_handle == thread->wait_handle;
150
151 if (type != thread->wait_type || wait_handle != thread->wait_handle)
152 return false;
153
154 return true;
155} 147}
156 148
157/// Stops the current thread 149/// Stops the current thread
158void StopThread(Handle handle, const char* reason) { 150ResultCode StopThread(Handle handle, const char* reason) {
159 Thread* thread = g_object_pool.GetFast<Thread>(handle); 151 Thread* thread = g_object_pool.Get<Thread>(handle);
160 _assert_msg_(KERNEL, (thread != nullptr), "called, but thread is nullptr!"); 152 if (thread == nullptr) return InvalidHandle(ErrorModule::Kernel);
161 153
162 ChangeReadyState(thread, false); 154 ChangeReadyState(thread, false);
163 thread->status = THREADSTATUS_DORMANT; 155 thread->status = THREADSTATUS_DORMANT;
164 for (size_t i = 0; i < thread->waiting_threads.size(); ++i) { 156 for (Handle waiting_handle : thread->waiting_threads) {
165 const Handle waiting_thread = thread->waiting_threads[i]; 157 Thread* waiting_thread = g_object_pool.Get<Thread>(waiting_handle);
166 if (VerifyWait(waiting_thread, WAITTYPE_THREADEND, handle)) { 158 if (VerifyWait(waiting_thread, WAITTYPE_THREADEND, handle)) {
167 ResumeThreadFromWait(waiting_thread); 159 ResumeThreadFromWait(waiting_handle);
168 } 160 }
169 } 161 }
170 thread->waiting_threads.clear(); 162 thread->waiting_threads.clear();
@@ -172,6 +164,8 @@ void StopThread(Handle handle, const char* reason) {
172 // Stopped threads are never waiting. 164 // Stopped threads are never waiting.
173 thread->wait_type = WAITTYPE_NONE; 165 thread->wait_type = WAITTYPE_NONE;
174 thread->wait_handle = 0; 166 thread->wait_handle = 0;
167
168 return RESULT_SUCCESS;
175} 169}
176 170
177/// Changes a threads state 171/// Changes a threads state
@@ -195,13 +189,15 @@ Handle ArbitrateHighestPriorityThread(u32 arbiter, u32 address) {
195 s32 priority = THREADPRIO_LOWEST; 189 s32 priority = THREADPRIO_LOWEST;
196 190
197 // 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...
198 for (const auto& handle : thread_queue) { 192 for (Handle handle : thread_queue) {
193 Thread* thread = g_object_pool.Get<Thread>(handle);
199 194
200 // TODO(bunnei): Verify arbiter address... 195 // TODO(bunnei): Verify arbiter address...
201 if (!VerifyWait(handle, WAITTYPE_ARB, arbiter)) 196 if (!VerifyWait(thread, WAITTYPE_ARB, arbiter))
202 continue; 197 continue;
203 198
204 Thread* thread = g_object_pool.GetFast<Thread>(handle); 199 if (thread == nullptr)
200 continue; // TODO(yuriks): Thread handle will hang around forever. Should clean up.
205 if(thread->current_priority <= priority) { 201 if(thread->current_priority <= priority) {
206 highest_priority_thread = handle; 202 highest_priority_thread = handle;
207 priority = thread->current_priority; 203 priority = thread->current_priority;
@@ -218,10 +214,11 @@ Handle ArbitrateHighestPriorityThread(u32 arbiter, u32 address) {
218void ArbitrateAllThreads(u32 arbiter, u32 address) { 214void ArbitrateAllThreads(u32 arbiter, u32 address) {
219 215
220 // 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...
221 for (const auto& handle : thread_queue) { 217 for (Handle handle : thread_queue) {
218 Thread* thread = g_object_pool.Get<Thread>(handle);
222 219
223 // TODO(bunnei): Verify arbiter address... 220 // TODO(bunnei): Verify arbiter address...
224 if (VerifyWait(handle, WAITTYPE_ARB, arbiter)) 221 if (VerifyWait(thread, WAITTYPE_ARB, arbiter))
225 ResumeThreadFromWait(handle); 222 ResumeThreadFromWait(handle);
226 } 223 }
227} 224}
@@ -272,7 +269,7 @@ Thread* NextThread() {
272 if (next == 0) { 269 if (next == 0) {
273 return nullptr; 270 return nullptr;
274 } 271 }
275 return Kernel::g_object_pool.GetFast<Thread>(next); 272 return Kernel::g_object_pool.Get<Thread>(next);
276} 273}
277 274
278/** 275/**
@@ -289,8 +286,7 @@ void WaitCurrentThread(WaitType wait_type, Handle wait_handle) {
289 286
290/// Resumes a thread from waiting by marking it as "ready" 287/// Resumes a thread from waiting by marking it as "ready"
291void ResumeThreadFromWait(Handle handle) { 288void ResumeThreadFromWait(Handle handle) {
292 u32 error; 289 Thread* thread = Kernel::g_object_pool.Get<Thread>(handle);
293 Thread* thread = Kernel::g_object_pool.Get<Thread>(handle, error);
294 if (thread) { 290 if (thread) {
295 thread->status &= ~THREADSTATUS_WAIT; 291 thread->status &= ~THREADSTATUS_WAIT;
296 if (!(thread->status & (THREADSTATUS_WAITSUSPEND | THREADSTATUS_DORMANT | THREADSTATUS_DEAD))) { 292 if (!(thread->status & (THREADSTATUS_WAITSUSPEND | THREADSTATUS_DORMANT | THREADSTATUS_DEAD))) {
@@ -378,19 +374,23 @@ Handle CreateThread(const char* name, u32 entry_point, s32 priority, u32 arg, s3
378} 374}
379 375
380/// Get the priority of the thread specified by handle 376/// Get the priority of the thread specified by handle
381u32 GetThreadPriority(const Handle handle) { 377ResultVal<u32> GetThreadPriority(const Handle handle) {
382 Thread* thread = g_object_pool.GetFast<Thread>(handle); 378 Thread* thread = g_object_pool.Get<Thread>(handle);
383 _assert_msg_(KERNEL, (thread != nullptr), "called, but thread is nullptr!"); 379 if (thread == nullptr) return InvalidHandle(ErrorModule::Kernel);
384 return thread->current_priority; 380
381 return MakeResult<u32>(thread->current_priority);
385} 382}
386 383
387/// Set the priority of the thread specified by handle 384/// Set the priority of the thread specified by handle
388Result SetThreadPriority(Handle handle, s32 priority) { 385ResultCode SetThreadPriority(Handle handle, s32 priority) {
389 Thread* thread = nullptr; 386 Thread* thread = nullptr;
390 if (!handle) { 387 if (!handle) {
391 thread = GetCurrentThread(); // TODO(bunnei): Is this correct behavior? 388 thread = GetCurrentThread(); // TODO(bunnei): Is this correct behavior?
392 } else { 389 } else {
393 thread = g_object_pool.GetFast<Thread>(handle); 390 thread = g_object_pool.Get<Thread>(handle);
391 if (thread == nullptr) {
392 return InvalidHandle(ErrorModule::Kernel);
393 }
394 } 394 }
395 _assert_msg_(KERNEL, (thread != nullptr), "called, but thread is nullptr!"); 395 _assert_msg_(KERNEL, (thread != nullptr), "called, but thread is nullptr!");
396 396
@@ -417,7 +417,7 @@ Result SetThreadPriority(Handle handle, s32 priority) {
417 thread_ready_queue.push_back(thread->current_priority, handle); 417 thread_ready_queue.push_back(thread->current_priority, handle);
418 } 418 }
419 419
420 return 0; 420 return RESULT_SUCCESS;
421} 421}
422 422
423/// Sets up the primary application thread 423/// Sets up the primary application thread