libnx/nx/source/kernel/utimer.c

86 lines
1.9 KiB
C

// Copyright 2018 plutoo
#include "kernel/svc.h"
#include "kernel/utimer.h"
#include "arm/counter.h"
#include "utimer.h"
#include "wait.h"
#define STOPPED 0
void utimerCreate(UTimer* t, u64 interval, TimerType type)
{
_waitableInitialize(&t->waitable);
t->next_tick = STOPPED;
t->interval = armNsToTicks(interval);
t->type = type;
}
void utimerStart(UTimer* t)
{
mutexLock(&t->waitable.mutex);
if (t->next_tick == STOPPED) {
u64 new_tick = armGetSystemTick() + t->interval;
t->next_tick = new_tick;
_waitableSignalAllListeners(&t->waitable);
}
mutexUnlock(&t->waitable.mutex);
}
void utimerStop(UTimer* t)
{
mutexLock(&t->waitable.mutex);
if (t->next_tick != STOPPED) {
t->next_tick = STOPPED;
_waitableSignalAllListeners(&t->waitable);
}
mutexUnlock(&t->waitable.mutex);
}
void _utimerRecalculate(UTimer* t, u64 old_tick)
{
mutexLock(&t->waitable.mutex);
if (t->next_tick == old_tick) {
u64 interval = t->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;
}
mutexUnlock(&t->waitable.mutex);
}
u64 _utimerGetNextTick(UTimer* t)
{
u64 ret;
mutexLock(&t->waitable.mutex);
ret = t->next_tick;
mutexUnlock(&t->waitable.mutex);
return ret;
}
void _utimerAddListener(UTimer* t, WaiterNode* w, s32 idx, s32* idx_out, Handle thread)
{
_waiterNodeCreate(w, WaiterNodeType_Timer, &t->waitable, thread, idx, idx_out);
mutexLock(&t->waitable.mutex);
_waiterNodeAddToWaitable(w, &t->waitable);
mutexUnlock(&t->waitable.mutex);
}