mirror of
				https://git.zaroz.cloud/nintendo-back-up/yuzu/yuzu-mainline.git
				synced 2025-03-21 01:53:15 +00:00 
			
		
		
		
	Kernel: Initial implementation of thread preemption.
This commit is contained in:
		
							parent
							
								
									103f3a2fe5
								
							
						
					
					
						commit
						b49c0dab87
					
				| @ -12,6 +12,7 @@ | ||||
| 
 | ||||
| #include "core/core.h" | ||||
| #include "core/core_timing.h" | ||||
| #include "core/core_timing_util.h" | ||||
| #include "core/hle/kernel/address_arbiter.h" | ||||
| #include "core/hle/kernel/client_port.h" | ||||
| #include "core/hle/kernel/handle_table.h" | ||||
| @ -96,6 +97,7 @@ struct KernelCore::Impl { | ||||
| 
 | ||||
|         InitializeSystemResourceLimit(kernel); | ||||
|         InitializeThreads(); | ||||
|         InitializePreemption(); | ||||
|     } | ||||
| 
 | ||||
|     void Shutdown() { | ||||
| @ -111,6 +113,7 @@ struct KernelCore::Impl { | ||||
| 
 | ||||
|         thread_wakeup_callback_handle_table.Clear(); | ||||
|         thread_wakeup_event_type = nullptr; | ||||
|         preemption_event = nullptr; | ||||
| 
 | ||||
|         named_ports.clear(); | ||||
|     } | ||||
| @ -133,6 +136,18 @@ struct KernelCore::Impl { | ||||
|             system.CoreTiming().RegisterEvent("ThreadWakeupCallback", ThreadWakeupCallback); | ||||
|     } | ||||
| 
 | ||||
|     void InitializePreemption() { | ||||
|         preemption_event = system.CoreTiming().RegisterEvent( | ||||
|             "PreemptionCallback", [this](u64 userdata, s64 cycles_late) { | ||||
|                 global_scheduler.PreemptThreads(); | ||||
|                 s64 time_interval = Core::Timing::msToCycles(std::chrono::milliseconds(10)); | ||||
|                 system.CoreTiming().ScheduleEvent(time_interval, preemption_event); | ||||
|             }); | ||||
| 
 | ||||
|         s64 time_interval = Core::Timing::msToCycles(std::chrono::milliseconds(10)); | ||||
|         system.CoreTiming().ScheduleEvent(time_interval, preemption_event); | ||||
|     } | ||||
| 
 | ||||
|     std::atomic<u32> next_object_id{0}; | ||||
|     std::atomic<u64> next_kernel_process_id{Process::InitialKIPIDMin}; | ||||
|     std::atomic<u64> next_user_process_id{Process::ProcessIDMin}; | ||||
| @ -146,6 +161,7 @@ struct KernelCore::Impl { | ||||
|     SharedPtr<ResourceLimit> system_resource_limit; | ||||
| 
 | ||||
|     Core::Timing::EventType* thread_wakeup_event_type = nullptr; | ||||
|     Core::Timing::EventType* preemption_event = nullptr; | ||||
|     // TODO(yuriks): This can be removed if Thread objects are explicitly pooled in the future,
 | ||||
|     // allowing us to simply use a pool index or similar.
 | ||||
|     Kernel::HandleTable thread_wakeup_callback_handle_table; | ||||
|  | ||||
| @ -238,6 +238,16 @@ bool GlobalScheduler::YieldThreadAndWaitForLoadBalancing(Thread* yielding_thread | ||||
|     return AskForReselectionOrMarkRedundant(yielding_thread, winner); | ||||
| } | ||||
| 
 | ||||
| void GlobalScheduler::PreemptThreads() { | ||||
|     for (std::size_t core_id = 0; core_id < NUM_CPU_CORES; core_id++) { | ||||
|         const u64 priority = preemption_priorities[core_id]; | ||||
|         if (scheduled_queue[core_id].size(priority) > 1) { | ||||
|             scheduled_queue[core_id].yield(priority); | ||||
|             reselection_pending.store(true, std::memory_order_release); | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| void GlobalScheduler::Schedule(u32 priority, u32 core, Thread* thread) { | ||||
|     ASSERT_MSG(thread->GetProcessorID() == core, "Thread must be assigned to this core."); | ||||
|     scheduled_queue[core].add(thread, priority); | ||||
|  | ||||
| @ -133,6 +133,8 @@ public: | ||||
|      */ | ||||
|     bool YieldThreadAndWaitForLoadBalancing(Thread* thread); | ||||
| 
 | ||||
|     void PreemptThreads(); | ||||
| 
 | ||||
|     u32 CpuCoresCount() const { | ||||
|         return NUM_CPU_CORES; | ||||
|     } | ||||
| @ -153,6 +155,8 @@ private: | ||||
|     std::array<Common::MultiLevelQueue<Thread*, THREADPRIO_COUNT>, NUM_CPU_CORES> suggested_queue; | ||||
|     std::atomic<bool> reselection_pending; | ||||
| 
 | ||||
|     std::array<u64, NUM_CPU_CORES> preemption_priorities = {59, 59, 59, 62}; | ||||
| 
 | ||||
|     /// Lists all thread ids that aren't deleted/etc.
 | ||||
|     std::vector<SharedPtr<Thread>> thread_list; | ||||
|     Core::System& system; | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user
	 Fernando Sahmkow
						Fernando Sahmkow