From 103f3a2fe51a09caf3f478226b6957b23c6eff79 Mon Sep 17 00:00:00 2001 From: Fernando Sahmkow Date: Tue, 10 Sep 2019 10:23:43 -0400 Subject: Scheduler: Add protections for Yield bombing In case of redundant yields, the scheduler will now idle the core for it's timeslice, in order to avoid continuously yielding the same thing over and over. --- src/core/hle/kernel/svc.cpp | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) (limited to 'src/core/hle/kernel/svc.cpp') diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp index d520ed033..bd67fc96d 100644 --- a/src/core/hle/kernel/svc.cpp +++ b/src/core/hle/kernel/svc.cpp @@ -1556,17 +1556,18 @@ static void SleepThread(Core::System& system, s64 nanoseconds) { auto& scheduler = system.CurrentScheduler(); auto* const current_thread = scheduler.GetCurrentThread(); + bool redundant = false; if (nanoseconds <= 0) { switch (static_cast(nanoseconds)) { case SleepType::YieldWithoutLoadBalancing: - current_thread->YieldSimple(); + redundant = current_thread->YieldSimple(); break; case SleepType::YieldWithLoadBalancing: - current_thread->YieldAndBalanceLoad(); + redundant = current_thread->YieldAndBalanceLoad(); break; case SleepType::YieldAndWaitForLoadBalancing: - current_thread->YieldAndWaitForLoadBalancing(); + redundant = current_thread->YieldAndWaitForLoadBalancing(); break; default: UNREACHABLE_MSG("Unimplemented sleep yield type '{:016X}'!", nanoseconds); @@ -1575,7 +1576,11 @@ static void SleepThread(Core::System& system, s64 nanoseconds) { current_thread->Sleep(nanoseconds); } - system.PrepareReschedule(current_thread->GetProcessorID()); + if (redundant) { + system.CoreTiming().Idle(); + } else { + system.PrepareReschedule(current_thread->GetProcessorID()); + } } /// Wait process wide key atomic -- cgit v1.2.3