mirror of
				https://github.com/PabloMK7/citra.git
				synced 2025-10-31 13:50:03 +00:00 
			
		
		
		
	Merge pull request #2421 from Subv/timers
Timers: Immediately signal the timer if it was started with an initial value of 0
This commit is contained in:
		
						commit
						fb5301cf6e
					
				
					 3 changed files with 36 additions and 16 deletions
				
			
		|  | @ -52,9 +52,14 @@ void Timer::Set(s64 initial, s64 interval) { | |||
|     initial_delay = initial; | ||||
|     interval_delay = interval; | ||||
| 
 | ||||
|     u64 initial_microseconds = initial / 1000; | ||||
|     CoreTiming::ScheduleEvent(usToCycles(initial_microseconds), timer_callback_event_type, | ||||
|                               callback_handle); | ||||
|     if (initial == 0) { | ||||
|         // Immediately invoke the callback
 | ||||
|         Signal(0); | ||||
|     } else { | ||||
|         u64 initial_microseconds = initial / 1000; | ||||
|         CoreTiming::ScheduleEvent(usToCycles(initial_microseconds), timer_callback_event_type, | ||||
|                                   callback_handle); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| void Timer::Cancel() { | ||||
|  | @ -72,6 +77,20 @@ void Timer::WakeupAllWaitingThreads() { | |||
|         signaled = false; | ||||
| } | ||||
| 
 | ||||
| void Timer::Signal(int cycles_late) { | ||||
|     LOG_TRACE(Kernel, "Timer %08" PRIx64 " fired", timer_handle); | ||||
| 
 | ||||
|     // Resume all waiting threads
 | ||||
|     WakeupAllWaitingThreads(); | ||||
| 
 | ||||
|     if (interval_delay != 0) { | ||||
|         // Reschedule the timer with the interval delay
 | ||||
|         u64 interval_microseconds = interval_delay / 1000; | ||||
|         CoreTiming::ScheduleEvent(usToCycles(interval_microseconds) - cycles_late, | ||||
|                                   timer_callback_event_type, callback_handle); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| /// The timer callback event, called when a timer is fired
 | ||||
| static void TimerCallback(u64 timer_handle, int cycles_late) { | ||||
|     SharedPtr<Timer> timer = | ||||
|  | @ -82,19 +101,7 @@ static void TimerCallback(u64 timer_handle, int cycles_late) { | |||
|         return; | ||||
|     } | ||||
| 
 | ||||
|     LOG_TRACE(Kernel, "Timer %08" PRIx64 " fired", timer_handle); | ||||
| 
 | ||||
|     timer->signaled = true; | ||||
| 
 | ||||
|     // Resume all waiting threads
 | ||||
|     timer->WakeupAllWaitingThreads(); | ||||
| 
 | ||||
|     if (timer->interval_delay != 0) { | ||||
|         // Reschedule the timer with the interval delay
 | ||||
|         u64 interval_microseconds = timer->interval_delay / 1000; | ||||
|         CoreTiming::ScheduleEvent(usToCycles(interval_microseconds) - cycles_late, | ||||
|                                   timer_callback_event_type, timer_handle); | ||||
|     } | ||||
|     timer->Signal(cycles_late); | ||||
| } | ||||
| 
 | ||||
| void TimersInit() { | ||||
|  |  | |||
|  | @ -54,6 +54,14 @@ public: | |||
|     void Cancel(); | ||||
|     void Clear(); | ||||
| 
 | ||||
|     /**
 | ||||
|      * Signals the timer, waking up any waiting threads and rescheduling it | ||||
|      * for the next interval. | ||||
|      * This method should not be called from outside the timer callback handler, | ||||
|      * lest multiple callback events get scheduled. | ||||
|      */ | ||||
|     void Signal(int cycles_late); | ||||
| 
 | ||||
| private: | ||||
|     Timer(); | ||||
|     ~Timer() override; | ||||
|  |  | |||
|  | @ -837,6 +837,11 @@ static ResultCode SetTimer(Kernel::Handle handle, s64 initial, s64 interval) { | |||
| 
 | ||||
|     LOG_TRACE(Kernel_SVC, "called timer=0x%08X", handle); | ||||
| 
 | ||||
|     if (initial < 0 || interval < 0) { | ||||
|         return ResultCode(ErrorDescription::OutOfRange, ErrorModule::Kernel, | ||||
|                           ErrorSummary::InvalidArgument, ErrorLevel::Permanent); | ||||
|     } | ||||
| 
 | ||||
|     SharedPtr<Timer> timer = Kernel::g_handle_table.Get<Timer>(handle); | ||||
|     if (timer == nullptr) | ||||
|         return ERR_INVALID_HANDLE; | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue