From 68b4d323a0a34b4416ca3500ba75028facec1996 Mon Sep 17 00:00:00 2001 From: plutooo Date: Thu, 13 Dec 2018 02:52:02 +0100 Subject: [PATCH] utimer: Add TimerType_OneShot --- nx/include/switch/kernel/utimer.h | 12 +++++++++--- nx/source/kernel/uevent.c | 2 +- nx/source/kernel/utimer.c | 18 +++++++++++++----- 3 files changed, 23 insertions(+), 9 deletions(-) diff --git a/nx/include/switch/kernel/utimer.h b/nx/include/switch/kernel/utimer.h index b8d69283..280c11d3 100644 --- a/nx/include/switch/kernel/utimer.h +++ b/nx/include/switch/kernel/utimer.h @@ -4,9 +4,15 @@ typedef struct UsermodeTimer UsermodeTimer; +typedef enum { + TimerType_OneShot, + TimerType_Repeating +} TimerType; + struct UsermodeTimer { Waitable waitable; + TimerType type; u64 next_tick; u64 interval; }; @@ -15,12 +21,12 @@ struct UsermodeTimer * @brief Creates a usermode timer. * @param[out] t UsermodeTimer object. * @param[in] interval Interval (in nanoseconds). - * @param[in] start Whether to start the timer right away. + * @param[in] type Timer type (repeating or one-shot) * @note It is safe to wait on this timer with several threads simultaneously. * @note If more than one thread is listening on it, at least one thread will get the signal. No other guarantees. - * @note If the timer triggers twice before you wait on it, you will only get one signal. + * @note For a repeating timer: If the timer triggers twice before you wait on it, you will only get one signal. */ -void utimerCreate(UsermodeTimer* t, u64 interval, bool start); +void utimerCreate(UsermodeTimer* t, u64 interval, TimerType type); /** * @brief Starts the timer. * @param[in] t UsermodeTimer object. diff --git a/nx/source/kernel/uevent.c b/nx/source/kernel/uevent.c index 9ac277ed..05d14969 100644 --- a/nx/source/kernel/uevent.c +++ b/nx/source/kernel/uevent.c @@ -32,7 +32,7 @@ void _ueventTryAutoClear(UsermodeEvent* e) { mutexLock(&e->waitable.mutex); if (e->auto_clear) { - e->signal = true; + e->signal = false; } mutexUnlock(&e->waitable.mutex); } diff --git a/nx/source/kernel/utimer.c b/nx/source/kernel/utimer.c index 332bbbf7..f2307b2b 100644 --- a/nx/source/kernel/utimer.c +++ b/nx/source/kernel/utimer.c @@ -7,15 +7,13 @@ #define STOPPED 0 -void utimerCreate(UsermodeTimer* t, u64 interval, bool start) +void utimerCreate(UsermodeTimer* t, u64 interval, TimerType type) { _waitableInitialize(&t->waitable); t->next_tick = STOPPED; t->interval = armNsToTicks(interval); - - if (start) - utimerStart(t); + t->type = type; } void utimerStart(UsermodeTimer* t) @@ -52,7 +50,17 @@ void _utimerRecalculate(UsermodeTimer* t, u64 old_tick) if (t->next_tick == old_tick) { u64 interval = t->interval; - u64 new_tick = old_tick + ((svcGetSystemTick() - old_tick + interval - 1)/interval)*interval; + u64 new_tick = 0; + + switch (t->type) + { + case TimerType_OneShot: + new_tick = STOPPED; + break; + case TimerType_Repeating: + new_tick = old_tick + ((svcGetSystemTick() - old_tick + interval - 1)/interval)*interval; + break; + } t->next_tick = new_tick; }