diff options
author | bunnei <bunneidev@gmail.com> | 2018-12-15 06:28:12 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-12-15 06:28:12 +0100 |
commit | 2f2fc47af23708f4a79c1e3b554aafd84a32f7db (patch) | |
tree | 02114974dac4e65b2a1a011c7cad68b32a6a6a47 /src/core/hle/kernel/svc.cpp | |
parent | Merge pull request #1902 from lioncash/audio (diff) | |
parent | svc: Avoid incorrect fast yield condition (diff) | |
download | yuzu-2f2fc47af23708f4a79c1e3b554aafd84a32f7db.tar yuzu-2f2fc47af23708f4a79c1e3b554aafd84a32f7db.tar.gz yuzu-2f2fc47af23708f4a79c1e3b554aafd84a32f7db.tar.bz2 yuzu-2f2fc47af23708f4a79c1e3b554aafd84a32f7db.tar.lz yuzu-2f2fc47af23708f4a79c1e3b554aafd84a32f7db.tar.xz yuzu-2f2fc47af23708f4a79c1e3b554aafd84a32f7db.tar.zst yuzu-2f2fc47af23708f4a79c1e3b554aafd84a32f7db.zip |
Diffstat (limited to 'src/core/hle/kernel/svc.cpp')
-rw-r--r-- | src/core/hle/kernel/svc.cpp | 38 |
1 files changed, 29 insertions, 9 deletions
diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp index 5d36792ca..348a22904 100644 --- a/src/core/hle/kernel/svc.cpp +++ b/src/core/hle/kernel/svc.cpp @@ -1208,18 +1208,38 @@ static void ExitThread() { static void SleepThread(s64 nanoseconds) { LOG_TRACE(Kernel_SVC, "called nanoseconds={}", nanoseconds); - // Don't attempt to yield execution if there are no available threads to run, - // this way we avoid a useless reschedule to the idle thread. - if (nanoseconds == 0 && !Core::System::GetInstance().CurrentScheduler().HaveReadyThreads()) - return; + enum class SleepType : s64 { + YieldWithoutLoadBalancing = 0, + YieldWithLoadBalancing = -1, + YieldAndWaitForLoadBalancing = -2, + }; - // Sleep current thread and check for next thread to schedule - WaitCurrentThread_Sleep(); + if (nanoseconds <= 0) { + auto& scheduler{Core::System::GetInstance().CurrentScheduler()}; + switch (static_cast<SleepType>(nanoseconds)) { + case SleepType::YieldWithoutLoadBalancing: + scheduler.YieldWithoutLoadBalancing(GetCurrentThread()); + break; + case SleepType::YieldWithLoadBalancing: + scheduler.YieldWithLoadBalancing(GetCurrentThread()); + break; + case SleepType::YieldAndWaitForLoadBalancing: + scheduler.YieldAndWaitForLoadBalancing(GetCurrentThread()); + break; + default: + UNREACHABLE_MSG("Unimplemented sleep yield type '{:016X}'!", nanoseconds); + } + } else { + // Sleep current thread and check for next thread to schedule + WaitCurrentThread_Sleep(); - // Create an event to wake the thread up after the specified nanosecond delay has passed - GetCurrentThread()->WakeAfterDelay(nanoseconds); + // Create an event to wake the thread up after the specified nanosecond delay has passed + GetCurrentThread()->WakeAfterDelay(nanoseconds); + } - Core::System::GetInstance().PrepareReschedule(); + // Reschedule all CPU cores + for (std::size_t i = 0; i < Core::NUM_CPU_CORES; ++i) + Core::System::GetInstance().CpuCore(i).PrepareReschedule(); } /// Wait process wide key atomic |