diff options
Diffstat (limited to 'src/core/hle/kernel')
| -rw-r--r-- | src/core/hle/kernel/timer.cpp | 39 | ||||
| -rw-r--r-- | src/core/hle/kernel/timer.h | 8 | 
2 files changed, 31 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) {      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() { diff --git a/src/core/hle/kernel/timer.h b/src/core/hle/kernel/timer.h index c174f5664..b0f818933 100644 --- a/src/core/hle/kernel/timer.h +++ b/src/core/hle/kernel/timer.h @@ -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; | 
