|
|
|
@ -1284,10 +1284,14 @@ static ResultCode StartThread(Handle thread_handle) {
|
|
|
|
|
|
|
|
|
|
/// Called when a thread exits
|
|
|
|
|
static void ExitThread() {
|
|
|
|
|
LOG_TRACE(Kernel_SVC, "called, pc=0x{:08X}", Core::CurrentArmInterface().GetPC());
|
|
|
|
|
auto& system = Core::System::GetInstance();
|
|
|
|
|
|
|
|
|
|
ExitCurrentThread();
|
|
|
|
|
Core::System::GetInstance().PrepareReschedule();
|
|
|
|
|
LOG_TRACE(Kernel_SVC, "called, pc=0x{:08X}", system.CurrentArmInterface().GetPC());
|
|
|
|
|
|
|
|
|
|
auto* const current_thread = system.CurrentScheduler().GetCurrentThread();
|
|
|
|
|
current_thread->Stop();
|
|
|
|
|
system.CurrentScheduler().RemoveThread(current_thread);
|
|
|
|
|
system.PrepareReschedule();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Sleep the current thread
|
|
|
|
@ -1300,32 +1304,32 @@ static void SleepThread(s64 nanoseconds) {
|
|
|
|
|
YieldAndWaitForLoadBalancing = -2,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
auto& system = Core::System::GetInstance();
|
|
|
|
|
auto& scheduler = system.CurrentScheduler();
|
|
|
|
|
auto* const current_thread = scheduler.GetCurrentThread();
|
|
|
|
|
|
|
|
|
|
if (nanoseconds <= 0) {
|
|
|
|
|
auto& scheduler{Core::System::GetInstance().CurrentScheduler()};
|
|
|
|
|
switch (static_cast<SleepType>(nanoseconds)) {
|
|
|
|
|
case SleepType::YieldWithoutLoadBalancing:
|
|
|
|
|
scheduler.YieldWithoutLoadBalancing(GetCurrentThread());
|
|
|
|
|
scheduler.YieldWithoutLoadBalancing(current_thread);
|
|
|
|
|
break;
|
|
|
|
|
case SleepType::YieldWithLoadBalancing:
|
|
|
|
|
scheduler.YieldWithLoadBalancing(GetCurrentThread());
|
|
|
|
|
scheduler.YieldWithLoadBalancing(current_thread);
|
|
|
|
|
break;
|
|
|
|
|
case SleepType::YieldAndWaitForLoadBalancing:
|
|
|
|
|
scheduler.YieldAndWaitForLoadBalancing(GetCurrentThread());
|
|
|
|
|
scheduler.YieldAndWaitForLoadBalancing(current_thread);
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
UNREACHABLE_MSG("Unimplemented sleep yield type '{:016X}'!", nanoseconds);
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
// Sleep current thread and check for next thread to schedule
|
|
|
|
|
WaitCurrentThread_Sleep();
|
|
|
|
|
|
|
|
|
|
// Create an event to wake the thread up after the specified nanosecond delay has passed
|
|
|
|
|
GetCurrentThread()->WakeAfterDelay(nanoseconds);
|
|
|
|
|
current_thread->Sleep(nanoseconds);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Reschedule all CPU cores
|
|
|
|
|
for (std::size_t i = 0; i < Core::NUM_CPU_CORES; ++i)
|
|
|
|
|
Core::System::GetInstance().CpuCore(i).PrepareReschedule();
|
|
|
|
|
for (std::size_t i = 0; i < Core::NUM_CPU_CORES; ++i) {
|
|
|
|
|
system.CpuCore(i).PrepareReschedule();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Wait process wide key atomic
|
|
|
|
|