diff options
| author | 2015-01-07 10:10:58 -0500 | |
|---|---|---|
| committer | 2015-01-07 20:31:31 -0500 | |
| commit | 60a373a7862a85b8b030ea1b18d01d364ddf8a8b (patch) | |
| tree | e9e6288406b16f2a8dd10236c96567a895af3410 /src/core/hle/kernel/thread.cpp | |
| parent | Merge pull request #404 from bunnei/more-frame-synch-fixes (diff) | |
| download | yuzu-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.cpp | 23 |
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 | 452 | Handle 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 | |||
| 448 | Handle SetupMainThread(s32 priority, int stack_size) { | 460 | Handle 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 | ||
| 512 | bool 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 | |||
| 500 | ResultCode GetThreadId(u32* thread_id, Handle handle) { | 521 | ResultCode 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) |