summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar Subv2017-01-01 11:57:02 -0500
committerGravatar Subv2017-01-04 15:58:44 -0500
commit38a90882a4230bb797ae3f6857e986d70f3bd265 (patch)
tree3b2e841905a7cbeaceaebe297a128d75892d79f2 /src
parentTry a different encrypted bintray api key for travis. Change appveyor to uplo... (diff)
downloadyuzu-38a90882a4230bb797ae3f6857e986d70f3bd265.tar.gz
yuzu-38a90882a4230bb797ae3f6857e986d70f3bd265.tar.xz
yuzu-38a90882a4230bb797ae3f6857e986d70f3bd265.zip
Kernel/Synch: Do not attempt a reschedule on every syscall.
Not all syscalls should cause reschedules, this commit attempts to remedy that, however, it still does not cover all cases.
Diffstat (limited to 'src')
-rw-r--r--src/core/hle/kernel/mutex.cpp1
-rw-r--r--src/core/hle/svc.cpp19
2 files changed, 18 insertions, 2 deletions
diff --git a/src/core/hle/kernel/mutex.cpp b/src/core/hle/kernel/mutex.cpp
index 736944bae..8d92a9b8e 100644
--- a/src/core/hle/kernel/mutex.cpp
+++ b/src/core/hle/kernel/mutex.cpp
@@ -84,6 +84,7 @@ void Mutex::Release() {
84 if (lock_count == 0) { 84 if (lock_count == 0) {
85 holding_thread->held_mutexes.erase(this); 85 holding_thread->held_mutexes.erase(this);
86 ResumeWaitingThread(this); 86 ResumeWaitingThread(this);
87 Core::System::GetInstance().PrepareReschedule();
87 } 88 }
88 } 89 }
89} 90}
diff --git a/src/core/hle/svc.cpp b/src/core/hle/svc.cpp
index 2ca270de3..5b538be22 100644
--- a/src/core/hle/svc.cpp
+++ b/src/core/hle/svc.cpp
@@ -248,6 +248,8 @@ static ResultCode SendSyncRequest(Kernel::Handle handle) {
248 248
249 LOG_TRACE(Kernel_SVC, "called handle=0x%08X(%s)", handle, session->GetName().c_str()); 249 LOG_TRACE(Kernel_SVC, "called handle=0x%08X(%s)", handle, session->GetName().c_str());
250 250
251 Core::System::GetInstance().PrepareReschedule();
252
251 // TODO(Subv): svcSendSyncRequest should put the caller thread to sleep while the server 253 // TODO(Subv): svcSendSyncRequest should put the caller thread to sleep while the server
252 // responds and cause a reschedule. 254 // responds and cause a reschedule.
253 return session->SendSyncRequest(); 255 return session->SendSyncRequest();
@@ -284,6 +286,8 @@ static ResultCode WaitSynchronization1(Kernel::Handle handle, s64 nano_seconds)
284 // Create an event to wake the thread up after the specified nanosecond delay has passed 286 // Create an event to wake the thread up after the specified nanosecond delay has passed
285 thread->WakeAfterDelay(nano_seconds); 287 thread->WakeAfterDelay(nano_seconds);
286 288
289 Core::System::GetInstance().PrepareReschedule();
290
287 // Note: The output of this SVC will be set to RESULT_SUCCESS if the thread 291 // Note: The output of this SVC will be set to RESULT_SUCCESS if the thread
288 // resumes due to a signal in its wait objects. 292 // resumes due to a signal in its wait objects.
289 // Otherwise we retain the default value of timeout. 293 // Otherwise we retain the default value of timeout.
@@ -366,6 +370,8 @@ static ResultCode WaitSynchronizationN(s32* out, Kernel::Handle* handles, s32 ha
366 // Create an event to wake the thread up after the specified nanosecond delay has passed 370 // Create an event to wake the thread up after the specified nanosecond delay has passed
367 thread->WakeAfterDelay(nano_seconds); 371 thread->WakeAfterDelay(nano_seconds);
368 372
373 Core::System::GetInstance().PrepareReschedule();
374
369 // This value gets set to -1 by default in this case, it is not modified after this. 375 // This value gets set to -1 by default in this case, it is not modified after this.
370 *out = -1; 376 *out = -1;
371 // Note: The output of this SVC will be set to RESULT_SUCCESS if the thread resumes due to 377 // Note: The output of this SVC will be set to RESULT_SUCCESS if the thread resumes due to
@@ -414,6 +420,8 @@ static ResultCode WaitSynchronizationN(s32* out, Kernel::Handle* handles, s32 ha
414 // Create an event to wake the thread up after the specified nanosecond delay has passed 420 // Create an event to wake the thread up after the specified nanosecond delay has passed
415 thread->WakeAfterDelay(nano_seconds); 421 thread->WakeAfterDelay(nano_seconds);
416 422
423 Core::System::GetInstance().PrepareReschedule();
424
417 // Note: The output of this SVC will be set to RESULT_SUCCESS if the thread resumes due to a 425 // Note: The output of this SVC will be set to RESULT_SUCCESS if the thread resumes due to a
418 // signal in one of its wait objects. 426 // signal in one of its wait objects.
419 // Otherwise we retain the default value of timeout, and -1 in the out parameter 427 // Otherwise we retain the default value of timeout, and -1 in the out parameter
@@ -448,6 +456,9 @@ static ResultCode ArbitrateAddress(Kernel::Handle handle, u32 address, u32 type,
448 auto res = arbiter->ArbitrateAddress(static_cast<Kernel::ArbitrationType>(type), address, value, 456 auto res = arbiter->ArbitrateAddress(static_cast<Kernel::ArbitrationType>(type), address, value,
449 nanoseconds); 457 nanoseconds);
450 458
459 // TODO(Subv): Identify in which specific cases this call should cause a reschedule.
460 Core::System::GetInstance().PrepareReschedule();
461
451 return res; 462 return res;
452} 463}
453 464
@@ -574,6 +585,8 @@ static ResultCode CreateThread(Kernel::Handle* out_handle, s32 priority, u32 ent
574 585
575 CASCADE_RESULT(*out_handle, Kernel::g_handle_table.Create(std::move(thread))); 586 CASCADE_RESULT(*out_handle, Kernel::g_handle_table.Create(std::move(thread)));
576 587
588 Core::System::GetInstance().PrepareReschedule();
589
577 LOG_TRACE(Kernel_SVC, "called entrypoint=0x%08X (%s), arg=0x%08X, stacktop=0x%08X, " 590 LOG_TRACE(Kernel_SVC, "called entrypoint=0x%08X (%s), arg=0x%08X, stacktop=0x%08X, "
578 "threadpriority=0x%08X, processorid=0x%08X : created handle=0x%08X", 591 "threadpriority=0x%08X, processorid=0x%08X : created handle=0x%08X",
579 entry_point, name.c_str(), arg, stack_top, priority, processor_id, *out_handle); 592 entry_point, name.c_str(), arg, stack_top, priority, processor_id, *out_handle);
@@ -586,6 +599,7 @@ static void ExitThread() {
586 LOG_TRACE(Kernel_SVC, "called, pc=0x%08X", Core::CPU().GetPC()); 599 LOG_TRACE(Kernel_SVC, "called, pc=0x%08X", Core::CPU().GetPC());
587 600
588 Kernel::ExitCurrentThread(); 601 Kernel::ExitCurrentThread();
602 Core::System::GetInstance().PrepareReschedule();
589} 603}
590 604
591/// Gets the priority for the specified thread 605/// Gets the priority for the specified thread
@@ -605,6 +619,7 @@ static ResultCode SetThreadPriority(Kernel::Handle handle, s32 priority) {
605 return ERR_INVALID_HANDLE; 619 return ERR_INVALID_HANDLE;
606 620
607 thread->SetPriority(priority); 621 thread->SetPriority(priority);
622 Core::System::GetInstance().PrepareReschedule();
608 return RESULT_SUCCESS; 623 return RESULT_SUCCESS;
609} 624}
610 625
@@ -849,6 +864,8 @@ static void SleepThread(s64 nanoseconds) {
849 864
850 // Create an event to wake the thread up after the specified nanosecond delay has passed 865 // Create an event to wake the thread up after the specified nanosecond delay has passed
851 Kernel::GetCurrentThread()->WakeAfterDelay(nanoseconds); 866 Kernel::GetCurrentThread()->WakeAfterDelay(nanoseconds);
867
868 Core::System::GetInstance().PrepareReschedule();
852} 869}
853 870
854/// This returns the total CPU ticks elapsed since the CPU was powered-on 871/// This returns the total CPU ticks elapsed since the CPU was powered-on
@@ -1184,8 +1201,6 @@ void CallSVC(u32 immediate) {
1184 if (info) { 1201 if (info) {
1185 if (info->func) { 1202 if (info->func) {
1186 info->func(); 1203 info->func();
1187 // TODO(Subv): Not all service functions should cause a reschedule in all cases.
1188 Core::System::GetInstance().PrepareReschedule();
1189 } else { 1204 } else {
1190 LOG_ERROR(Kernel_SVC, "unimplemented SVC function %s(..)", info->name); 1205 LOG_ERROR(Kernel_SVC, "unimplemented SVC function %s(..)", info->name);
1191 } 1206 }