summaryrefslogtreecommitdiff
path: root/src/core/hle/kernel/svc.cpp
diff options
context:
space:
mode:
authorGravatar bunnei2018-12-15 00:28:12 -0500
committerGravatar GitHub2018-12-15 00:28:12 -0500
commit2f2fc47af23708f4a79c1e3b554aafd84a32f7db (patch)
tree02114974dac4e65b2a1a011c7cad68b32a6a6a47 /src/core/hle/kernel/svc.cpp
parentMerge pull request #1902 from lioncash/audio (diff)
parentsvc: Avoid incorrect fast yield condition (diff)
downloadyuzu-2f2fc47af23708f4a79c1e3b554aafd84a32f7db.tar.gz
yuzu-2f2fc47af23708f4a79c1e3b554aafd84a32f7db.tar.xz
yuzu-2f2fc47af23708f4a79c1e3b554aafd84a32f7db.zip
Merge pull request #1732 from DarkLordZach/yield-types
svc: Implement yield types 0 and -1
Diffstat (limited to 'src/core/hle/kernel/svc.cpp')
-rw-r--r--src/core/hle/kernel/svc.cpp38
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() {
1208static void SleepThread(s64 nanoseconds) { 1208static void SleepThread(s64 nanoseconds) {
1209 LOG_TRACE(Kernel_SVC, "called nanoseconds={}", nanoseconds); 1209 LOG_TRACE(Kernel_SVC, "called nanoseconds={}", nanoseconds);
1210 1210
1211 // Don't attempt to yield execution if there are no available threads to run, 1211 enum class SleepType : s64 {
1212 // this way we avoid a useless reschedule to the idle thread. 1212 YieldWithoutLoadBalancing = 0,
1213 if (nanoseconds == 0 && !Core::System::GetInstance().CurrentScheduler().HaveReadyThreads()) 1213 YieldWithLoadBalancing = -1,
1214 return; 1214 YieldAndWaitForLoadBalancing = -2,
1215 };
1215 1216
1216 // Sleep current thread and check for next thread to schedule 1217 if (nanoseconds <= 0) {
1217 WaitCurrentThread_Sleep(); 1218 auto& scheduler{Core::System::GetInstance().CurrentScheduler()};
1219 switch (static_cast<SleepType>(nanoseconds)) {
1220 case SleepType::YieldWithoutLoadBalancing:
1221 scheduler.YieldWithoutLoadBalancing(GetCurrentThread());
1222 break;
1223 case SleepType::YieldWithLoadBalancing:
1224 scheduler.YieldWithLoadBalancing(GetCurrentThread());
1225 break;
1226 case SleepType::YieldAndWaitForLoadBalancing:
1227 scheduler.YieldAndWaitForLoadBalancing(GetCurrentThread());
1228 break;
1229 default:
1230 UNREACHABLE_MSG("Unimplemented sleep yield type '{:016X}'!", nanoseconds);
1231 }
1232 } else {
1233 // Sleep current thread and check for next thread to schedule
1234 WaitCurrentThread_Sleep();
1218 1235
1219 // Create an event to wake the thread up after the specified nanosecond delay has passed 1236 // Create an event to wake the thread up after the specified nanosecond delay has passed
1220 GetCurrentThread()->WakeAfterDelay(nanoseconds); 1237 GetCurrentThread()->WakeAfterDelay(nanoseconds);
1238 }
1221 1239
1222 Core::System::GetInstance().PrepareReschedule(); 1240 // Reschedule all CPU cores
1241 for (std::size_t i = 0; i < Core::NUM_CPU_CORES; ++i)
1242 Core::System::GetInstance().CpuCore(i).PrepareReschedule();
1223} 1243}
1224 1244
1225/// Wait process wide key atomic 1245/// Wait process wide key atomic