summaryrefslogtreecommitdiff
path: root/src/core/hle/kernel/thread.cpp
diff options
context:
space:
mode:
authorGravatar Yuri Kunde Schlesner2015-05-11 16:09:10 -0300
committerGravatar Yuri Kunde Schlesner2015-05-11 22:39:39 -0300
commit4f7a055081dff4299ee049a03c7a6f1659406942 (patch)
treea9ba4323003af89d5fcb8b993a27bcad98401e06 /src/core/hle/kernel/thread.cpp
parentMerge pull request #749 from yuriks/stack-top (diff)
downloadyuzu-4f7a055081dff4299ee049a03c7a6f1659406942.tar.gz
yuzu-4f7a055081dff4299ee049a03c7a6f1659406942.tar.xz
yuzu-4f7a055081dff4299ee049a03c7a6f1659406942.zip
Thread: Remove the idle thread
Instead just use nullptr to represent no thread is active.
Diffstat (limited to 'src/core/hle/kernel/thread.cpp')
-rw-r--r--src/core/hle/kernel/thread.cpp46
1 files changed, 19 insertions, 27 deletions
diff --git a/src/core/hle/kernel/thread.cpp b/src/core/hle/kernel/thread.cpp
index 957cbdfee..b962da8f0 100644
--- a/src/core/hle/kernel/thread.cpp
+++ b/src/core/hle/kernel/thread.cpp
@@ -157,7 +157,7 @@ static void PriorityBoostStarvedThreads() {
157 157
158 u64 delta = current_ticks - thread->last_running_ticks; 158 u64 delta = current_ticks - thread->last_running_ticks;
159 159
160 if (thread->status == THREADSTATUS_READY && delta > boost_timeout && !thread->idle) { 160 if (thread->status == THREADSTATUS_READY && delta > boost_timeout) {
161 const s32 priority = std::max(ready_queue.get_first()->current_priority - 1, 0); 161 const s32 priority = std::max(ready_queue.get_first()->current_priority - 1, 0);
162 thread->BoostPriority(priority); 162 thread->BoostPriority(priority);
163 } 163 }
@@ -169,8 +169,6 @@ static void PriorityBoostStarvedThreads() {
169 * @param new_thread The thread to switch to 169 * @param new_thread The thread to switch to
170 */ 170 */
171static void SwitchContext(Thread* new_thread) { 171static void SwitchContext(Thread* new_thread) {
172 DEBUG_ASSERT_MSG(new_thread->status == THREADSTATUS_READY, "Thread must be ready to become running.");
173
174 Thread* previous_thread = GetCurrentThread(); 172 Thread* previous_thread = GetCurrentThread();
175 173
176 // Save context for previous thread 174 // Save context for previous thread
@@ -188,6 +186,8 @@ static void SwitchContext(Thread* new_thread) {
188 186
189 // Load context of new thread 187 // Load context of new thread
190 if (new_thread) { 188 if (new_thread) {
189 DEBUG_ASSERT_MSG(new_thread->status == THREADSTATUS_READY, "Thread must be ready to become running.");
190
191 current_thread = new_thread; 191 current_thread = new_thread;
192 192
193 ready_queue.remove(new_thread->current_priority, new_thread); 193 ready_queue.remove(new_thread->current_priority, new_thread);
@@ -215,6 +215,10 @@ static Thread* PopNextReadyThread() {
215 // We have to do better than the current thread. 215 // We have to do better than the current thread.
216 // This call returns null when that's not possible. 216 // This call returns null when that's not possible.
217 next = ready_queue.pop_first_better(thread->current_priority); 217 next = ready_queue.pop_first_better(thread->current_priority);
218 if (!next) {
219 // Otherwise just keep going with the current thread
220 next = thread;
221 }
218 } else { 222 } else {
219 next = ready_queue.pop_first(); 223 next = ready_queue.pop_first();
220 } 224 }
@@ -448,16 +452,6 @@ void Thread::BoostPriority(s32 priority) {
448 current_priority = priority; 452 current_priority = priority;
449} 453}
450 454
451SharedPtr<Thread> SetupIdleThread() {
452 // We need to pass a few valid values to get around parameter checking in Thread::Create.
453 // TODO(yuriks): Figure out a way to avoid passing the bogus VAddr parameter
454 auto thread = Thread::Create("idle", Memory::TLS_AREA_VADDR, THREADPRIO_LOWEST, 0,
455 THREADPROCESSORID_0, 0).MoveFrom();
456
457 thread->idle = true;
458 return thread;
459}
460
461SharedPtr<Thread> SetupMainThread(u32 entry_point, s32 priority) { 455SharedPtr<Thread> SetupMainThread(u32 entry_point, s32 priority) {
462 DEBUG_ASSERT(!GetCurrentThread()); 456 DEBUG_ASSERT(!GetCurrentThread());
463 457
@@ -474,24 +468,25 @@ SharedPtr<Thread> SetupMainThread(u32 entry_point, s32 priority) {
474} 468}
475 469
476void Reschedule() { 470void Reschedule() {
477 Thread* prev = GetCurrentThread();
478
479 PriorityBoostStarvedThreads(); 471 PriorityBoostStarvedThreads();
480 472
473 Thread* cur = GetCurrentThread();
481 Thread* next = PopNextReadyThread(); 474 Thread* next = PopNextReadyThread();
482 HLE::g_reschedule = false; 475 HLE::g_reschedule = false;
483 476
484 if (next != nullptr) { 477 // Don't bother switching to the same thread
485 LOG_TRACE(Kernel, "context switch %u -> %u", prev->GetObjectId(), next->GetObjectId()); 478 if (next == cur)
486 SwitchContext(next); 479 return;
487 } else {
488 LOG_TRACE(Kernel, "cannot context switch from %u, no higher priority thread!", prev->GetObjectId());
489 480
490 for (auto& thread : thread_list) { 481 if (cur && next) {
491 LOG_TRACE(Kernel, "\tid=%u prio=0x%02X, status=0x%08X", thread->GetObjectId(), 482 LOG_TRACE(Kernel, "context switch %u -> %u", cur->GetObjectId(), next->GetObjectId());
492 thread->current_priority, thread->status); 483 } else if (cur) {
493 } 484 LOG_TRACE(Kernel, "context switch %u -> idle", cur->GetObjectId());
485 } else {
486 LOG_TRACE(Kernel, "context switch idle -> %u", next->GetObjectId());
494 } 487 }
488
489 SwitchContext(next);
495} 490}
496 491
497void Thread::SetWaitSynchronizationResult(ResultCode result) { 492void Thread::SetWaitSynchronizationResult(ResultCode result) {
@@ -516,9 +511,6 @@ void ThreadingInit() {
516 511
517 thread_list.clear(); 512 thread_list.clear();
518 ready_queue.clear(); 513 ready_queue.clear();
519
520 // Setup the idle thread
521 SetupIdleThread();
522} 514}
523 515
524void ThreadingShutdown() { 516void ThreadingShutdown() {