mirror of
				https://github.com/yuzu-emu/yuzu-mainline.git
				synced 2025-11-04 14:34:59 +00:00 
			
		
		
		
	hle: kernel: Move single core "phantom mode" out of KThread.
- This is a workaround that does not belong in a kernel primitive.
This commit is contained in:
		
							parent
							
								
									eea346ba8e
								
							
						
					
					
						commit
						4782985013
					
				| 
						 | 
				
			
			@ -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());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in a new issue