summaryrefslogtreecommitdiff
path: root/src/core/hle/kernel/scheduler.cpp
diff options
context:
space:
mode:
authorGravatar Zach Hilman2018-11-22 00:33:53 -0500
committerGravatar Zach Hilman2018-11-22 00:33:53 -0500
commit820d81b9a5392951c18daa5a47d6c0ffd28baa9b (patch)
treedab20f1ff49ab76cdcd511e189799f4d6e40677e /src/core/hle/kernel/scheduler.cpp
parentsvc: Implement yield types 0 and -1 (diff)
downloadyuzu-820d81b9a5392951c18daa5a47d6c0ffd28baa9b.tar.gz
yuzu-820d81b9a5392951c18daa5a47d6c0ffd28baa9b.tar.xz
yuzu-820d81b9a5392951c18daa5a47d6c0ffd28baa9b.zip
scheduler: Add explanations for YieldWith and WithoutLoadBalancing
Diffstat (limited to 'src/core/hle/kernel/scheduler.cpp')
-rw-r--r--src/core/hle/kernel/scheduler.cpp61
1 files changed, 57 insertions, 4 deletions
diff --git a/src/core/hle/kernel/scheduler.cpp b/src/core/hle/kernel/scheduler.cpp
index fb5e14950..624c841ad 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"
@@ -169,7 +170,7 @@ void Scheduler::UnscheduleThread(Thread* thread, u32 priority) {
169 ready_queue.remove(priority, thread); 170 ready_queue.remove(priority, thread);
170} 171}
171 172
172void Scheduler::RescheduleThread(Thread* thread, u32 priority) { 173void Scheduler::MoveThreadToBackOfPriorityQueue(Thread* thread, u32 priority) {
173 std::lock_guard<std::mutex> lock(scheduler_mutex); 174 std::lock_guard<std::mutex> lock(scheduler_mutex);
174 175
175 // Thread is not in queue 176 // Thread is not in queue
@@ -189,12 +190,64 @@ void Scheduler::SetThreadPriority(Thread* thread, u32 priority) {
189 ready_queue.prepare(priority); 190 ready_queue.prepare(priority);
190} 191}
191 192
192Thread* Scheduler::GetNextSuggestedThread(u32 core) { 193Thread* Scheduler::GetNextSuggestedThread(u32 core) const {
193 std::lock_guard<std::mutex> lock(scheduler_mutex); 194 std::lock_guard<std::mutex> lock(scheduler_mutex);
194 195
195 const auto mask = 1 << core; 196 const u32 mask = 1U << core;
196 return ready_queue.get_first_filter( 197 return ready_queue.get_first_filter(
197 [&mask](Thread* thread) { return (thread->GetAffinityMask() & mask) != 0; }); 198 [mask](Thread const* thread) { return (thread->GetAffinityMask() & mask) != 0; });
199}
200
201void Scheduler::YieldWithoutLoadBalancing(Thread* thread) {
202 ASSERT(thread != nullptr);
203 // Avoid yielding if the thread isn't even running.
204 ASSERT(thread->GetStatus() == ThreadStatus::Running);
205
206 // Sanity check that the priority is valid
207 ASSERT(thread->GetPriority() < THREADPRIO_COUNT);
208
209 // Yield this thread
210 MoveThreadToBackOfPriorityQueue(thread, thread->GetPriority());
211 Reschedule();
212}
213
214void Scheduler::YieldWithLoadBalancing(Thread* thread) {
215 ASSERT(thread != nullptr);
216 const auto priority = thread->GetPriority();
217 const auto core = static_cast<u32>(thread->GetProcessorID());
218
219 // Avoid yielding if the thread isn't even running.
220 ASSERT(thread->GetStatus() == ThreadStatus::Running);
221
222 // Sanity check that the priority is valid
223 ASSERT(priority < THREADPRIO_COUNT);
224
225 // Reschedule thread to end of queue.
226 MoveThreadToBackOfPriorityQueue(thread, priority);
227
228 Thread* suggested_thread = nullptr;
229
230 // Search through all of the cpu cores (except this one) for a suggested thread.
231 // Take the first non-nullptr one
232 for (unsigned cur_core = 0; cur_core < Core::NUM_CPU_CORES; ++cur_core) {
233 if (cur_core == core)
234 continue;
235
236 const auto res =
237 Core::System::GetInstance().CpuCore(cur_core).Scheduler().GetNextSuggestedThread(core);
238 if (res != nullptr) {
239 suggested_thread = res;
240 break;
241 }
242 }
243
244 // If a suggested thread was found, queue that for this core
245 if (suggested_thread != nullptr)
246 suggested_thread->ChangeCore(core, suggested_thread->GetAffinityMask());
247}
248
249void Scheduler::YieldAndWaitForLoadBalancing(Thread* thread) {
250 UNIMPLEMENTED_MSG("Wait for load balancing thread yield type is not implemented!");
198} 251}
199 252
200} // namespace Kernel 253} // namespace Kernel