|
|
|
@ -27,6 +27,13 @@ namespace Core {
|
|
|
|
|
|
|
|
|
|
System::~System() = default;
|
|
|
|
|
|
|
|
|
|
/// Runs a CPU core while the system is powered on
|
|
|
|
|
static void RunCpuCore(std::shared_ptr<Cpu> cpu_state) {
|
|
|
|
|
while (Core::System().GetInstance().IsPoweredOn()) {
|
|
|
|
|
cpu_state->RunLoop(true);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
System::ResultStatus System::RunLoop(bool tight_loop) {
|
|
|
|
|
status = ResultStatus::Success;
|
|
|
|
|
|
|
|
|
@ -109,7 +116,7 @@ System::ResultStatus System::Load(EmuWindow* emu_window, const std::string& file
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void System::PrepareReschedule() {
|
|
|
|
|
cpu_cores[0]->PrepareReschedule();
|
|
|
|
|
CurrentCpuCore().PrepareReschedule();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
PerfStats::Results System::GetAndResetPerfStats() {
|
|
|
|
@ -123,14 +130,13 @@ System::ResultStatus System::Init(EmuWindow* emu_window, u32 system_mode) {
|
|
|
|
|
|
|
|
|
|
current_process = Kernel::Process::Create("main");
|
|
|
|
|
|
|
|
|
|
for (auto& cpu_core : cpu_cores) {
|
|
|
|
|
cpu_core = std::make_unique<Cpu>();
|
|
|
|
|
cpu_barrier = std::make_shared<CpuBarrier>();
|
|
|
|
|
for (size_t index = 0; index < cpu_cores.size(); ++index) {
|
|
|
|
|
cpu_cores[index] = std::make_shared<Cpu>(cpu_barrier, index);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
gpu_core = std::make_unique<Tegra::GPU>();
|
|
|
|
|
|
|
|
|
|
telemetry_session = std::make_unique<Core::TelemetrySession>();
|
|
|
|
|
|
|
|
|
|
service_manager = std::make_shared<Service::SM::ServiceManager>();
|
|
|
|
|
|
|
|
|
|
HW::Init();
|
|
|
|
@ -142,6 +148,14 @@ System::ResultStatus System::Init(EmuWindow* emu_window, u32 system_mode) {
|
|
|
|
|
return ResultStatus::ErrorVideoCore;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Create threads for CPU cores 1-3, and build thread_to_cpu map
|
|
|
|
|
// CPU core 0 is run on the main thread
|
|
|
|
|
thread_to_cpu[std::this_thread::get_id()] = cpu_cores[0];
|
|
|
|
|
for (size_t index = 0; index < cpu_core_threads.size(); ++index) {
|
|
|
|
|
cpu_core_threads[index] = std::make_unique<std::thread>(RunCpuCore, cpu_cores[index + 1]);
|
|
|
|
|
thread_to_cpu[cpu_core_threads[index]->get_id()] = cpu_cores[index + 1];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
NGLOG_DEBUG(Core, "Initialized OK");
|
|
|
|
|
|
|
|
|
|
// Reset counters and set time origin to current frame
|
|
|
|
@ -171,9 +185,15 @@ void System::Shutdown() {
|
|
|
|
|
telemetry_session.reset();
|
|
|
|
|
gpu_core.reset();
|
|
|
|
|
|
|
|
|
|
// Close all CPU/threading state
|
|
|
|
|
thread_to_cpu.clear();
|
|
|
|
|
for (auto& cpu_core : cpu_cores) {
|
|
|
|
|
cpu_core.reset();
|
|
|
|
|
}
|
|
|
|
|
for (auto& thread : cpu_core_threads) {
|
|
|
|
|
thread->join();
|
|
|
|
|
thread.reset();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
CoreTiming::Shutdown();
|
|
|
|
|
|
|
|
|
|