Merge pull request #2193 from lioncash/global
kernel/scheduler: Pass in system instance in constructor
This commit is contained in:
commit
037d9bdde3
5 changed files with 23 additions and 17 deletions
|
@ -11,6 +11,7 @@
|
||||||
#endif
|
#endif
|
||||||
#include "core/arm/exclusive_monitor.h"
|
#include "core/arm/exclusive_monitor.h"
|
||||||
#include "core/arm/unicorn/arm_unicorn.h"
|
#include "core/arm/unicorn/arm_unicorn.h"
|
||||||
|
#include "core/core.h"
|
||||||
#include "core/core_cpu.h"
|
#include "core/core_cpu.h"
|
||||||
#include "core/core_timing.h"
|
#include "core/core_timing.h"
|
||||||
#include "core/hle/kernel/scheduler.h"
|
#include "core/hle/kernel/scheduler.h"
|
||||||
|
@ -49,9 +50,9 @@ bool CpuBarrier::Rendezvous() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
Cpu::Cpu(Timing::CoreTiming& core_timing, ExclusiveMonitor& exclusive_monitor,
|
Cpu::Cpu(System& system, ExclusiveMonitor& exclusive_monitor, CpuBarrier& cpu_barrier,
|
||||||
CpuBarrier& cpu_barrier, std::size_t core_index)
|
std::size_t core_index)
|
||||||
: cpu_barrier{cpu_barrier}, core_timing{core_timing}, core_index{core_index} {
|
: cpu_barrier{cpu_barrier}, core_timing{system.CoreTiming()}, core_index{core_index} {
|
||||||
if (Settings::values.use_cpu_jit) {
|
if (Settings::values.use_cpu_jit) {
|
||||||
#ifdef ARCHITECTURE_x86_64
|
#ifdef ARCHITECTURE_x86_64
|
||||||
arm_interface = std::make_unique<ARM_Dynarmic>(core_timing, exclusive_monitor, core_index);
|
arm_interface = std::make_unique<ARM_Dynarmic>(core_timing, exclusive_monitor, core_index);
|
||||||
|
@ -63,7 +64,7 @@ Cpu::Cpu(Timing::CoreTiming& core_timing, ExclusiveMonitor& exclusive_monitor,
|
||||||
arm_interface = std::make_unique<ARM_Unicorn>(core_timing);
|
arm_interface = std::make_unique<ARM_Unicorn>(core_timing);
|
||||||
}
|
}
|
||||||
|
|
||||||
scheduler = std::make_unique<Kernel::Scheduler>(*arm_interface);
|
scheduler = std::make_unique<Kernel::Scheduler>(system, *arm_interface);
|
||||||
}
|
}
|
||||||
|
|
||||||
Cpu::~Cpu() = default;
|
Cpu::~Cpu() = default;
|
||||||
|
|
|
@ -15,6 +15,10 @@ namespace Kernel {
|
||||||
class Scheduler;
|
class Scheduler;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace Core {
|
||||||
|
class System;
|
||||||
|
}
|
||||||
|
|
||||||
namespace Core::Timing {
|
namespace Core::Timing {
|
||||||
class CoreTiming;
|
class CoreTiming;
|
||||||
}
|
}
|
||||||
|
@ -45,8 +49,8 @@ private:
|
||||||
|
|
||||||
class Cpu {
|
class Cpu {
|
||||||
public:
|
public:
|
||||||
Cpu(Timing::CoreTiming& core_timing, ExclusiveMonitor& exclusive_monitor,
|
Cpu(System& system, ExclusiveMonitor& exclusive_monitor, CpuBarrier& cpu_barrier,
|
||||||
CpuBarrier& cpu_barrier, std::size_t core_index);
|
std::size_t core_index);
|
||||||
~Cpu();
|
~Cpu();
|
||||||
|
|
||||||
void RunLoop(bool tight_loop = true);
|
void RunLoop(bool tight_loop = true);
|
||||||
|
|
|
@ -27,8 +27,7 @@ void CpuCoreManager::Initialize(System& system) {
|
||||||
exclusive_monitor = Cpu::MakeExclusiveMonitor(cores.size());
|
exclusive_monitor = Cpu::MakeExclusiveMonitor(cores.size());
|
||||||
|
|
||||||
for (std::size_t index = 0; index < cores.size(); ++index) {
|
for (std::size_t index = 0; index < cores.size(); ++index) {
|
||||||
cores[index] =
|
cores[index] = std::make_unique<Cpu>(system, *exclusive_monitor, *barrier, index);
|
||||||
std::make_unique<Cpu>(system.CoreTiming(), *exclusive_monitor, *barrier, index);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create threads for CPU cores 1-3, and build thread_to_cpu map
|
// Create threads for CPU cores 1-3, and build thread_to_cpu map
|
||||||
|
|
|
@ -19,7 +19,8 @@ namespace Kernel {
|
||||||
|
|
||||||
std::mutex Scheduler::scheduler_mutex;
|
std::mutex Scheduler::scheduler_mutex;
|
||||||
|
|
||||||
Scheduler::Scheduler(Core::ARM_Interface& cpu_core) : cpu_core(cpu_core) {}
|
Scheduler::Scheduler(Core::System& system, Core::ARM_Interface& cpu_core)
|
||||||
|
: cpu_core{cpu_core}, system{system} {}
|
||||||
|
|
||||||
Scheduler::~Scheduler() {
|
Scheduler::~Scheduler() {
|
||||||
for (auto& thread : thread_list) {
|
for (auto& thread : thread_list) {
|
||||||
|
@ -61,7 +62,7 @@ Thread* Scheduler::PopNextReadyThread() {
|
||||||
|
|
||||||
void Scheduler::SwitchContext(Thread* new_thread) {
|
void Scheduler::SwitchContext(Thread* new_thread) {
|
||||||
Thread* const previous_thread = GetCurrentThread();
|
Thread* const previous_thread = GetCurrentThread();
|
||||||
Process* const previous_process = Core::CurrentProcess();
|
Process* const previous_process = system.Kernel().CurrentProcess();
|
||||||
|
|
||||||
UpdateLastContextSwitchTime(previous_thread, previous_process);
|
UpdateLastContextSwitchTime(previous_thread, previous_process);
|
||||||
|
|
||||||
|
@ -94,8 +95,8 @@ void Scheduler::SwitchContext(Thread* new_thread) {
|
||||||
|
|
||||||
auto* const thread_owner_process = current_thread->GetOwnerProcess();
|
auto* const thread_owner_process = current_thread->GetOwnerProcess();
|
||||||
if (previous_process != thread_owner_process) {
|
if (previous_process != thread_owner_process) {
|
||||||
Core::System::GetInstance().Kernel().MakeCurrentProcess(thread_owner_process);
|
system.Kernel().MakeCurrentProcess(thread_owner_process);
|
||||||
SetCurrentPageTable(&Core::CurrentProcess()->VMManager().page_table);
|
SetCurrentPageTable(&thread_owner_process->VMManager().page_table);
|
||||||
}
|
}
|
||||||
|
|
||||||
cpu_core.LoadContext(new_thread->GetContext());
|
cpu_core.LoadContext(new_thread->GetContext());
|
||||||
|
@ -111,7 +112,7 @@ void Scheduler::SwitchContext(Thread* new_thread) {
|
||||||
|
|
||||||
void Scheduler::UpdateLastContextSwitchTime(Thread* thread, Process* process) {
|
void Scheduler::UpdateLastContextSwitchTime(Thread* thread, Process* process) {
|
||||||
const u64 prev_switch_ticks = last_context_switch_time;
|
const u64 prev_switch_ticks = last_context_switch_time;
|
||||||
const u64 most_recent_switch_ticks = Core::System::GetInstance().CoreTiming().GetTicks();
|
const u64 most_recent_switch_ticks = system.CoreTiming().GetTicks();
|
||||||
const u64 update_ticks = most_recent_switch_ticks - prev_switch_ticks;
|
const u64 update_ticks = most_recent_switch_ticks - prev_switch_ticks;
|
||||||
|
|
||||||
if (thread != nullptr) {
|
if (thread != nullptr) {
|
||||||
|
@ -223,8 +224,7 @@ void Scheduler::YieldWithLoadBalancing(Thread* thread) {
|
||||||
// Take the first non-nullptr one
|
// Take the first non-nullptr one
|
||||||
for (unsigned cur_core = 0; cur_core < Core::NUM_CPU_CORES; ++cur_core) {
|
for (unsigned cur_core = 0; cur_core < Core::NUM_CPU_CORES; ++cur_core) {
|
||||||
const auto res =
|
const auto res =
|
||||||
Core::System::GetInstance().CpuCore(cur_core).Scheduler().GetNextSuggestedThread(
|
system.CpuCore(cur_core).Scheduler().GetNextSuggestedThread(core, priority);
|
||||||
core, priority);
|
|
||||||
|
|
||||||
// If scheduler provides a suggested thread
|
// If scheduler provides a suggested thread
|
||||||
if (res != nullptr) {
|
if (res != nullptr) {
|
||||||
|
|
|
@ -13,7 +13,8 @@
|
||||||
|
|
||||||
namespace Core {
|
namespace Core {
|
||||||
class ARM_Interface;
|
class ARM_Interface;
|
||||||
}
|
class System;
|
||||||
|
} // namespace Core
|
||||||
|
|
||||||
namespace Kernel {
|
namespace Kernel {
|
||||||
|
|
||||||
|
@ -21,7 +22,7 @@ class Process;
|
||||||
|
|
||||||
class Scheduler final {
|
class Scheduler final {
|
||||||
public:
|
public:
|
||||||
explicit Scheduler(Core::ARM_Interface& cpu_core);
|
explicit Scheduler(Core::System& system, Core::ARM_Interface& cpu_core);
|
||||||
~Scheduler();
|
~Scheduler();
|
||||||
|
|
||||||
/// Returns whether there are any threads that are ready to run.
|
/// Returns whether there are any threads that are ready to run.
|
||||||
|
@ -162,6 +163,7 @@ private:
|
||||||
Core::ARM_Interface& cpu_core;
|
Core::ARM_Interface& cpu_core;
|
||||||
u64 last_context_switch_time = 0;
|
u64 last_context_switch_time = 0;
|
||||||
|
|
||||||
|
Core::System& system;
|
||||||
static std::mutex scheduler_mutex;
|
static std::mutex scheduler_mutex;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue