From 409dcf0e0aecfdb676fd3b64223a25e47c1b1c1a Mon Sep 17 00:00:00 2001 From: Zach Hilman Date: Sun, 18 Nov 2018 23:44:19 -0500 Subject: svc: Implement yield types 0 and -1 --- src/core/hle/kernel/thread.cpp | 60 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) (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 4ffb76818..ddc4da1c0 100644 --- a/src/core/hle/kernel/thread.cpp +++ b/src/core/hle/kernel/thread.cpp @@ -388,6 +388,66 @@ bool Thread::InvokeWakeupCallback(ThreadWakeupReason reason, SharedPtr t return wakeup_callback(reason, std::move(thread), std::move(object), index); } +void Thread::YieldNormal() { + // Avoid yielding if the thread isn't even running. + if (status != ThreadStatus::Running) { + return; + } + + if (nominal_priority < THREADPRIO_COUNT) { + scheduler->RescheduleThread(this, nominal_priority); + scheduler->Reschedule(); + } +} + +void Thread::YieldWithLoadBalancing() { + auto priority = nominal_priority; + auto core = processor_id; + + // Avoid yielding if the thread isn't even running. + if (status != ThreadStatus::Running) { + Core::System::GetInstance().CpuCore(processor_id).PrepareReschedule(); + return; + } + + SharedPtr next; + const auto& threads = scheduler->GetThreadList(); + + if (priority < THREADPRIO_COUNT) { + // Reschedule thread to end of queue. + scheduler->RescheduleThread(this, priority); + + const auto iter = std::find_if(threads.begin(), threads.end(), + [&priority](const SharedPtr& thread) { + return thread->GetNominalPriority() == priority; + }); + + if (iter != threads.end()) + next = iter->get(); + } + + Thread* suggested_thread = nullptr; + + for (int i = 0; i < 4; ++i) { + if (i == core) + continue; + + const auto res = + Core::System::GetInstance().CpuCore(i).Scheduler().GetNextSuggestedThread(core); + if (res != nullptr) { + suggested_thread = res; + break; + } + } + + if (suggested_thread != nullptr) + suggested_thread->ChangeCore(core, suggested_thread->GetAffinityMask()); +} + +void Thread::YieldAndWaitForLoadBalancing() { + UNIMPLEMENTED_MSG("Wait for load balancing thread yield type is not implemented!"); +} + //////////////////////////////////////////////////////////////////////////////////////////////////// /** -- cgit v1.2.3