summaryrefslogtreecommitdiff
path: root/src/core/hle/kernel/scheduler.cpp
diff options
context:
space:
mode:
authorGravatar bunnei2018-12-15 00:28:12 -0500
committerGravatar GitHub2018-12-15 00:28:12 -0500
commit2f2fc47af23708f4a79c1e3b554aafd84a32f7db (patch)
tree02114974dac4e65b2a1a011c7cad68b32a6a6a47 /src/core/hle/kernel/scheduler.cpp
parentMerge pull request #1902 from lioncash/audio (diff)
parentsvc: Avoid incorrect fast yield condition (diff)
downloadyuzu-2f2fc47af23708f4a79c1e3b554aafd84a32f7db.tar.gz
yuzu-2f2fc47af23708f4a79c1e3b554aafd84a32f7db.tar.xz
yuzu-2f2fc47af23708f4a79c1e3b554aafd84a32f7db.zip
Merge pull request #1732 from DarkLordZach/yield-types
svc: Implement yield types 0 and -1
Diffstat (limited to 'src/core/hle/kernel/scheduler.cpp')
-rw-r--r--src/core/hle/kernel/scheduler.cpp66
1 files changed, 66 insertions, 0 deletions
diff --git a/src/core/hle/kernel/scheduler.cpp b/src/core/hle/kernel/scheduler.cpp
index 5a5f4cef1..df4d6cf0a 100644
--- a/src/core/hle/kernel/scheduler.cpp
+++ b/src/core/hle/kernel/scheduler.cpp
@@ -9,6 +9,7 @@
9#include "common/logging/log.h" 9#include "common/logging/log.h"
10#include "core/arm/arm_interface.h" 10#include "core/arm/arm_interface.h"
11#include "core/core.h" 11#include "core/core.h"
12#include "core/core_cpu.h"
12#include "core/core_timing.h" 13#include "core/core_timing.h"
13#include "core/hle/kernel/kernel.h" 14#include "core/hle/kernel/kernel.h"
14#include "core/hle/kernel/process.h" 15#include "core/hle/kernel/process.h"
@@ -179,4 +180,69 @@ void Scheduler::SetThreadPriority(Thread* thread, u32 priority) {
179 ready_queue.prepare(priority); 180 ready_queue.prepare(priority);
180} 181}
181 182
183Thread* Scheduler::GetNextSuggestedThread(u32 core, u32 maximum_priority) const {
184 std::lock_guard<std::mutex> lock(scheduler_mutex);
185
186 const u32 mask = 1U << core;
187 return ready_queue.get_first_filter([mask, maximum_priority](Thread const* thread) {
188 return (thread->GetAffinityMask() & mask) != 0 && thread->GetPriority() < maximum_priority;
189 });
190}
191
192void Scheduler::YieldWithoutLoadBalancing(Thread* thread) {
193 ASSERT(thread != nullptr);
194 // Avoid yielding if the thread isn't even running.
195 ASSERT(thread->GetStatus() == ThreadStatus::Running);
196
197 // Sanity check that the priority is valid
198 ASSERT(thread->GetPriority() < THREADPRIO_COUNT);
199
200 // Yield this thread -- sleep for zero time and force reschedule to different thread
201 WaitCurrentThread_Sleep();
202 GetCurrentThread()->WakeAfterDelay(0);
203}
204
205void Scheduler::YieldWithLoadBalancing(Thread* thread) {
206 ASSERT(thread != nullptr);
207 const auto priority = thread->GetPriority();
208 const auto core = static_cast<u32>(thread->GetProcessorID());
209
210 // Avoid yielding if the thread isn't even running.
211 ASSERT(thread->GetStatus() == ThreadStatus::Running);
212
213 // Sanity check that the priority is valid
214 ASSERT(priority < THREADPRIO_COUNT);
215
216 // Sleep for zero time to be able to force reschedule to different thread
217 WaitCurrentThread_Sleep();
218 GetCurrentThread()->WakeAfterDelay(0);
219
220 Thread* suggested_thread = nullptr;
221
222 // Search through all of the cpu cores (except this one) for a suggested thread.
223 // Take the first non-nullptr one
224 for (unsigned cur_core = 0; cur_core < Core::NUM_CPU_CORES; ++cur_core) {
225 const auto res =
226 Core::System::GetInstance().CpuCore(cur_core).Scheduler().GetNextSuggestedThread(
227 core, priority);
228
229 // If scheduler provides a suggested thread
230 if (res != nullptr) {
231 // And its better than the current suggested thread (or is the first valid one)
232 if (suggested_thread == nullptr ||
233 suggested_thread->GetPriority() > res->GetPriority()) {
234 suggested_thread = res;
235 }
236 }
237 }
238
239 // If a suggested thread was found, queue that for this core
240 if (suggested_thread != nullptr)
241 suggested_thread->ChangeCore(core, suggested_thread->GetAffinityMask());
242}
243
244void Scheduler::YieldAndWaitForLoadBalancing(Thread* thread) {
245 UNIMPLEMENTED_MSG("Wait for load balancing thread yield type is not implemented!");
246}
247
182} // namespace Kernel 248} // namespace Kernel