|
|
@ -9,6 +9,7 @@
|
|
|
|
#include "common/logging/log.h"
|
|
|
|
#include "common/logging/log.h"
|
|
|
|
#include "core/arm/arm_interface.h"
|
|
|
|
#include "core/arm/arm_interface.h"
|
|
|
|
#include "core/core.h"
|
|
|
|
#include "core/core.h"
|
|
|
|
|
|
|
|
#include "core/core_timing.h"
|
|
|
|
#include "core/hle/kernel/kernel.h"
|
|
|
|
#include "core/hle/kernel/kernel.h"
|
|
|
|
#include "core/hle/kernel/process.h"
|
|
|
|
#include "core/hle/kernel/process.h"
|
|
|
|
#include "core/hle/kernel/scheduler.h"
|
|
|
|
#include "core/hle/kernel/scheduler.h"
|
|
|
@ -34,6 +35,10 @@ Thread* Scheduler::GetCurrentThread() const {
|
|
|
|
return current_thread.get();
|
|
|
|
return current_thread.get();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
u64 Scheduler::GetLastContextSwitchTicks() const {
|
|
|
|
|
|
|
|
return last_context_switch_time;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
Thread* Scheduler::PopNextReadyThread() {
|
|
|
|
Thread* Scheduler::PopNextReadyThread() {
|
|
|
|
Thread* next = nullptr;
|
|
|
|
Thread* next = nullptr;
|
|
|
|
Thread* thread = GetCurrentThread();
|
|
|
|
Thread* thread = GetCurrentThread();
|
|
|
@ -54,7 +59,10 @@ Thread* Scheduler::PopNextReadyThread() {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void Scheduler::SwitchContext(Thread* new_thread) {
|
|
|
|
void Scheduler::SwitchContext(Thread* new_thread) {
|
|
|
|
Thread* previous_thread = GetCurrentThread();
|
|
|
|
Thread* const previous_thread = GetCurrentThread();
|
|
|
|
|
|
|
|
Process* const previous_process = Core::CurrentProcess();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
UpdateLastContextSwitchTime(previous_thread, previous_process);
|
|
|
|
|
|
|
|
|
|
|
|
// Save context for previous thread
|
|
|
|
// Save context for previous thread
|
|
|
|
if (previous_thread) {
|
|
|
|
if (previous_thread) {
|
|
|
@ -78,8 +86,6 @@ void Scheduler::SwitchContext(Thread* new_thread) {
|
|
|
|
// Cancel any outstanding wakeup events for this thread
|
|
|
|
// Cancel any outstanding wakeup events for this thread
|
|
|
|
new_thread->CancelWakeupTimer();
|
|
|
|
new_thread->CancelWakeupTimer();
|
|
|
|
|
|
|
|
|
|
|
|
auto* const previous_process = Core::CurrentProcess();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
current_thread = new_thread;
|
|
|
|
current_thread = new_thread;
|
|
|
|
|
|
|
|
|
|
|
|
ready_queue.remove(new_thread->GetPriority(), new_thread);
|
|
|
|
ready_queue.remove(new_thread->GetPriority(), new_thread);
|
|
|
@ -102,6 +108,22 @@ void Scheduler::SwitchContext(Thread* new_thread) {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void Scheduler::UpdateLastContextSwitchTime(Thread* thread, Process* process) {
|
|
|
|
|
|
|
|
const u64 prev_switch_ticks = last_context_switch_time;
|
|
|
|
|
|
|
|
const u64 most_recent_switch_ticks = CoreTiming::GetTicks();
|
|
|
|
|
|
|
|
const u64 update_ticks = most_recent_switch_ticks - prev_switch_ticks;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (thread != nullptr) {
|
|
|
|
|
|
|
|
thread->UpdateCPUTimeTicks(update_ticks);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (process != nullptr) {
|
|
|
|
|
|
|
|
process->UpdateCPUTimeTicks(update_ticks);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
last_context_switch_time = most_recent_switch_ticks;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void Scheduler::Reschedule() {
|
|
|
|
void Scheduler::Reschedule() {
|
|
|
|
std::lock_guard<std::mutex> lock(scheduler_mutex);
|
|
|
|
std::lock_guard<std::mutex> lock(scheduler_mutex);
|
|
|
|
|
|
|
|
|
|
|
|