summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/core/core.cpp32
-rw-r--r--src/core/core.h10
-rw-r--r--src/core/core_cpu.cpp11
-rw-r--r--src/core/settings.h1
-rw-r--r--src/core/telemetry_session.cpp2
-rw-r--r--src/yuzu/configuration/config.cpp2
-rw-r--r--src/yuzu/configuration/configure_general.cpp3
-rw-r--r--src/yuzu/configuration/configure_general.ui7
-rw-r--r--src/yuzu_cmd/config.cpp1
-rw-r--r--src/yuzu_cmd/default_ini.h4
10 files changed, 56 insertions, 17 deletions
diff --git a/src/core/core.cpp b/src/core/core.cpp
index 1e6be34c8..59c8940f7 100644
--- a/src/core/core.cpp
+++ b/src/core/core.cpp
@@ -126,6 +126,21 @@ PerfStats::Results System::GetAndResetPerfStats() {
return perf_stats.GetAndResetStats(CoreTiming::GetGlobalTimeUs());
}
+const std::shared_ptr<Kernel::Scheduler>& System::Scheduler(size_t core_index) {
+ if (!Settings::values.use_multi_core) {
+ // Always use Core 0 scheduler when multicore is disabled
+ return cpu_cores[0]->Scheduler();
+ }
+
+ ASSERT(core_index < NUM_CPU_CORES);
+ return cpu_cores[core_index]->Scheduler();
+}
+
+ARM_Interface& System::ArmInterface(size_t core_index) {
+ ASSERT(core_index < NUM_CPU_CORES);
+ return cpu_cores[core_index]->ArmInterface();
+}
+
System::ResultStatus System::Init(EmuWindow* emu_window, u32 system_mode) {
NGLOG_DEBUG(HW_Memory, "initialized OK");
@@ -154,9 +169,12 @@ System::ResultStatus System::Init(EmuWindow* emu_window, u32 system_mode) {
// 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];
+ if (Settings::values.use_multi_core) {
+ 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");
@@ -190,9 +208,11 @@ void System::Shutdown() {
// Close all CPU/threading state
cpu_barrier->NotifyEnd();
- for (auto& thread : cpu_core_threads) {
- thread->join();
- thread.reset();
+ if (Settings::values.use_multi_core) {
+ for (auto& thread : cpu_core_threads) {
+ thread->join();
+ thread.reset();
+ }
}
thread_to_cpu.clear();
for (auto& cpu_core : cpu_cores) {
diff --git a/src/core/core.h b/src/core/core.h
index 561e7b48f..115061932 100644
--- a/src/core/core.h
+++ b/src/core/core.h
@@ -112,10 +112,7 @@ public:
return CurrentCpuCore().ArmInterface();
}
- ARM_Interface& ArmInterface(size_t core_index) {
- ASSERT(core_index < NUM_CPU_CORES);
- return cpu_cores[core_index]->ArmInterface();
- }
+ ARM_Interface& ArmInterface(size_t core_index);
Tegra::GPU& GPU() {
return *gpu_core;
@@ -125,10 +122,7 @@ public:
return *CurrentCpuCore().Scheduler();
}
- const std::shared_ptr<Kernel::Scheduler>& Scheduler(size_t core_index) {
- ASSERT(core_index < NUM_CPU_CORES);
- return cpu_cores[core_index]->Scheduler();
- }
+ const std::shared_ptr<Kernel::Scheduler>& Scheduler(size_t core_index);
Kernel::SharedPtr<Kernel::Process>& CurrentProcess() {
return current_process;
diff --git a/src/core/core_cpu.cpp b/src/core/core_cpu.cpp
index bd9869d28..099f2bb1a 100644
--- a/src/core/core_cpu.cpp
+++ b/src/core/core_cpu.cpp
@@ -26,9 +26,12 @@ void CpuBarrier::NotifyEnd() {
}
bool CpuBarrier::Rendezvous() {
- if (end) {
- return false;
- } else {
+ if (!Settings::values.use_multi_core) {
+ // Meaningless when running in single-core mode
+ return true;
+ }
+
+ if (!end) {
std::unique_lock<std::mutex> lock(mutex);
--cores_waiting;
@@ -41,6 +44,8 @@ bool CpuBarrier::Rendezvous() {
condition.wait(lock);
return true;
}
+
+ return false;
}
Cpu::Cpu(std::shared_ptr<CpuBarrier> cpu_barrier, size_t core_index)
diff --git a/src/core/settings.h b/src/core/settings.h
index cfec63c21..a7f1e5fa0 100644
--- a/src/core/settings.h
+++ b/src/core/settings.h
@@ -121,6 +121,7 @@ struct Values {
// Core
bool use_cpu_jit;
+ bool use_multi_core;
// Data Storage
bool use_virtual_sd;
diff --git a/src/core/telemetry_session.cpp b/src/core/telemetry_session.cpp
index 02c52bb55..a60aa1143 100644
--- a/src/core/telemetry_session.cpp
+++ b/src/core/telemetry_session.cpp
@@ -155,6 +155,8 @@ TelemetrySession::TelemetrySession() {
// Log user configuration information
AddField(Telemetry::FieldType::UserConfig, "Core_UseCpuJit", Settings::values.use_cpu_jit);
+ AddField(Telemetry::FieldType::UserConfig, "Core_UseMultiCore",
+ Settings::values.use_multi_core);
AddField(Telemetry::FieldType::UserConfig, "Renderer_ResolutionFactor",
Settings::values.resolution_factor);
AddField(Telemetry::FieldType::UserConfig, "Renderer_ToggleFramelimit",
diff --git a/src/yuzu/configuration/config.cpp b/src/yuzu/configuration/config.cpp
index 8843f2078..8316db708 100644
--- a/src/yuzu/configuration/config.cpp
+++ b/src/yuzu/configuration/config.cpp
@@ -78,6 +78,7 @@ void Config::ReadValues() {
qt_config->beginGroup("Core");
Settings::values.use_cpu_jit = qt_config->value("use_cpu_jit", true).toBool();
+ Settings::values.use_multi_core = qt_config->value("use_multi_core", false).toBool();
qt_config->endGroup();
qt_config->beginGroup("Renderer");
@@ -177,6 +178,7 @@ void Config::SaveValues() {
qt_config->beginGroup("Core");
qt_config->setValue("use_cpu_jit", Settings::values.use_cpu_jit);
+ qt_config->setValue("use_multi_core", Settings::values.use_multi_core);
qt_config->endGroup();
qt_config->beginGroup("Renderer");
diff --git a/src/yuzu/configuration/configure_general.cpp b/src/yuzu/configuration/configure_general.cpp
index 2d73fc5aa..baa558667 100644
--- a/src/yuzu/configuration/configure_general.cpp
+++ b/src/yuzu/configuration/configure_general.cpp
@@ -20,6 +20,7 @@ ConfigureGeneral::ConfigureGeneral(QWidget* parent)
this->setConfiguration();
ui->use_cpu_jit->setEnabled(!Core::System::GetInstance().IsPoweredOn());
+ ui->use_multi_core->setEnabled(!Core::System::GetInstance().IsPoweredOn());
ui->use_docked_mode->setEnabled(!Core::System::GetInstance().IsPoweredOn());
}
@@ -30,6 +31,7 @@ void ConfigureGeneral::setConfiguration() {
ui->toggle_check_exit->setChecked(UISettings::values.confirm_before_closing);
ui->theme_combobox->setCurrentIndex(ui->theme_combobox->findData(UISettings::values.theme));
ui->use_cpu_jit->setChecked(Settings::values.use_cpu_jit);
+ ui->use_multi_core->setChecked(Settings::values.use_multi_core);
ui->use_docked_mode->setChecked(Settings::values.use_docked_mode);
}
@@ -40,6 +42,7 @@ void ConfigureGeneral::applyConfiguration() {
ui->theme_combobox->itemData(ui->theme_combobox->currentIndex()).toString();
Settings::values.use_cpu_jit = ui->use_cpu_jit->isChecked();
+ Settings::values.use_multi_core = ui->use_multi_core->isChecked();
Settings::values.use_docked_mode = ui->use_docked_mode->isChecked();
Settings::Apply();
}
diff --git a/src/yuzu/configuration/configure_general.ui b/src/yuzu/configuration/configure_general.ui
index 1775c4d40..233adbe27 100644
--- a/src/yuzu/configuration/configure_general.ui
+++ b/src/yuzu/configuration/configure_general.ui
@@ -58,6 +58,13 @@
</property>
</widget>
</item>
+ <item>
+ <widget class="QCheckBox" name="use_multi_core">
+ <property name="text">
+ <string>Enable multi-core</string>
+ </property>
+ </widget>
+ </item>
</layout>
</item>
</layout>
diff --git a/src/yuzu_cmd/config.cpp b/src/yuzu_cmd/config.cpp
index 675f9cafa..ee6e4d658 100644
--- a/src/yuzu_cmd/config.cpp
+++ b/src/yuzu_cmd/config.cpp
@@ -91,6 +91,7 @@ void Config::ReadValues() {
// Core
Settings::values.use_cpu_jit = sdl2_config->GetBoolean("Core", "use_cpu_jit", true);
+ Settings::values.use_multi_core = sdl2_config->GetBoolean("Core", "use_multi_core", false);
// Renderer
Settings::values.resolution_factor =
diff --git a/src/yuzu_cmd/default_ini.h b/src/yuzu_cmd/default_ini.h
index 02254403d..1c438c3f5 100644
--- a/src/yuzu_cmd/default_ini.h
+++ b/src/yuzu_cmd/default_ini.h
@@ -80,6 +80,10 @@ touch_device=
# 0: Interpreter (slow), 1 (default): JIT (fast)
use_cpu_jit =
+# Whether to use multi-core for CPU emulation
+# 0 (default): Disabled, 1: Enabled
+use_multi_core=
+
[Renderer]
# Whether to use software or hardware rendering.
# 0: Software, 1 (default): Hardware