| 
									
										
										
										
											2018-05-01 22:21:38 -04:00
										 |  |  | // Copyright 2018 yuzu emulator team
 | 
					
						
							|  |  |  | // Licensed under GPLv2 or any later version
 | 
					
						
							|  |  |  | // Refer to the license.txt file included.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #pragma once
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-03 00:16:12 -04:00
										 |  |  | #include <atomic>
 | 
					
						
							| 
									
										
										
										
											2018-05-02 21:26:14 -04:00
										 |  |  | #include <condition_variable>
 | 
					
						
							| 
									
										
										
										
											2018-05-01 22:21:38 -04:00
										 |  |  | #include <memory>
 | 
					
						
							| 
									
										
										
										
											2018-05-02 21:26:14 -04:00
										 |  |  | #include <mutex>
 | 
					
						
							| 
									
										
										
										
											2018-05-01 22:21:38 -04:00
										 |  |  | #include <string>
 | 
					
						
							|  |  |  | #include "common/common_types.h"
 | 
					
						
							| 
									
										
										
										
											2018-07-03 14:28:46 +01:00
										 |  |  | #include "core/arm/exclusive_monitor.h"
 | 
					
						
							| 
									
										
										
										
											2018-05-01 22:21:38 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | class ARM_Interface; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | namespace Kernel { | 
					
						
							|  |  |  | class Scheduler; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | namespace Core { | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-02 21:26:14 -04:00
										 |  |  | constexpr unsigned NUM_CPU_CORES{4}; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class CpuBarrier { | 
					
						
							|  |  |  | public: | 
					
						
							| 
									
										
										
										
											2018-05-03 00:16:12 -04:00
										 |  |  |     bool IsAlive() const { | 
					
						
							|  |  |  |         return !end; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2018-05-02 21:26:14 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-03 00:16:12 -04:00
										 |  |  |     void NotifyEnd(); | 
					
						
							| 
									
										
										
										
											2018-05-02 21:26:14 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-03 00:16:12 -04:00
										 |  |  |     bool Rendezvous(); | 
					
						
							| 
									
										
										
										
											2018-05-02 21:26:14 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | private: | 
					
						
							|  |  |  |     unsigned cores_waiting{NUM_CPU_CORES}; | 
					
						
							|  |  |  |     std::mutex mutex; | 
					
						
							|  |  |  |     std::condition_variable condition; | 
					
						
							| 
									
										
										
										
											2018-05-03 00:16:12 -04:00
										 |  |  |     std::atomic<bool> end{}; | 
					
						
							| 
									
										
										
										
											2018-05-02 21:26:14 -04:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-01 22:21:38 -04:00
										 |  |  | class Cpu { | 
					
						
							|  |  |  | public: | 
					
						
							| 
									
										
										
										
											2018-07-03 14:28:46 +01:00
										 |  |  |     Cpu(std::shared_ptr<ExclusiveMonitor> exclusive_monitor, | 
					
						
							|  |  |  |         std::shared_ptr<CpuBarrier> cpu_barrier, size_t core_index); | 
					
						
							| 
									
										
										
										
											2018-05-01 22:21:38 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |     void RunLoop(bool tight_loop = true); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     void SingleStep(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     void PrepareReschedule(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-02 22:36:51 -04:00
										 |  |  |     ARM_Interface& ArmInterface() { | 
					
						
							| 
									
										
										
										
											2018-05-01 22:21:38 -04:00
										 |  |  |         return *arm_interface; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-02 22:36:51 -04:00
										 |  |  |     const ARM_Interface& ArmInterface() const { | 
					
						
							|  |  |  |         return *arm_interface; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     const std::shared_ptr<Kernel::Scheduler>& Scheduler() const { | 
					
						
							|  |  |  |         return scheduler; | 
					
						
							| 
									
										
										
										
											2018-05-01 22:21:38 -04:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-02 21:26:14 -04:00
										 |  |  |     bool IsMainCore() const { | 
					
						
							|  |  |  |         return core_index == 0; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-03 14:28:46 +01:00
										 |  |  |     size_t CoreIndex() const { | 
					
						
							|  |  |  |         return core_index; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     static std::shared_ptr<ExclusiveMonitor> MakeExclusiveMonitor(size_t num_cores); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-01 22:21:38 -04:00
										 |  |  | private: | 
					
						
							|  |  |  |     void Reschedule(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     std::shared_ptr<ARM_Interface> arm_interface; | 
					
						
							| 
									
										
										
										
											2018-05-02 21:26:14 -04:00
										 |  |  |     std::shared_ptr<CpuBarrier> cpu_barrier; | 
					
						
							| 
									
										
										
										
											2018-05-02 22:36:51 -04:00
										 |  |  |     std::shared_ptr<Kernel::Scheduler> scheduler; | 
					
						
							| 
									
										
										
										
											2018-05-01 22:21:38 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |     bool reschedule_pending{}; | 
					
						
							| 
									
										
										
										
											2018-05-02 21:26:14 -04:00
										 |  |  |     size_t core_index; | 
					
						
							| 
									
										
										
										
											2018-05-01 22:21:38 -04:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | } // namespace Core
 |