diff options
| author | 2018-11-22 00:33:53 -0500 | |
|---|---|---|
| committer | 2018-11-22 00:33:53 -0500 | |
| commit | 820d81b9a5392951c18daa5a47d6c0ffd28baa9b (patch) | |
| tree | dab20f1ff49ab76cdcd511e189799f4d6e40677e /src/core/hle/kernel/scheduler.cpp | |
| parent | svc: Implement yield types 0 and -1 (diff) | |
| download | yuzu-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.cpp | 61 |
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 | ||
| 172 | void Scheduler::RescheduleThread(Thread* thread, u32 priority) { | 173 | void 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 | ||
| 192 | Thread* Scheduler::GetNextSuggestedThread(u32 core) { | 193 | Thread* 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 | |||
| 201 | void 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 | |||
| 214 | void 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 | |||
| 249 | void 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 |