summaryrefslogtreecommitdiff
path: root/src/core/hle/kernel/svc.cpp
diff options
context:
space:
mode:
authorGravatar Fernando Sahmkow2019-09-10 10:23:43 -0400
committerGravatar FernandoS272019-10-15 11:55:13 -0400
commit103f3a2fe51a09caf3f478226b6957b23c6eff79 (patch)
tree5304773e043ed3db6a55e4666fc25143560396af /src/core/hle/kernel/svc.cpp
parentKernel: Style and Corrections (diff)
downloadyuzu-103f3a2fe51a09caf3f478226b6957b23c6eff79.tar.gz
yuzu-103f3a2fe51a09caf3f478226b6957b23c6eff79.tar.xz
yuzu-103f3a2fe51a09caf3f478226b6957b23c6eff79.zip
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 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) {
1556 1556
1557 auto& scheduler = system.CurrentScheduler(); 1557 auto& scheduler = system.CurrentScheduler();
1558 auto* const current_thread = scheduler.GetCurrentThread(); 1558 auto* const current_thread = scheduler.GetCurrentThread();
1559 bool redundant = false;
1559 1560
1560 if (nanoseconds <= 0) { 1561 if (nanoseconds <= 0) {
1561 switch (static_cast<SleepType>(nanoseconds)) { 1562 switch (static_cast<SleepType>(nanoseconds)) {
1562 case SleepType::YieldWithoutLoadBalancing: 1563 case SleepType::YieldWithoutLoadBalancing:
1563 current_thread->YieldSimple(); 1564 redundant = current_thread->YieldSimple();
1564 break; 1565 break;
1565 case SleepType::YieldWithLoadBalancing: 1566 case SleepType::YieldWithLoadBalancing:
1566 current_thread->YieldAndBalanceLoad(); 1567 redundant = current_thread->YieldAndBalanceLoad();
1567 break; 1568 break;
1568 case SleepType::YieldAndWaitForLoadBalancing: 1569 case SleepType::YieldAndWaitForLoadBalancing:
1569 current_thread->YieldAndWaitForLoadBalancing(); 1570 redundant = current_thread->YieldAndWaitForLoadBalancing();
1570 break; 1571 break;
1571 default: 1572 default:
1572 UNREACHABLE_MSG("Unimplemented sleep yield type '{:016X}'!", nanoseconds); 1573 UNREACHABLE_MSG("Unimplemented sleep yield type '{:016X}'!", nanoseconds);
@@ -1575,7 +1576,11 @@ static void SleepThread(Core::System& system, s64 nanoseconds) {
1575 current_thread->Sleep(nanoseconds); 1576 current_thread->Sleep(nanoseconds);
1576 } 1577 }
1577 1578
1578 system.PrepareReschedule(current_thread->GetProcessorID()); 1579 if (redundant) {
1580 system.CoreTiming().Idle();
1581 } else {
1582 system.PrepareReschedule(current_thread->GetProcessorID());
1583 }
1579} 1584}
1580 1585
1581/// Wait process wide key atomic 1586/// Wait process wide key atomic