Kernel: Implement Time Manager.
This commit is contained in:
		
				
					committed by
					
						 FernandoS27
						FernandoS27
					
				
			
			
				
	
			
			
			
						parent
						
							179bafa7cb
						
					
				
				
					commit
					5c90d22f3d
				
			| @@ -187,6 +187,8 @@ add_library(core STATIC | ||||
|     hle/kernel/synchronization.h | ||||
|     hle/kernel/thread.cpp | ||||
|     hle/kernel/thread.h | ||||
|     hle/kernel/time_manager.cpp | ||||
|     hle/kernel/time_manager.h | ||||
|     hle/kernel/transfer_memory.cpp | ||||
|     hle/kernel/transfer_memory.h | ||||
|     hle/kernel/vm_manager.cpp | ||||
|   | ||||
| @@ -27,6 +27,7 @@ | ||||
| #include "core/hle/kernel/scheduler.h" | ||||
| #include "core/hle/kernel/synchronization.h" | ||||
| #include "core/hle/kernel/thread.h" | ||||
| #include "core/hle/kernel/time_manager.h" | ||||
| #include "core/hle/lock.h" | ||||
| #include "core/hle/result.h" | ||||
| #include "core/memory.h" | ||||
| @@ -100,7 +101,7 @@ static void ThreadWakeupCallback(u64 thread_handle, [[maybe_unused]] s64 cycles_ | ||||
|  | ||||
| struct KernelCore::Impl { | ||||
|     explicit Impl(Core::System& system, KernelCore& kernel) | ||||
|         : system{system}, global_scheduler{kernel}, synchronization{system} {} | ||||
|         : system{system}, global_scheduler{kernel}, synchronization{system}, time_manager{system} {} | ||||
|  | ||||
|     void Initialize(KernelCore& kernel) { | ||||
|         Shutdown(); | ||||
| @@ -238,6 +239,7 @@ struct KernelCore::Impl { | ||||
|     Process* current_process = nullptr; | ||||
|     Kernel::GlobalScheduler global_scheduler; | ||||
|     Kernel::Synchronization synchronization; | ||||
|     Kernel::TimeManager time_manager; | ||||
|  | ||||
|     std::shared_ptr<ResourceLimit> system_resource_limit; | ||||
|  | ||||
| @@ -337,6 +339,14 @@ const Kernel::Synchronization& KernelCore::Synchronization() const { | ||||
|     return impl->synchronization; | ||||
| } | ||||
|  | ||||
| Kernel::TimeManager& KernelCore::TimeManager() { | ||||
|     return impl->time_manager; | ||||
| } | ||||
|  | ||||
| const Kernel::TimeManager& KernelCore::TimeManager() const { | ||||
|     return impl->time_manager; | ||||
| } | ||||
|  | ||||
| Core::ExclusiveMonitor& KernelCore::GetExclusiveMonitor() { | ||||
|     return *impl->exclusive_monitor; | ||||
| } | ||||
|   | ||||
| @@ -33,6 +33,7 @@ class ResourceLimit; | ||||
| class Scheduler; | ||||
| class Synchronization; | ||||
| class Thread; | ||||
| class TimeManager; | ||||
|  | ||||
| /// Represents a single instance of the kernel. | ||||
| class KernelCore { | ||||
| @@ -107,6 +108,12 @@ public: | ||||
|     /// Gets the an instance of the Synchronization Interface. | ||||
|     const Kernel::Synchronization& Synchronization() const; | ||||
|  | ||||
|     /// Gets the an instance of the TimeManager Interface. | ||||
|     Kernel::TimeManager& TimeManager(); | ||||
|  | ||||
|     /// Gets the an instance of the TimeManager Interface. | ||||
|     const Kernel::TimeManager& TimeManager() const; | ||||
|  | ||||
|     /// Stops execution of 'id' core, in order to reschedule a new thread. | ||||
|     void PrepareReschedule(std::size_t id); | ||||
|  | ||||
|   | ||||
							
								
								
									
										42
									
								
								src/core/hle/kernel/time_manager.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										42
									
								
								src/core/hle/kernel/time_manager.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,42 @@ | ||||
| // Copyright 2020 yuzu Emulator Project | ||||
| // Licensed under GPLv2 or any later version | ||||
| // Refer to the license.txt file included. | ||||
|  | ||||
| #include "core/core.h" | ||||
| #include "core/core_timing.h" | ||||
| #include "core/core_timing_util.h" | ||||
| #include "core/hle/kernel/handle_table.h" | ||||
| #include "core/hle/kernel/kernel.h" | ||||
| #include "core/hle/kernel/thread.h" | ||||
| #include "core/hle/kernel/time_manager.h" | ||||
|  | ||||
| namespace Kernel { | ||||
|  | ||||
| TimeManager::TimeManager(Core::System& system) : system{system} { | ||||
|     time_manager_event_type = Core::Timing::CreateEvent( | ||||
|         "Kernel::TimeManagerCallback", [this](u64 thread_handle, [[maybe_unused]] s64 cycles_late) { | ||||
|             Handle proper_handle = static_cast<Handle>(thread_handle); | ||||
|             std::shared_ptr<Thread> thread = | ||||
|                 this->system.Kernel().RetrieveThreadFromGlobalHandleTable(proper_handle); | ||||
|             thread->ResumeFromWait(); | ||||
|         }); | ||||
| } | ||||
|  | ||||
| void TimeManager::ScheduleTimeEvent(Handle& event_handle, Thread* timetask, s64 nanoseconds) { | ||||
|     if (nanoseconds > 0) { | ||||
|         ASSERT(timetask); | ||||
|         event_handle = timetask->GetGlobalHandle(); | ||||
|         const s64 cycles = Core::Timing::nsToCycles(std::chrono::nanoseconds{nanoseconds}); | ||||
|         system.CoreTiming().ScheduleEvent(cycles, time_manager_event_type, event_handle); | ||||
|     } else { | ||||
|         event_handle = InvalidHandle; | ||||
|     } | ||||
| } | ||||
|  | ||||
| void TimeManager::UnscheduleTimeEvent(Handle event_handle) { | ||||
|     if (event_handle != InvalidHandle) { | ||||
|         system.CoreTiming().UnscheduleEvent(time_manager_event_type, event_handle); | ||||
|     } | ||||
| } | ||||
|  | ||||
| } // namespace Kernel | ||||
							
								
								
									
										36
									
								
								src/core/hle/kernel/time_manager.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										36
									
								
								src/core/hle/kernel/time_manager.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,36 @@ | ||||
| // Copyright 2020 yuzu Emulator Project | ||||
| // Licensed under GPLv2 or any later version | ||||
| // Refer to the license.txt file included. | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| #include <memory> | ||||
|  | ||||
| #include "core/hle/kernel/object.h" | ||||
|  | ||||
| namespace Core { | ||||
| class System; | ||||
| } // namespace Core | ||||
|  | ||||
| namespace Core::Timing { | ||||
| struct EventType; | ||||
| } // namespace Core::Timing | ||||
|  | ||||
| namespace Kernel { | ||||
|  | ||||
| class Thread; | ||||
|  | ||||
| class TimeManager { | ||||
| public: | ||||
|     TimeManager(Core::System& system); | ||||
|  | ||||
|     void ScheduleTimeEvent(Handle& event_handle, Thread* timetask, s64 nanoseconds); | ||||
|  | ||||
|     void UnscheduleTimeEvent(Handle event_handle); | ||||
|  | ||||
| private: | ||||
|     Core::System& system; | ||||
|     std::shared_ptr<Core::Timing::EventType> time_manager_event_type; | ||||
| }; | ||||
|  | ||||
| } // namespace Kernel | ||||
		Reference in New Issue
	
	Block a user