From 60a373a7862a85b8b030ea1b18d01d364ddf8a8b Mon Sep 17 00:00:00 2001 From: Subv Date: Wed, 7 Jan 2015 10:10:58 -0500 Subject: 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. --- src/core/hle/kernel/thread.cpp | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) (limited to 'src/core/hle/kernel/thread.cpp') 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 @@ #include "common/thread_queue_list.h" #include "core/core.h" +#include "core/core_timing.h" #include "core/hle/hle.h" #include "core/hle/kernel/kernel.h" #include "core/hle/kernel/thread.h" @@ -34,6 +35,7 @@ public: inline bool IsReady() const { return (status & THREADSTATUS_READY) != 0; } inline bool IsWaiting() const { return (status & THREADSTATUS_WAIT) != 0; } inline bool IsSuspended() const { return (status & THREADSTATUS_SUSPEND) != 0; } + inline bool IsIdle() const { return idle; } ResultVal WaitSynchronization() override { const bool wait = status != THREADSTATUS_DORMANT; @@ -69,6 +71,9 @@ public: std::vector waiting_threads; std::string name; + + /// Whether this thread is intended to never actually be executed, i.e. always idle + bool idle = false; }; // Lists all thread ids that aren't deleted/etc. @@ -444,7 +449,14 @@ ResultCode SetThreadPriority(Handle handle, s32 priority) { return RESULT_SUCCESS; } -/// Sets up the primary application thread +Handle SetupIdleThread() { + Handle handle; + Thread* thread = CreateThread(handle, "idle", 0, THREADPRIO_LOWEST, THREADPROCESSORID_0, 0, 0); + thread->idle = true; + CallThread(thread); + return handle; +} + Handle SetupMainThread(s32 priority, int stack_size) { Handle handle; @@ -497,6 +509,15 @@ void Reschedule() { ResumeThreadFromWait(prev->GetHandle()); } +bool IsIdleThread(Handle handle) { + Thread* thread = g_handle_table.Get(handle); + if (!thread) { + LOG_ERROR(Kernel, "Thread not found %u", handle); + return false; + } + return thread->IsIdle(); +} + ResultCode GetThreadId(u32* thread_id, Handle handle) { Thread* thread = g_handle_table.Get(handle); if (thread == nullptr) -- cgit v1.2.3