summaryrefslogtreecommitdiff
path: root/src/core/hle/kernel/thread.cpp
diff options
context:
space:
mode:
authorGravatar Subv2015-01-07 10:10:58 -0500
committerGravatar Subv2015-01-07 20:31:31 -0500
commit60a373a7862a85b8b030ea1b18d01d364ddf8a8b (patch)
treee9e6288406b16f2a8dd10236c96567a895af3410 /src/core/hle/kernel/thread.cpp
parentMerge pull request #404 from bunnei/more-frame-synch-fixes (diff)
downloadyuzu-60a373a7862a85b8b030ea1b18d01d364ddf8a8b.tar.gz
yuzu-60a373a7862a85b8b030ea1b18d01d364ddf8a8b.tar.xz
yuzu-60a373a7862a85b8b030ea1b18d01d364ddf8a8b.zip
Threads: Use a dummy idle thread when no other are ready.
This thread will not actually execute instructions, it will only advance the timing/events and try to yield immediately to the next ready thread, if there aren't any ready threads then it will be rescheduled and start its job again.
Diffstat (limited to 'src/core/hle/kernel/thread.cpp')
-rw-r--r--src/core/hle/kernel/thread.cpp23
1 files changed, 22 insertions, 1 deletions
diff --git a/src/core/hle/kernel/thread.cpp b/src/core/hle/kernel/thread.cpp
index d76451146..58fb62e89 100644
--- a/src/core/hle/kernel/thread.cpp
+++ b/src/core/hle/kernel/thread.cpp
@@ -11,6 +11,7 @@
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/core_timing.h"
14#include "core/hle/hle.h" 15#include "core/hle/hle.h"
15#include "core/hle/kernel/kernel.h" 16#include "core/hle/kernel/kernel.h"
16#include "core/hle/kernel/thread.h" 17#include "core/hle/kernel/thread.h"
@@ -34,6 +35,7 @@ public:
34 inline bool IsReady() const { return (status & THREADSTATUS_READY) != 0; } 35 inline bool IsReady() const { return (status & THREADSTATUS_READY) != 0; }
35 inline bool IsWaiting() const { return (status & THREADSTATUS_WAIT) != 0; } 36 inline bool IsWaiting() const { return (status & THREADSTATUS_WAIT) != 0; }
36 inline bool IsSuspended() const { return (status & THREADSTATUS_SUSPEND) != 0; } 37 inline bool IsSuspended() const { return (status & THREADSTATUS_SUSPEND) != 0; }
38 inline bool IsIdle() const { return idle; }
37 39
38 ResultVal<bool> WaitSynchronization() override { 40 ResultVal<bool> WaitSynchronization() override {
39 const bool wait = status != THREADSTATUS_DORMANT; 41 const bool wait = status != THREADSTATUS_DORMANT;
@@ -69,6 +71,9 @@ public:
69 std::vector<Handle> waiting_threads; 71 std::vector<Handle> waiting_threads;
70 72
71 std::string name; 73 std::string name;
74
75 /// Whether this thread is intended to never actually be executed, i.e. always idle
76 bool idle = false;
72}; 77};
73 78
74// Lists all thread ids that aren't deleted/etc. 79// Lists all thread ids that aren't deleted/etc.
@@ -444,7 +449,14 @@ ResultCode SetThreadPriority(Handle handle, s32 priority) {
444 return RESULT_SUCCESS; 449 return RESULT_SUCCESS;
445} 450}
446 451
447/// Sets up the primary application thread 452Handle SetupIdleThread() {
453 Handle handle;
454 Thread* thread = CreateThread(handle, "idle", 0, THREADPRIO_LOWEST, THREADPROCESSORID_0, 0, 0);
455 thread->idle = true;
456 CallThread(thread);
457 return handle;
458}
459
448Handle SetupMainThread(s32 priority, int stack_size) { 460Handle SetupMainThread(s32 priority, int stack_size) {
449 Handle handle; 461 Handle handle;
450 462
@@ -497,6 +509,15 @@ void Reschedule() {
497 ResumeThreadFromWait(prev->GetHandle()); 509 ResumeThreadFromWait(prev->GetHandle());
498} 510}
499 511
512bool IsIdleThread(Handle handle) {
513 Thread* thread = g_handle_table.Get<Thread>(handle);
514 if (!thread) {
515 LOG_ERROR(Kernel, "Thread not found %u", handle);
516 return false;
517 }
518 return thread->IsIdle();
519}
520
500ResultCode GetThreadId(u32* thread_id, Handle handle) { 521ResultCode GetThreadId(u32* thread_id, Handle handle) {
501 Thread* thread = g_handle_table.Get<Thread>(handle); 522 Thread* thread = g_handle_table.Get<Thread>(handle);
502 if (thread == nullptr) 523 if (thread == nullptr)