mirror of
				https://github.com/PabloMK7/citra.git
				synced 2025-10-30 21:30:04 +00:00 
			
		
		
		
	ArmInterface: return ref instead of copy for GetTimer (#5227)
* ArmInterface: return ref instead of copy for GetTimer * ArmInterface: add const ref GetTimer * ArmInterface: return raw pointer instead of shared_ptr in GetTimer * remove more unnecessary shared_ptr usage * Fix save states * fix unit tests
This commit is contained in:
		
							parent
							
								
									38c3c9c74b
								
							
						
					
					
						commit
						39463f1f6d
					
				
					 9 changed files with 46 additions and 32 deletions
				
			
		|  | @ -228,8 +228,12 @@ public: | ||||||
| 
 | 
 | ||||||
|     virtual void PurgeState() = 0; |     virtual void PurgeState() = 0; | ||||||
| 
 | 
 | ||||||
|     std::shared_ptr<Core::Timing::Timer> GetTimer() { |     Core::Timing::Timer& GetTimer() { | ||||||
|         return timer; |         return *timer; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     const Core::Timing::Timer& GetTimer() const { | ||||||
|  |         return *timer; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     u32 GetID() const { |     u32 GetID() const { | ||||||
|  |  | ||||||
|  | @ -137,10 +137,10 @@ public: | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     void AddTicks(std::uint64_t ticks) override { |     void AddTicks(std::uint64_t ticks) override { | ||||||
|         parent.GetTimer()->AddTicks(ticks); |         parent.GetTimer().AddTicks(ticks); | ||||||
|     } |     } | ||||||
|     std::uint64_t GetTicksRemaining() override { |     std::uint64_t GetTicksRemaining() override { | ||||||
|         s64 ticks = parent.GetTimer()->GetDowncount(); |         s64 ticks = parent.GetTimer().GetDowncount(); | ||||||
|         return static_cast<u64>(ticks <= 0 ? 0 : ticks); |         return static_cast<u64>(ticks <= 0 ? 0 : ticks); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -3865,7 +3865,7 @@ SWI_INST : { | ||||||
|     if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) { |     if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) { | ||||||
|         DEBUG_ASSERT(cpu->system != nullptr); |         DEBUG_ASSERT(cpu->system != nullptr); | ||||||
|         swi_inst* const inst_cream = (swi_inst*)inst_base->component; |         swi_inst* const inst_cream = (swi_inst*)inst_base->component; | ||||||
|         cpu->system->GetRunningCore().GetTimer()->AddTicks(num_instrs); |         cpu->system->GetRunningCore().GetTimer().AddTicks(num_instrs); | ||||||
|         cpu->NumInstrsToExecute = |         cpu->NumInstrsToExecute = | ||||||
|             num_instrs >= cpu->NumInstrsToExecute ? 0 : cpu->NumInstrsToExecute - num_instrs; |             num_instrs >= cpu->NumInstrsToExecute ? 0 : cpu->NumInstrsToExecute - num_instrs; | ||||||
|         num_instrs = 0; |         num_instrs = 0; | ||||||
|  |  | ||||||
|  | @ -144,14 +144,14 @@ System::ResultStatus System::RunLoop(bool tight_loop) { | ||||||
|     // So we have to get those cores to the same global time first
 |     // So we have to get those cores to the same global time first
 | ||||||
|     u64 global_ticks = timing->GetGlobalTicks(); |     u64 global_ticks = timing->GetGlobalTicks(); | ||||||
|     s64 max_delay = 0; |     s64 max_delay = 0; | ||||||
|     std::shared_ptr<ARM_Interface> current_core_to_execute = nullptr; |     ARM_Interface* current_core_to_execute = nullptr; | ||||||
|     for (auto& cpu_core : cpu_cores) { |     for (auto& cpu_core : cpu_cores) { | ||||||
|         if (cpu_core->GetTimer()->GetTicks() < global_ticks) { |         if (cpu_core->GetTimer().GetTicks() < global_ticks) { | ||||||
|             s64 delay = global_ticks - cpu_core->GetTimer()->GetTicks(); |             s64 delay = global_ticks - cpu_core->GetTimer().GetTicks(); | ||||||
|             cpu_core->GetTimer()->Advance(delay); |             cpu_core->GetTimer().Advance(delay); | ||||||
|             if (max_delay < delay) { |             if (max_delay < delay) { | ||||||
|                 max_delay = delay; |                 max_delay = delay; | ||||||
|                 current_core_to_execute = cpu_core; |                 current_core_to_execute = cpu_core.get(); | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  | @ -159,12 +159,14 @@ System::ResultStatus System::RunLoop(bool tight_loop) { | ||||||
|     if (max_delay > 0) { |     if (max_delay > 0) { | ||||||
|         LOG_TRACE(Core_ARM11, "Core {} running (delayed) for {} ticks", |         LOG_TRACE(Core_ARM11, "Core {} running (delayed) for {} ticks", | ||||||
|                   current_core_to_execute->GetID(), |                   current_core_to_execute->GetID(), | ||||||
|                   current_core_to_execute->GetTimer()->GetDowncount()); |                   current_core_to_execute->GetTimer().GetDowncount()); | ||||||
|         running_core = current_core_to_execute.get(); |         if (running_core != current_core_to_execute) { | ||||||
|         kernel->SetRunningCPU(current_core_to_execute); |             running_core = current_core_to_execute; | ||||||
|  |             kernel->SetRunningCPU(running_core); | ||||||
|  |         } | ||||||
|         if (kernel->GetCurrentThreadManager().GetCurrentThread() == nullptr) { |         if (kernel->GetCurrentThreadManager().GetCurrentThread() == nullptr) { | ||||||
|             LOG_TRACE(Core_ARM11, "Core {} idling", current_core_to_execute->GetID()); |             LOG_TRACE(Core_ARM11, "Core {} idling", current_core_to_execute->GetID()); | ||||||
|             current_core_to_execute->GetTimer()->Idle(); |             current_core_to_execute->GetTimer().Idle(); | ||||||
|             PrepareReschedule(); |             PrepareReschedule(); | ||||||
|         } else { |         } else { | ||||||
|             if (tight_loop) { |             if (tight_loop) { | ||||||
|  | @ -179,21 +181,21 @@ System::ResultStatus System::RunLoop(bool tight_loop) { | ||||||
|         // TODO: Make special check for idle since we can easily revert the time of idle cores
 |         // TODO: Make special check for idle since we can easily revert the time of idle cores
 | ||||||
|         s64 max_slice = Timing::MAX_SLICE_LENGTH; |         s64 max_slice = Timing::MAX_SLICE_LENGTH; | ||||||
|         for (const auto& cpu_core : cpu_cores) { |         for (const auto& cpu_core : cpu_cores) { | ||||||
|             max_slice = std::min(max_slice, cpu_core->GetTimer()->GetMaxSliceLength()); |             max_slice = std::min(max_slice, cpu_core->GetTimer().GetMaxSliceLength()); | ||||||
|         } |         } | ||||||
|         for (auto& cpu_core : cpu_cores) { |         for (auto& cpu_core : cpu_cores) { | ||||||
|             cpu_core->GetTimer()->Advance(max_slice); |             cpu_core->GetTimer().Advance(max_slice); | ||||||
|         } |         } | ||||||
|         for (auto& cpu_core : cpu_cores) { |         for (auto& cpu_core : cpu_cores) { | ||||||
|             LOG_TRACE(Core_ARM11, "Core {} running for {} ticks", cpu_core->GetID(), |             LOG_TRACE(Core_ARM11, "Core {} running for {} ticks", cpu_core->GetID(), | ||||||
|                       cpu_core->GetTimer()->GetDowncount()); |                       cpu_core->GetTimer().GetDowncount()); | ||||||
|             running_core = cpu_core.get(); |             running_core = cpu_core.get(); | ||||||
|             kernel->SetRunningCPU(cpu_core); |             kernel->SetRunningCPU(running_core); | ||||||
|             // If we don't have a currently active thread then don't execute instructions,
 |             // If we don't have a currently active thread then don't execute instructions,
 | ||||||
|             // instead advance to the next event and try to yield to the next thread
 |             // instead advance to the next event and try to yield to the next thread
 | ||||||
|             if (kernel->GetCurrentThreadManager().GetCurrentThread() == nullptr) { |             if (kernel->GetCurrentThreadManager().GetCurrentThread() == nullptr) { | ||||||
|                 LOG_TRACE(Core_ARM11, "Core {} idling", cpu_core->GetID()); |                 LOG_TRACE(Core_ARM11, "Core {} idling", cpu_core->GetID()); | ||||||
|                 cpu_core->GetTimer()->Idle(); |                 cpu_core->GetTimer().Idle(); | ||||||
|                 PrepareReschedule(); |                 PrepareReschedule(); | ||||||
|             } else { |             } else { | ||||||
|                 if (tight_loop) { |                 if (tight_loop) { | ||||||
|  | @ -371,7 +373,7 @@ System::ResultStatus System::Init(Frontend::EmuWindow& emu_window, u32 system_mo | ||||||
|     running_core = cpu_cores[0].get(); |     running_core = cpu_cores[0].get(); | ||||||
| 
 | 
 | ||||||
|     kernel->SetCPUs(cpu_cores); |     kernel->SetCPUs(cpu_cores); | ||||||
|     kernel->SetRunningCPU(cpu_cores[0]); |     kernel->SetRunningCPU(cpu_cores[0].get()); | ||||||
| 
 | 
 | ||||||
|     if (Settings::values.enable_dsp_lle) { |     if (Settings::values.enable_dsp_lle) { | ||||||
|         dsp_core = std::make_unique<AudioCore::DspLle>(*memory, |         dsp_core = std::make_unique<AudioCore::DspLle>(*memory, | ||||||
|  |  | ||||||
|  | @ -26,7 +26,7 @@ Timing::Timing(std::size_t num_cores, u32 cpu_clock_percentage) { | ||||||
|         timers[i] = std::make_shared<Timer>(); |         timers[i] = std::make_shared<Timer>(); | ||||||
|     } |     } | ||||||
|     UpdateClockSpeed(cpu_clock_percentage); |     UpdateClockSpeed(cpu_clock_percentage); | ||||||
|     current_timer = timers[0]; |     current_timer = timers[0].get(); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void Timing::UpdateClockSpeed(u32 cpu_clock_percentage) { | void Timing::UpdateClockSpeed(u32 cpu_clock_percentage) { | ||||||
|  | @ -50,12 +50,12 @@ TimingEventType* Timing::RegisterEvent(const std::string& name, TimedCallback ca | ||||||
| void Timing::ScheduleEvent(s64 cycles_into_future, const TimingEventType* event_type, u64 userdata, | void Timing::ScheduleEvent(s64 cycles_into_future, const TimingEventType* event_type, u64 userdata, | ||||||
|                            std::size_t core_id) { |                            std::size_t core_id) { | ||||||
|     ASSERT(event_type != nullptr); |     ASSERT(event_type != nullptr); | ||||||
|     std::shared_ptr<Timing::Timer> timer; |     Timing::Timer* timer = nullptr; | ||||||
|     if (core_id == std::numeric_limits<std::size_t>::max()) { |     if (core_id == std::numeric_limits<std::size_t>::max()) { | ||||||
|         timer = current_timer; |         timer = current_timer; | ||||||
|     } else { |     } else { | ||||||
|         ASSERT(core_id < timers.size()); |         ASSERT(core_id < timers.size()); | ||||||
|         timer = timers.at(core_id); |         timer = timers.at(core_id).get(); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     s64 timeout = timer->GetTicks() + cycles_into_future; |     s64 timeout = timer->GetTicks() + cycles_into_future; | ||||||
|  | @ -103,7 +103,7 @@ void Timing::RemoveEvent(const TimingEventType* event_type) { | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void Timing::SetCurrentTimer(std::size_t core_id) { | void Timing::SetCurrentTimer(std::size_t core_id) { | ||||||
|     current_timer = timers[core_id]; |     current_timer = timers[core_id].get(); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| s64 Timing::GetTicks() const { | s64 Timing::GetTicks() const { | ||||||
|  |  | ||||||
|  | @ -281,20 +281,28 @@ private: | ||||||
|     std::unordered_map<std::string, TimingEventType> event_types = {}; |     std::unordered_map<std::string, TimingEventType> event_types = {}; | ||||||
| 
 | 
 | ||||||
|     std::vector<std::shared_ptr<Timer>> timers; |     std::vector<std::shared_ptr<Timer>> timers; | ||||||
|     std::shared_ptr<Timer> current_timer; |     Timer* current_timer = nullptr; | ||||||
| 
 | 
 | ||||||
|     // Stores a scaling for the internal clockspeed. Changing this number results in
 |     // Stores a scaling for the internal clockspeed. Changing this number results in
 | ||||||
|     // under/overclocking the guest cpu
 |     // under/overclocking the guest cpu
 | ||||||
|     double cpu_clock_scale = 1.0; |     double cpu_clock_scale = 1.0; | ||||||
| 
 | 
 | ||||||
|     template <class Archive> |     template <class Archive> | ||||||
|     void serialize(Archive& ar, const unsigned int) { |     void serialize(Archive& ar, const unsigned int file_version) { | ||||||
|         // event_types set during initialization of other things
 |         // event_types set during initialization of other things
 | ||||||
|         ar& global_timer; |         ar& global_timer; | ||||||
|         ar& timers; |         ar& timers; | ||||||
|         ar& current_timer; |         if (file_version == 0) { | ||||||
|  |             std::shared_ptr<Timer> x; | ||||||
|  |             ar& x; | ||||||
|  |             current_timer = x.get(); | ||||||
|  |         } else { | ||||||
|  |             ar& current_timer; | ||||||
|  |         } | ||||||
|     } |     } | ||||||
|     friend class boost::serialization::access; |     friend class boost::serialization::access; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| } // namespace Core
 | } // namespace Core
 | ||||||
|  | 
 | ||||||
|  | BOOST_CLASS_VERSION(Core::Timing, 1) | ||||||
|  |  | ||||||
|  | @ -93,7 +93,7 @@ void KernelSystem::SetCPUs(std::vector<std::shared_ptr<ARM_Interface>> cpus) { | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void KernelSystem::SetRunningCPU(std::shared_ptr<ARM_Interface> cpu) { | void KernelSystem::SetRunningCPU(ARM_Interface* cpu) { | ||||||
|     if (current_process) { |     if (current_process) { | ||||||
|         stored_processes[current_cpu->GetID()] = current_process; |         stored_processes[current_cpu->GetID()] = current_process; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  | @ -218,7 +218,7 @@ public: | ||||||
| 
 | 
 | ||||||
|     void SetCPUs(std::vector<std::shared_ptr<ARM_Interface>> cpu); |     void SetCPUs(std::vector<std::shared_ptr<ARM_Interface>> cpu); | ||||||
| 
 | 
 | ||||||
|     void SetRunningCPU(std::shared_ptr<ARM_Interface> cpu); |     void SetRunningCPU(ARM_Interface* cpu); | ||||||
| 
 | 
 | ||||||
|     ThreadManager& GetThreadManager(u32 core_id); |     ThreadManager& GetThreadManager(u32 core_id); | ||||||
|     const ThreadManager& GetThreadManager(u32 core_id) const; |     const ThreadManager& GetThreadManager(u32 core_id) const; | ||||||
|  | @ -257,7 +257,7 @@ public: | ||||||
|     /// Map of named ports managed by the kernel, which can be retrieved using the ConnectToPort
 |     /// Map of named ports managed by the kernel, which can be retrieved using the ConnectToPort
 | ||||||
|     std::unordered_map<std::string, std::shared_ptr<ClientPort>> named_ports; |     std::unordered_map<std::string, std::shared_ptr<ClientPort>> named_ports; | ||||||
| 
 | 
 | ||||||
|     std::shared_ptr<ARM_Interface> current_cpu; |     ARM_Interface* current_cpu = nullptr; | ||||||
| 
 | 
 | ||||||
|     Memory::MemorySystem& memory; |     Memory::MemorySystem& memory; | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -1254,10 +1254,10 @@ void SVC::SleepThread(s64 nanoseconds) { | ||||||
| /// This returns the total CPU ticks elapsed since the CPU was powered-on
 | /// This returns the total CPU ticks elapsed since the CPU was powered-on
 | ||||||
| s64 SVC::GetSystemTick() { | s64 SVC::GetSystemTick() { | ||||||
|     // TODO: Use globalTicks here?
 |     // TODO: Use globalTicks here?
 | ||||||
|     s64 result = system.GetRunningCore().GetTimer()->GetTicks(); |     s64 result = system.GetRunningCore().GetTimer().GetTicks(); | ||||||
|     // Advance time to defeat dumb games (like Cubic Ninja) that busy-wait for the frame to end.
 |     // Advance time to defeat dumb games (like Cubic Ninja) that busy-wait for the frame to end.
 | ||||||
|     // Measured time between two calls on a 9.2 o3DS with Ninjhax 1.1b
 |     // Measured time between two calls on a 9.2 o3DS with Ninjhax 1.1b
 | ||||||
|     system.GetRunningCore().GetTimer()->AddTicks(150); |     system.GetRunningCore().GetTimer().AddTicks(150); | ||||||
|     return result; |     return result; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue