aboutsummaryrefslogtreecommitdiff
path: root/src/core/hle/kernel/svc.cpp
diff options
context:
space:
mode:
authorFernando Sahmkow <fsahmkow27@gmail.com>2019-09-10 10:23:43 -0400
committerFernandoS27 <fsahmkow27@gmail.com>2019-10-15 11:55:13 -0400
commitacdce3b4df6305ecc41647b80177b09a72b2e2aa (patch)
tree5304773e043ed3db6a55e4666fc25143560396af /src/core/hle/kernel/svc.cpp
parent5130168171d67075b2d64566d6d41bf17985c272 (diff)
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.
Diffstat (limited to 'src/core/hle/kernel/svc.cpp')
-rw-r--r--src/core/hle/kernel/svc.cpp13
1 files changed, 9 insertions, 4 deletions
diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp
index d520ed0332..bd67fc96d7 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<SleepType>(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