From 73e1855b9de7530980a393594230e35a8a9078d2 Mon Sep 17 00:00:00 2001 From: 0x1abin <0x1abin@gmail.com> Date: Fri, 20 Aug 2021 16:02:46 +0800 Subject: [PATCH] Check if timer's expiry time is greater than time and care about uint32_t wraparounds. --- MultiTimer.c | 13 +++++++++---- MultiTimer.h | 4 ++-- examples/test_linux.c | 10 +++++----- 3 files changed, 16 insertions(+), 11 deletions(-) diff --git a/MultiTimer.c b/MultiTimer.c index 75de835..99d1d37 100644 --- a/MultiTimer.c +++ b/MultiTimer.c @@ -1,10 +1,15 @@ #include "MultiTimer.h" #include -// Timer handle list head. +#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 +/* Timer tick */ static PlatformTicksFunction_t platformTicksFunction = NULL; int MultiTimerInstall(PlatformTicksFunction_t ticksFunc) @@ -15,7 +20,7 @@ int MultiTimerInstall(PlatformTicksFunction_t ticksFunc) int MultiTimerStart(MultiTimer* timer, uint32_t timing, MultiTimerCallback_t callback, void* userData) { - if (!timer || !callback) { + if (!timer || !callback || timing > MULTIMER_MAX_TIMEOUT) { return -1; } MultiTimer** nextTimer = &timerList; @@ -68,7 +73,7 @@ int MultiTimerYield(void) for (; *nextTimer; nextTimer = &(*nextTimer)->next) { MultiTimer* entry = *nextTimer; /* Sorted list, just process with the front part. */ - if (entry->deadline > platformTicksFunction()) { + if (CHECK_TIME_LESS_THAN(platformTicksFunction(), entry->deadline)) { return (int)(entry->deadline - platformTicksFunction()); } /* remove expired timer from list */ diff --git a/MultiTimer.h b/MultiTimer.h index 60eb45f..23926ef 100644 --- a/MultiTimer.h +++ b/MultiTimer.h @@ -7,7 +7,7 @@ extern "C" { #endif -typedef uint64_t (*PlatformTicksFunction_t)(void); +typedef uint32_t (*PlatformTicksFunction_t)(void); typedef struct MultiTimerHandle MultiTimer; @@ -15,7 +15,7 @@ typedef void (*MultiTimerCallback_t)(MultiTimer* timer, void* userData); struct MultiTimerHandle { MultiTimer* next; - uint64_t deadline; + uint32_t deadline; MultiTimerCallback_t callback; void* userData; }; diff --git a/examples/test_linux.c b/examples/test_linux.c index 30ff5ad..d945b34 100755 --- a/examples/test_linux.c +++ b/examples/test_linux.c @@ -7,27 +7,27 @@ MultiTimer timer1; MultiTimer timer2; MultiTimer timer3; -uint64_t PlatformTicksGetFunc(void) +uint32_t PlatformTicksGetFunc(void) { struct timespec current_time; clock_gettime(CLOCK_MONOTONIC, ¤t_time); - return (uint64_t)((current_time.tv_sec * 1000) + (current_time.tv_nsec / 1000000)); + return (uint32_t)((current_time.tv_sec * 1000) + (current_time.tv_nsec / 1000000)); } void exampleTimer1Callback(MultiTimer* timer, void *userData) { - printf("[T:%012ld] Timer:%p callback-> %s.\r\n", PlatformTicksGetFunc(), timer, (char*)userData); + printf("[T:%010d] Timer:%p callback-> %s.\r\n", PlatformTicksGetFunc(), timer, (char*)userData); MultiTimerStart(timer, 1000, exampleTimer1Callback, userData); } void exampleTimer2Callback(MultiTimer* timer, void *userData) { - printf("[T:%012ld] Timer:%p callback-> %s.\r\n", PlatformTicksGetFunc(), timer, (char*)userData); + printf("[T:%010d] Timer:%p callback-> %s.\r\n", PlatformTicksGetFunc(), timer, (char*)userData); } void exampleTimer3Callback(MultiTimer* timer, void *userData) { - printf("[T:%012ld] Timer:%p callback-> %s.\r\n", PlatformTicksGetFunc(), timer, (char*)userData); + printf("[T:%010d] Timer:%p callback-> %s.\r\n", PlatformTicksGetFunc(), timer, (char*)userData); MultiTimerStart(timer, 4567, exampleTimer3Callback, userData); }