summaryrefslogtreecommitdiff
path: root/src/core/hle/kernel/thread.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/hle/kernel/thread.cpp')
-rw-r--r--src/core/hle/kernel/thread.cpp51
1 files changed, 30 insertions, 21 deletions
diff --git a/src/core/hle/kernel/thread.cpp b/src/core/hle/kernel/thread.cpp
index cc70cbca7..b01779f2e 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
@@ -38,16 +39,17 @@ public:
38 * @param wait Boolean wait set if current thread should wait as a result of sync operation 39 * @param wait Boolean wait set if current thread should wait as a result of sync operation
39 * @return Result of operation, 0 on success, otherwise error code 40 * @return Result of operation, 0 on success, otherwise error code
40 */ 41 */
41 Result WaitSynchronization(bool* wait) override { 42 ResultVal<bool> WaitSynchronization() override {
42 if (status != THREADSTATUS_DORMANT) { 43 if (status != THREADSTATUS_DORMANT) {
43 Handle thread = GetCurrentThreadHandle(); 44 Handle thread = GetCurrentThreadHandle();
44 if (std::find(waiting_threads.begin(), waiting_threads.end(), thread) == waiting_threads.end()) { 45 if (std::find(waiting_threads.begin(), waiting_threads.end(), thread) == waiting_threads.end()) {
45 waiting_threads.push_back(thread); 46 waiting_threads.push_back(thread);
46 } 47 }
47 WaitCurrentThread(WAITTYPE_THREADEND, this->GetHandle()); 48 WaitCurrentThread(WAITTYPE_THREADEND, this->GetHandle());
48 *wait = true; 49 return MakeResult<bool>(true);
50 } else {
51 return MakeResult<bool>(false);
49 } 52 }
50 return 0;
51 } 53 }
52 54
53 ThreadContext context; 55 ThreadContext context;
@@ -144,9 +146,9 @@ void ChangeReadyState(Thread* t, bool ready) {
144} 146}
145 147
146/// Verify that a thread has not been released from waiting 148/// Verify that a thread has not been released from waiting
147inline bool VerifyWait(const Handle& handle, WaitType type, Handle wait_handle) { 149inline bool VerifyWait(Handle handle, WaitType type, Handle wait_handle) {
148 Thread* thread = g_object_pool.GetFast<Thread>(handle); 150 Thread* thread = g_object_pool.Get<Thread>(handle);
149 _assert_msg_(KERNEL, (thread != nullptr), "called, but thread is nullptr!"); 151 _dbg_assert_(KERNEL, thread != nullptr);
150 152
151 if (type != thread->wait_type || wait_handle != thread->wait_handle) 153 if (type != thread->wait_type || wait_handle != thread->wait_handle)
152 return false; 154 return false;
@@ -155,9 +157,9 @@ inline bool VerifyWait(const Handle& handle, WaitType type, Handle wait_handle)
155} 157}
156 158
157/// Stops the current thread 159/// Stops the current thread
158void StopThread(Handle handle, const char* reason) { 160ResultCode StopThread(Handle handle, const char* reason) {
159 Thread* thread = g_object_pool.GetFast<Thread>(handle); 161 Thread* thread = g_object_pool.Get<Thread>(handle);
160 _assert_msg_(KERNEL, (thread != nullptr), "called, but thread is nullptr!"); 162 if (thread == nullptr) return InvalidHandle(ErrorModule::Kernel);
161 163
162 ChangeReadyState(thread, false); 164 ChangeReadyState(thread, false);
163 thread->status = THREADSTATUS_DORMANT; 165 thread->status = THREADSTATUS_DORMANT;
@@ -172,6 +174,8 @@ void StopThread(Handle handle, const char* reason) {
172 // Stopped threads are never waiting. 174 // Stopped threads are never waiting.
173 thread->wait_type = WAITTYPE_NONE; 175 thread->wait_type = WAITTYPE_NONE;
174 thread->wait_handle = 0; 176 thread->wait_handle = 0;
177
178 return RESULT_SUCCESS;
175} 179}
176 180
177/// Changes a threads state 181/// Changes a threads state
@@ -201,7 +205,9 @@ Handle ArbitrateHighestPriorityThread(u32 arbiter, u32 address) {
201 if (!VerifyWait(handle, WAITTYPE_ARB, arbiter)) 205 if (!VerifyWait(handle, WAITTYPE_ARB, arbiter))
202 continue; 206 continue;
203 207
204 Thread* thread = g_object_pool.GetFast<Thread>(handle); 208 Thread* thread = g_object_pool.Get<Thread>(handle);
209 if (thread == nullptr)
210 continue; // TODO(yuriks): Thread handle will hang around forever. Should clean up.
205 if(thread->current_priority <= priority) { 211 if(thread->current_priority <= priority) {
206 highest_priority_thread = handle; 212 highest_priority_thread = handle;
207 priority = thread->current_priority; 213 priority = thread->current_priority;
@@ -272,7 +278,7 @@ Thread* NextThread() {
272 if (next == 0) { 278 if (next == 0) {
273 return nullptr; 279 return nullptr;
274 } 280 }
275 return Kernel::g_object_pool.GetFast<Thread>(next); 281 return Kernel::g_object_pool.Get<Thread>(next);
276} 282}
277 283
278/** 284/**
@@ -289,8 +295,7 @@ void WaitCurrentThread(WaitType wait_type, Handle wait_handle) {
289 295
290/// Resumes a thread from waiting by marking it as "ready" 296/// Resumes a thread from waiting by marking it as "ready"
291void ResumeThreadFromWait(Handle handle) { 297void ResumeThreadFromWait(Handle handle) {
292 u32 error; 298 Thread* thread = Kernel::g_object_pool.Get<Thread>(handle);
293 Thread* thread = Kernel::g_object_pool.Get<Thread>(handle, error);
294 if (thread) { 299 if (thread) {
295 thread->status &= ~THREADSTATUS_WAIT; 300 thread->status &= ~THREADSTATUS_WAIT;
296 if (!(thread->status & (THREADSTATUS_WAITSUSPEND | THREADSTATUS_DORMANT | THREADSTATUS_DEAD))) { 301 if (!(thread->status & (THREADSTATUS_WAITSUSPEND | THREADSTATUS_DORMANT | THREADSTATUS_DEAD))) {
@@ -378,19 +383,23 @@ Handle CreateThread(const char* name, u32 entry_point, s32 priority, u32 arg, s3
378} 383}
379 384
380/// Get the priority of the thread specified by handle 385/// Get the priority of the thread specified by handle
381u32 GetThreadPriority(const Handle handle) { 386ResultVal<u32> GetThreadPriority(const Handle handle) {
382 Thread* thread = g_object_pool.GetFast<Thread>(handle); 387 Thread* thread = g_object_pool.Get<Thread>(handle);
383 _assert_msg_(KERNEL, (thread != nullptr), "called, but thread is nullptr!"); 388 if (thread == nullptr) return InvalidHandle(ErrorModule::Kernel);
384 return thread->current_priority; 389
390 return MakeResult<u32>(thread->current_priority);
385} 391}
386 392
387/// Set the priority of the thread specified by handle 393/// Set the priority of the thread specified by handle
388Result SetThreadPriority(Handle handle, s32 priority) { 394ResultCode SetThreadPriority(Handle handle, s32 priority) {
389 Thread* thread = nullptr; 395 Thread* thread = nullptr;
390 if (!handle) { 396 if (!handle) {
391 thread = GetCurrentThread(); // TODO(bunnei): Is this correct behavior? 397 thread = GetCurrentThread(); // TODO(bunnei): Is this correct behavior?
392 } else { 398 } else {
393 thread = g_object_pool.GetFast<Thread>(handle); 399 thread = g_object_pool.Get<Thread>(handle);
400 if (thread == nullptr) {
401 return InvalidHandle(ErrorModule::Kernel);
402 }
394 } 403 }
395 _assert_msg_(KERNEL, (thread != nullptr), "called, but thread is nullptr!"); 404 _assert_msg_(KERNEL, (thread != nullptr), "called, but thread is nullptr!");
396 405
@@ -417,7 +426,7 @@ Result SetThreadPriority(Handle handle, s32 priority) {
417 thread_ready_queue.push_back(thread->current_priority, handle); 426 thread_ready_queue.push_back(thread->current_priority, handle);
418 } 427 }
419 428
420 return 0; 429 return RESULT_SUCCESS;
421} 430}
422 431
423/// Sets up the primary application thread 432/// Sets up the primary application thread