summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/core/cpu_manager.cpp13
-rw-r--r--src/core/hle/kernel/k_thread.h9
-rw-r--r--src/core/hle/kernel/kernel.cpp21
-rw-r--r--src/core/hle/kernel/kernel.h4
4 files changed, 31 insertions, 16 deletions
diff --git a/src/core/cpu_manager.cpp b/src/core/cpu_manager.cpp
index 018cd2e25..719258250 100644
--- a/src/core/cpu_manager.cpp
+++ b/src/core/cpu_manager.cpp
@@ -217,9 +217,9 @@ void CpuManager::SingleCoreRunGuestLoop() {
physical_core = &kernel.CurrentPhysicalCore();
}
system.ExitDynarmicProfile();
- thread->SetPhantomMode(true);
+ kernel.SetIsPhantomModeForSingleCore(true);
system.CoreTiming().Advance();
- thread->SetPhantomMode(false);
+ kernel.SetIsPhantomModeForSingleCore(false);
physical_core->ArmInterface().ClearExclusiveState();
PreemptSingleCore();
auto& scheduler = kernel.Scheduler(current_core);
@@ -255,22 +255,23 @@ void CpuManager::SingleCoreRunSuspendThread() {
void CpuManager::PreemptSingleCore(bool from_running_enviroment) {
{
- auto& scheduler = system.Kernel().Scheduler(current_core);
+ auto& kernel = system.Kernel();
+ auto& scheduler = kernel.Scheduler(current_core);
Kernel::KThread* current_thread = scheduler.GetCurrentThread();
if (idle_count >= 4 || from_running_enviroment) {
if (!from_running_enviroment) {
system.CoreTiming().Idle();
idle_count = 0;
}
- current_thread->SetPhantomMode(true);
+ kernel.SetIsPhantomModeForSingleCore(true);
system.CoreTiming().Advance();
- current_thread->SetPhantomMode(false);
+ kernel.SetIsPhantomModeForSingleCore(false);
}
current_core.store((current_core + 1) % Core::Hardware::NUM_CPU_CORES);
system.CoreTiming().ResetTicks();
scheduler.Unload(scheduler.GetCurrentThread());
- auto& next_scheduler = system.Kernel().Scheduler(current_core);
+ auto& next_scheduler = kernel.Scheduler(current_core);
Common::Fiber::YieldTo(current_thread->GetHostContext(), next_scheduler.ControlContext());
}
diff --git a/src/core/hle/kernel/k_thread.h b/src/core/hle/kernel/k_thread.h
index d9fe2e363..7dec9449e 100644
--- a/src/core/hle/kernel/k_thread.h
+++ b/src/core/hle/kernel/k_thread.h
@@ -451,14 +451,6 @@ public:
is_continuous_on_svc = is_continuous;
}
- bool IsPhantomMode() const {
- return is_phantom_mode;
- }
-
- void SetPhantomMode(bool phantom) {
- is_phantom_mode = phantom;
- }
-
bool HasExited() const {
return has_exited;
}
@@ -747,7 +739,6 @@ private:
bool is_continuous_on_svc = false;
bool will_be_terminated = false;
- bool is_phantom_mode = false;
bool has_exited = false;
bool was_running = false;
diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp
index 6ae0bdeed..80a78e643 100644
--- a/src/core/hle/kernel/kernel.cpp
+++ b/src/core/hle/kernel/kernel.cpp
@@ -62,6 +62,7 @@ struct KernelCore::Impl {
global_scheduler_context = std::make_unique<Kernel::GlobalSchedulerContext>(kernel);
service_thread_manager =
std::make_unique<Common::ThreadWorker>(1, "yuzu:ServiceThreadManager");
+ is_phantom_mode_for_singlecore = false;
InitializePhysicalCores();
InitializeSystemResourceLimit(kernel);
@@ -227,6 +228,15 @@ struct KernelCore::Impl {
return this_id;
}
+ bool IsPhantomModeForSingleCore() const {
+ return is_phantom_mode_for_singlecore;
+ }
+
+ void SetIsPhantomModeForSingleCore(bool value) {
+ ASSERT(!is_multicore);
+ is_phantom_mode_for_singlecore = value;
+ }
+
[[nodiscard]] Core::EmuThreadHandle GetCurrentEmuThreadID() {
Core::EmuThreadHandle result = Core::EmuThreadHandle::InvalidHandle();
result.host_handle = GetCurrentHostThreadID();
@@ -235,7 +245,7 @@ struct KernelCore::Impl {
}
const Kernel::KScheduler& sched = cores[result.host_handle].Scheduler();
const Kernel::KThread* current = sched.GetCurrentThread();
- if (current != nullptr && !current->IsPhantomMode()) {
+ if (current != nullptr && !IsPhantomModeForSingleCore()) {
result.guest_handle = current->GetGlobalHandle();
} else {
result.guest_handle = InvalidHandle;
@@ -345,6 +355,7 @@ struct KernelCore::Impl {
std::array<std::unique_ptr<Kernel::KScheduler>, Core::Hardware::NUM_CPU_CORES> schedulers{};
bool is_multicore{};
+ bool is_phantom_mode_for_singlecore{};
u32 single_core_thread_id{};
std::array<u64, Core::Hardware::NUM_CPU_CORES> svc_ticks{};
@@ -643,4 +654,12 @@ void KernelCore::ReleaseServiceThread(std::weak_ptr<Kernel::ServiceThread> servi
});
}
+bool KernelCore::IsPhantomModeForSingleCore() const {
+ return impl->IsPhantomModeForSingleCore();
+}
+
+void KernelCore::SetIsPhantomModeForSingleCore(bool value) {
+ impl->SetIsPhantomModeForSingleCore(value);
+}
+
} // namespace Kernel
diff --git a/src/core/hle/kernel/kernel.h b/src/core/hle/kernel/kernel.h
index 41c553582..fc58f3ecb 100644
--- a/src/core/hle/kernel/kernel.h
+++ b/src/core/hle/kernel/kernel.h
@@ -237,6 +237,10 @@ public:
*/
void ReleaseServiceThread(std::weak_ptr<Kernel::ServiceThread> service_thread);
+ /// Workaround for single-core mode when preempting threads while idle.
+ bool IsPhantomModeForSingleCore() const;
+ void SetIsPhantomModeForSingleCore(bool value);
+
private:
friend class Object;
friend class Process;