diff options
Diffstat (limited to 'src/core/hle/kernel/timer.cpp')
| -rw-r--r-- | src/core/hle/kernel/timer.cpp | 39 |
1 files changed, 23 insertions, 16 deletions
diff --git a/src/core/hle/kernel/timer.cpp b/src/core/hle/kernel/timer.cpp index 60537f355..c42003e9d 100644 --- a/src/core/hle/kernel/timer.cpp +++ b/src/core/hle/kernel/timer.cpp | |||
| @@ -52,9 +52,14 @@ void Timer::Set(s64 initial, s64 interval) { | |||
| 52 | initial_delay = initial; | 52 | initial_delay = initial; |
| 53 | interval_delay = interval; | 53 | interval_delay = interval; |
| 54 | 54 | ||
| 55 | u64 initial_microseconds = initial / 1000; | 55 | if (initial == 0) { |
| 56 | CoreTiming::ScheduleEvent(usToCycles(initial_microseconds), timer_callback_event_type, | 56 | // Immediately invoke the callback |
| 57 | callback_handle); | 57 | Signal(0); |
| 58 | } else { | ||
| 59 | u64 initial_microseconds = initial / 1000; | ||
| 60 | CoreTiming::ScheduleEvent(usToCycles(initial_microseconds), timer_callback_event_type, | ||
| 61 | callback_handle); | ||
| 62 | } | ||
| 58 | } | 63 | } |
| 59 | 64 | ||
| 60 | void Timer::Cancel() { | 65 | void Timer::Cancel() { |
| @@ -72,6 +77,20 @@ void Timer::WakeupAllWaitingThreads() { | |||
| 72 | signaled = false; | 77 | signaled = false; |
| 73 | } | 78 | } |
| 74 | 79 | ||
| 80 | void Timer::Signal(int cycles_late) { | ||
| 81 | LOG_TRACE(Kernel, "Timer %08" PRIx64 " fired", timer_handle); | ||
| 82 | |||
| 83 | // Resume all waiting threads | ||
| 84 | WakeupAllWaitingThreads(); | ||
| 85 | |||
| 86 | if (interval_delay != 0) { | ||
| 87 | // Reschedule the timer with the interval delay | ||
| 88 | u64 interval_microseconds = interval_delay / 1000; | ||
| 89 | CoreTiming::ScheduleEvent(usToCycles(interval_microseconds) - cycles_late, | ||
| 90 | timer_callback_event_type, callback_handle); | ||
| 91 | } | ||
| 92 | } | ||
| 93 | |||
| 75 | /// The timer callback event, called when a timer is fired | 94 | /// The timer callback event, called when a timer is fired |
| 76 | static void TimerCallback(u64 timer_handle, int cycles_late) { | 95 | static void TimerCallback(u64 timer_handle, int cycles_late) { |
| 77 | SharedPtr<Timer> timer = | 96 | SharedPtr<Timer> timer = |
| @@ -82,19 +101,7 @@ static void TimerCallback(u64 timer_handle, int cycles_late) { | |||
| 82 | return; | 101 | return; |
| 83 | } | 102 | } |
| 84 | 103 | ||
| 85 | LOG_TRACE(Kernel, "Timer %08" PRIx64 " fired", timer_handle); | 104 | timer->Signal(cycles_late); |
| 86 | |||
| 87 | timer->signaled = true; | ||
| 88 | |||
| 89 | // Resume all waiting threads | ||
| 90 | timer->WakeupAllWaitingThreads(); | ||
| 91 | |||
| 92 | if (timer->interval_delay != 0) { | ||
| 93 | // Reschedule the timer with the interval delay | ||
| 94 | u64 interval_microseconds = timer->interval_delay / 1000; | ||
| 95 | CoreTiming::ScheduleEvent(usToCycles(interval_microseconds) - cycles_late, | ||
| 96 | timer_callback_event_type, timer_handle); | ||
| 97 | } | ||
| 98 | } | 105 | } |
| 99 | 106 | ||
| 100 | void TimersInit() { | 107 | void TimersInit() { |