summaryrefslogtreecommitdiff
path: root/src/core/hle/kernel/timer.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/hle/kernel/timer.cpp')
-rw-r--r--src/core/hle/kernel/timer.cpp39
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
60void Timer::Cancel() { 65void Timer::Cancel() {
@@ -72,6 +77,20 @@ void Timer::WakeupAllWaitingThreads() {
72 signaled = false; 77 signaled = false;
73} 78}
74 79
80void 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
76static void TimerCallback(u64 timer_handle, int cycles_late) { 95static 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
100void TimersInit() { 107void TimersInit() {