core: Create a thread for each CPU core, keep in lock-step with a barrier.

This commit is contained in:
bunnei 2018-05-02 21:26:14 -04:00
parent 5590245930
commit 9776ff9179
4 changed files with 94 additions and 18 deletions

View file

@ -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();