utimer: Add TimerType_OneShot

This commit is contained in:
plutooo 2018-12-13 02:52:02 +01:00 committed by fincs
parent 0c0261bf2f
commit 68b4d323a0
3 changed files with 23 additions and 9 deletions

View File

@ -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.

View File

@ -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);
}

View File

@ -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;
}