Kernel: Don't attempt to yield execution in SleepThread(0) if there are no available threads to run.

With this we avoid an useless temporary deschedule of the current thread.
master
Subv 2017-01-05 14:14:22 +07:00
parent f20d872643
commit fc2266130b
3 changed files with 14 additions and 0 deletions

@ -556,6 +556,10 @@ SharedPtr<Thread> SetupMainThread(u32 entry_point, s32 priority) {
return thread; return thread;
} }
bool HaveReadyThreads() {
return ready_queue.get_first() != nullptr;
}
void Reschedule() { void Reschedule() {
PriorityBoostStarvedThreads(); PriorityBoostStarvedThreads();

@ -218,6 +218,11 @@ private:
*/ */
SharedPtr<Thread> SetupMainThread(u32 entry_point, s32 priority); SharedPtr<Thread> SetupMainThread(u32 entry_point, s32 priority);
/**
* Returns whether there are any threads that are ready to run.
*/
bool HaveReadyThreads();
/** /**
* Reschedules to the next available thread (call after current thread is suspended) * Reschedules to the next available thread (call after current thread is suspended)
*/ */

@ -849,6 +849,11 @@ static ResultCode CancelTimer(Kernel::Handle handle) {
static void SleepThread(s64 nanoseconds) { static void SleepThread(s64 nanoseconds) {
LOG_TRACE(Kernel_SVC, "called nanoseconds=%lld", nanoseconds); LOG_TRACE(Kernel_SVC, "called nanoseconds=%lld", nanoseconds);
// Don't attempt to yield execution if there are no available threads to run,
// this way we avoid a useless reschedule to the idle thread.
if (nanoseconds == 0 && !Kernel::HaveReadyThreads())
return;
// Sleep current thread and check for next thread to schedule // Sleep current thread and check for next thread to schedule
Kernel::WaitCurrentThread_Sleep(); Kernel::WaitCurrentThread_Sleep();