You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
MultiTimer/MultiTimer.c

92 lines
2.6 KiB
C

#include "MultiTimer.h"
#include <stdio.h>
#define MULTIMER_MAX_TIMEOUT 0x7fffffff
/* Check if timer's expiry time is greater than time and care about uint32_t wraparounds */
#define CHECK_TIME_LESS_THAN(t, compare_to) ( (((uint32_t)((t)-(compare_to))) > MULTIMER_MAX_TIMEOUT) ? 1 : 0 )
/* Timer handle list head. */
static MultiTimer* timerList = NULL;
/* Timer tick */
static PlatformTicksFunction_t platformTicksFunction = NULL;
int MultiTimerInstall(PlatformTicksFunction_t ticksFunc)
{
platformTicksFunction = ticksFunc;
return 0;
}
int MultiTimerStart(MultiTimer* timer, uint32_t timing, MultiTimerCallback_t callback, void* userData)
{
if (!timer || !callback || timing > MULTIMER_MAX_TIMEOUT) {
return -1;
}
MultiTimer** nextTimer = &timerList;
/* Remove the existing target timer. */
for (; *nextTimer; nextTimer = &(*nextTimer)->next) {
if (timer == *nextTimer) {
*nextTimer = timer->next; /* remove from list */
break;
}
}
/* Init timer. */
timer->deadline = platformTicksFunction() + timing;
timer->callback = callback;
timer->userData = userData;
/* Insert timer. */
for (nextTimer = &timerList;; nextTimer = &(*nextTimer)->next) {
if (!*nextTimer) {
timer->next = NULL;
*nextTimer = timer;
break;
}
if (timer->deadline < (*nextTimer)->deadline) {
timer->next = *nextTimer;
*nextTimer = timer;
break;
}
}
return 0;
}
int MultiTimerStop(MultiTimer* timer)
{
MultiTimer** nextTimer = &timerList;
/* Find and remove timer. */
for (; *nextTimer; nextTimer = &(*nextTimer)->next) {
MultiTimer* entry = *nextTimer;
if (entry == timer) {
*nextTimer = timer->next;
break;
}
}
return 0;
}
int MultiTimerYield(void)
{
MultiTimer** nextTimer = &timerList;
for (; *nextTimer; nextTimer = &(*nextTimer)->next) {
MultiTimer* entry = *nextTimer;
/* Sorted list, just process with the front part. */
if (CHECK_TIME_LESS_THAN(platformTicksFunction(), entry->deadline)) {
return (int)(entry->deadline - platformTicksFunction());
}
/* remove expired timer from list */
*nextTimer = entry->next;
/* call callback */
if (entry->callback) {
entry->callback(entry, entry->userData);
}
if (entry->next == NULL) {
return 0;
}
}
return 0;
}