summaryrefslogtreecommitdiff
path: root/src/core/core.cpp
diff options
context:
space:
mode:
authorGravatar bunnei2018-05-02 21:26:14 -0400
committerGravatar bunnei2018-05-10 19:34:46 -0400
commit9776ff91797423a9cf19571faafe4648fb5a1d1d (patch)
tree46a7c94c53faee26b805f6290a09c45d33f7bf11 /src/core/core.cpp
parentcore: Move common CPU core things to its own class. (diff)
downloadyuzu-9776ff91797423a9cf19571faafe4648fb5a1d1d.tar.gz
yuzu-9776ff91797423a9cf19571faafe4648fb5a1d1d.tar.xz
yuzu-9776ff91797423a9cf19571faafe4648fb5a1d1d.zip
core: Create a thread for each CPU core, keep in lock-step with a barrier.
Diffstat (limited to 'src/core/core.cpp')
-rw-r--r--src/core/core.cpp30
1 files changed, 25 insertions, 5 deletions
diff --git a/src/core/core.cpp b/src/core/core.cpp
index 0af78c18c..066423f23 100644
--- a/src/core/core.cpp
+++ b/src/core/core.cpp
@@ -27,6 +27,13 @@ namespace Core {
27 27
28System::~System() = default; 28System::~System() = default;
29 29
30/// Runs a CPU core while the system is powered on
31static void RunCpuCore(std::shared_ptr<Cpu> cpu_state) {
32 while (Core::System().GetInstance().IsPoweredOn()) {
33 cpu_state->RunLoop(true);
34 }
35}
36
30System::ResultStatus System::RunLoop(bool tight_loop) { 37System::ResultStatus System::RunLoop(bool tight_loop) {
31 status = ResultStatus::Success; 38 status = ResultStatus::Success;
32 39
@@ -109,7 +116,7 @@ System::ResultStatus System::Load(EmuWindow* emu_window, const std::string& file
109} 116}
110 117
111void System::PrepareReschedule() { 118void System::PrepareReschedule() {
112 cpu_cores[0]->PrepareReschedule(); 119 CurrentCpuCore().PrepareReschedule();
113} 120}
114 121
115PerfStats::Results System::GetAndResetPerfStats() { 122PerfStats::Results System::GetAndResetPerfStats() {
@@ -123,14 +130,13 @@ System::ResultStatus System::Init(EmuWindow* emu_window, u32 system_mode) {
123 130
124 current_process = Kernel::Process::Create("main"); 131 current_process = Kernel::Process::Create("main");
125 132
126 for (auto& cpu_core : cpu_cores) { 133 cpu_barrier = std::make_shared<CpuBarrier>();
127 cpu_core = std::make_unique<Cpu>(); 134 for (size_t index = 0; index < cpu_cores.size(); ++index) {
135 cpu_cores[index] = std::make_shared<Cpu>(cpu_barrier, index);
128 } 136 }
129 137
130 gpu_core = std::make_unique<Tegra::GPU>(); 138 gpu_core = std::make_unique<Tegra::GPU>();
131
132 telemetry_session = std::make_unique<Core::TelemetrySession>(); 139 telemetry_session = std::make_unique<Core::TelemetrySession>();
133
134 service_manager = std::make_shared<Service::SM::ServiceManager>(); 140 service_manager = std::make_shared<Service::SM::ServiceManager>();
135 141
136 HW::Init(); 142 HW::Init();
@@ -142,6 +148,14 @@ System::ResultStatus System::Init(EmuWindow* emu_window, u32 system_mode) {
142 return ResultStatus::ErrorVideoCore; 148 return ResultStatus::ErrorVideoCore;
143 } 149 }
144 150
151 // Create threads for CPU cores 1-3, and build thread_to_cpu map
152 // CPU core 0 is run on the main thread
153 thread_to_cpu[std::this_thread::get_id()] = cpu_cores[0];
154 for (size_t index = 0; index < cpu_core_threads.size(); ++index) {
155 cpu_core_threads[index] = std::make_unique<std::thread>(RunCpuCore, cpu_cores[index + 1]);
156 thread_to_cpu[cpu_core_threads[index]->get_id()] = cpu_cores[index + 1];
157 }
158
145 NGLOG_DEBUG(Core, "Initialized OK"); 159 NGLOG_DEBUG(Core, "Initialized OK");
146 160
147 // Reset counters and set time origin to current frame 161 // Reset counters and set time origin to current frame
@@ -171,9 +185,15 @@ void System::Shutdown() {
171 telemetry_session.reset(); 185 telemetry_session.reset();
172 gpu_core.reset(); 186 gpu_core.reset();
173 187
188 // Close all CPU/threading state
189 thread_to_cpu.clear();
174 for (auto& cpu_core : cpu_cores) { 190 for (auto& cpu_core : cpu_cores) {
175 cpu_core.reset(); 191 cpu_core.reset();
176 } 192 }
193 for (auto& thread : cpu_core_threads) {
194 thread->join();
195 thread.reset();
196 }
177 197
178 CoreTiming::Shutdown(); 198 CoreTiming::Shutdown();
179 199