diff options
| author | 2020-12-31 02:13:02 -0800 | |
|---|---|---|
| committer | 2021-01-28 21:42:25 -0800 | |
| commit | 47829850131f04075950b733cb93a3688e8afb5b (patch) | |
| tree | 26f0cf0a7f9b01c0266b2b3752fb600953875129 /src | |
| parent | hle: kernel: KThread: Remove thread types that do not exist. (diff) | |
| download | yuzu-47829850131f04075950b733cb93a3688e8afb5b.tar.gz yuzu-47829850131f04075950b733cb93a3688e8afb5b.tar.xz yuzu-47829850131f04075950b733cb93a3688e8afb5b.zip | |
hle: kernel: Move single core "phantom mode" out of KThread.
- This is a workaround that does not belong in a kernel primitive.
Diffstat (limited to 'src')
| -rw-r--r-- | src/core/cpu_manager.cpp | 13 | ||||
| -rw-r--r-- | src/core/hle/kernel/k_thread.h | 9 | ||||
| -rw-r--r-- | src/core/hle/kernel/kernel.cpp | 21 | ||||
| -rw-r--r-- | src/core/hle/kernel/kernel.h | 4 |
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() { | |||
| 217 | physical_core = &kernel.CurrentPhysicalCore(); | 217 | physical_core = &kernel.CurrentPhysicalCore(); |
| 218 | } | 218 | } |
| 219 | system.ExitDynarmicProfile(); | 219 | system.ExitDynarmicProfile(); |
| 220 | thread->SetPhantomMode(true); | 220 | kernel.SetIsPhantomModeForSingleCore(true); |
| 221 | system.CoreTiming().Advance(); | 221 | system.CoreTiming().Advance(); |
| 222 | thread->SetPhantomMode(false); | 222 | kernel.SetIsPhantomModeForSingleCore(false); |
| 223 | physical_core->ArmInterface().ClearExclusiveState(); | 223 | physical_core->ArmInterface().ClearExclusiveState(); |
| 224 | PreemptSingleCore(); | 224 | PreemptSingleCore(); |
| 225 | auto& scheduler = kernel.Scheduler(current_core); | 225 | auto& scheduler = kernel.Scheduler(current_core); |
| @@ -255,22 +255,23 @@ void CpuManager::SingleCoreRunSuspendThread() { | |||
| 255 | 255 | ||
| 256 | void CpuManager::PreemptSingleCore(bool from_running_enviroment) { | 256 | void CpuManager::PreemptSingleCore(bool from_running_enviroment) { |
| 257 | { | 257 | { |
| 258 | auto& scheduler = system.Kernel().Scheduler(current_core); | 258 | auto& kernel = system.Kernel(); |
| 259 | auto& scheduler = kernel.Scheduler(current_core); | ||
| 259 | Kernel::KThread* current_thread = scheduler.GetCurrentThread(); | 260 | Kernel::KThread* current_thread = scheduler.GetCurrentThread(); |
| 260 | if (idle_count >= 4 || from_running_enviroment) { | 261 | if (idle_count >= 4 || from_running_enviroment) { |
| 261 | if (!from_running_enviroment) { | 262 | if (!from_running_enviroment) { |
| 262 | system.CoreTiming().Idle(); | 263 | system.CoreTiming().Idle(); |
| 263 | idle_count = 0; | 264 | idle_count = 0; |
| 264 | } | 265 | } |
| 265 | current_thread->SetPhantomMode(true); | 266 | kernel.SetIsPhantomModeForSingleCore(true); |
| 266 | system.CoreTiming().Advance(); | 267 | system.CoreTiming().Advance(); |
| 267 | current_thread->SetPhantomMode(false); | 268 | kernel.SetIsPhantomModeForSingleCore(false); |
| 268 | } | 269 | } |
| 269 | current_core.store((current_core + 1) % Core::Hardware::NUM_CPU_CORES); | 270 | current_core.store((current_core + 1) % Core::Hardware::NUM_CPU_CORES); |
| 270 | system.CoreTiming().ResetTicks(); | 271 | system.CoreTiming().ResetTicks(); |
| 271 | scheduler.Unload(scheduler.GetCurrentThread()); | 272 | scheduler.Unload(scheduler.GetCurrentThread()); |
| 272 | 273 | ||
| 273 | auto& next_scheduler = system.Kernel().Scheduler(current_core); | 274 | auto& next_scheduler = kernel.Scheduler(current_core); |
| 274 | Common::Fiber::YieldTo(current_thread->GetHostContext(), next_scheduler.ControlContext()); | 275 | Common::Fiber::YieldTo(current_thread->GetHostContext(), next_scheduler.ControlContext()); |
| 275 | } | 276 | } |
| 276 | 277 | ||
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: | |||
| 451 | is_continuous_on_svc = is_continuous; | 451 | is_continuous_on_svc = is_continuous; |
| 452 | } | 452 | } |
| 453 | 453 | ||
| 454 | bool IsPhantomMode() const { | ||
| 455 | return is_phantom_mode; | ||
| 456 | } | ||
| 457 | |||
| 458 | void SetPhantomMode(bool phantom) { | ||
| 459 | is_phantom_mode = phantom; | ||
| 460 | } | ||
| 461 | |||
| 462 | bool HasExited() const { | 454 | bool HasExited() const { |
| 463 | return has_exited; | 455 | return has_exited; |
| 464 | } | 456 | } |
| @@ -747,7 +739,6 @@ private: | |||
| 747 | bool is_continuous_on_svc = false; | 739 | bool is_continuous_on_svc = false; |
| 748 | 740 | ||
| 749 | bool will_be_terminated = false; | 741 | bool will_be_terminated = false; |
| 750 | bool is_phantom_mode = false; | ||
| 751 | bool has_exited = false; | 742 | bool has_exited = false; |
| 752 | 743 | ||
| 753 | bool was_running = false; | 744 | 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 { | |||
| 62 | global_scheduler_context = std::make_unique<Kernel::GlobalSchedulerContext>(kernel); | 62 | global_scheduler_context = std::make_unique<Kernel::GlobalSchedulerContext>(kernel); |
| 63 | service_thread_manager = | 63 | service_thread_manager = |
| 64 | std::make_unique<Common::ThreadWorker>(1, "yuzu:ServiceThreadManager"); | 64 | std::make_unique<Common::ThreadWorker>(1, "yuzu:ServiceThreadManager"); |
| 65 | is_phantom_mode_for_singlecore = false; | ||
| 65 | 66 | ||
| 66 | InitializePhysicalCores(); | 67 | InitializePhysicalCores(); |
| 67 | InitializeSystemResourceLimit(kernel); | 68 | InitializeSystemResourceLimit(kernel); |
| @@ -227,6 +228,15 @@ struct KernelCore::Impl { | |||
| 227 | return this_id; | 228 | return this_id; |
| 228 | } | 229 | } |
| 229 | 230 | ||
| 231 | bool IsPhantomModeForSingleCore() const { | ||
| 232 | return is_phantom_mode_for_singlecore; | ||
| 233 | } | ||
| 234 | |||
| 235 | void SetIsPhantomModeForSingleCore(bool value) { | ||
| 236 | ASSERT(!is_multicore); | ||
| 237 | is_phantom_mode_for_singlecore = value; | ||
| 238 | } | ||
| 239 | |||
| 230 | [[nodiscard]] Core::EmuThreadHandle GetCurrentEmuThreadID() { | 240 | [[nodiscard]] Core::EmuThreadHandle GetCurrentEmuThreadID() { |
| 231 | Core::EmuThreadHandle result = Core::EmuThreadHandle::InvalidHandle(); | 241 | Core::EmuThreadHandle result = Core::EmuThreadHandle::InvalidHandle(); |
| 232 | result.host_handle = GetCurrentHostThreadID(); | 242 | result.host_handle = GetCurrentHostThreadID(); |
| @@ -235,7 +245,7 @@ struct KernelCore::Impl { | |||
| 235 | } | 245 | } |
| 236 | const Kernel::KScheduler& sched = cores[result.host_handle].Scheduler(); | 246 | const Kernel::KScheduler& sched = cores[result.host_handle].Scheduler(); |
| 237 | const Kernel::KThread* current = sched.GetCurrentThread(); | 247 | const Kernel::KThread* current = sched.GetCurrentThread(); |
| 238 | if (current != nullptr && !current->IsPhantomMode()) { | 248 | if (current != nullptr && !IsPhantomModeForSingleCore()) { |
| 239 | result.guest_handle = current->GetGlobalHandle(); | 249 | result.guest_handle = current->GetGlobalHandle(); |
| 240 | } else { | 250 | } else { |
| 241 | result.guest_handle = InvalidHandle; | 251 | result.guest_handle = InvalidHandle; |
| @@ -345,6 +355,7 @@ struct KernelCore::Impl { | |||
| 345 | std::array<std::unique_ptr<Kernel::KScheduler>, Core::Hardware::NUM_CPU_CORES> schedulers{}; | 355 | std::array<std::unique_ptr<Kernel::KScheduler>, Core::Hardware::NUM_CPU_CORES> schedulers{}; |
| 346 | 356 | ||
| 347 | bool is_multicore{}; | 357 | bool is_multicore{}; |
| 358 | bool is_phantom_mode_for_singlecore{}; | ||
| 348 | u32 single_core_thread_id{}; | 359 | u32 single_core_thread_id{}; |
| 349 | 360 | ||
| 350 | std::array<u64, Core::Hardware::NUM_CPU_CORES> svc_ticks{}; | 361 | std::array<u64, Core::Hardware::NUM_CPU_CORES> svc_ticks{}; |
| @@ -643,4 +654,12 @@ void KernelCore::ReleaseServiceThread(std::weak_ptr<Kernel::ServiceThread> servi | |||
| 643 | }); | 654 | }); |
| 644 | } | 655 | } |
| 645 | 656 | ||
| 657 | bool KernelCore::IsPhantomModeForSingleCore() const { | ||
| 658 | return impl->IsPhantomModeForSingleCore(); | ||
| 659 | } | ||
| 660 | |||
| 661 | void KernelCore::SetIsPhantomModeForSingleCore(bool value) { | ||
| 662 | impl->SetIsPhantomModeForSingleCore(value); | ||
| 663 | } | ||
| 664 | |||
| 646 | } // namespace Kernel | 665 | } // 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: | |||
| 237 | */ | 237 | */ |
| 238 | void ReleaseServiceThread(std::weak_ptr<Kernel::ServiceThread> service_thread); | 238 | void ReleaseServiceThread(std::weak_ptr<Kernel::ServiceThread> service_thread); |
| 239 | 239 | ||
| 240 | /// Workaround for single-core mode when preempting threads while idle. | ||
| 241 | bool IsPhantomModeForSingleCore() const; | ||
| 242 | void SetIsPhantomModeForSingleCore(bool value); | ||
| 243 | |||
| 240 | private: | 244 | private: |
| 241 | friend class Object; | 245 | friend class Object; |
| 242 | friend class Process; | 246 | friend class Process; |