From 20e4961f9eb3ea712a4d101d5984a6e0e68a23bd Mon Sep 17 00:00:00 2001 From: mzuther Date: Sat, 20 Nov 2010 20:22:05 +0000 Subject: started commenting the timer code I'm not done yet, but my system is currently very unstable, and I don't want the changes to get lost... :( git-svn-id: https://ssl.bulix.org/svn/lcd4linux/trunk@1134 3ae390bd-cb1e-0410-b409-cd5a39f66f1f --- timer.c | 202 ++++++++++++++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 160 insertions(+), 42 deletions(-) (limited to 'timer.c') diff --git a/timer.c b/timer.c index 80d2521..c80e960 100644 --- a/timer.c +++ b/timer.c @@ -22,23 +22,36 @@ * */ -/* +/* * exported functions: * - * int timer_add (void(*callback)(void *data), void *data, int interval, int one_shot); - * adds a timer to the queue + * int timer_add(void (*callback) (void *data), void *data, const int + * interval, const int one_shot) + * + * Create a new timer and add it to the timer queue. + * + * + * int timer_add_late(void (*callback) (void *data), void *data, const + * int interval, const int one_shot) + * + * This function creates a new timer and adds it to the timer queue + * just as timer_add() does, but the timer will NOT be triggered + * immediately (useful for scheduling things). + * + * + * int timer_process (struct timespec *delay) * - * int timer_process (struct timespec *delay); * process timer queue * - * int timer_remove(void (*callback) (void *data), void *data); - * remove a timer with given callback and data * - * int timer_add_late(void (*callback) (void *data), void *data, const int interval, const int one_shot) - * same as timer_add, but the one shot does not fire now (useful for scheduling things) + * int timer_remove(void (*callback) (void *data), void *data) + * + * Remove a new timer with given callback and data. + * + * + * void timer_exit(void) * - * void timer_exit(); - * release all timers + * Release all timers and free the associated memory block. * */ @@ -71,89 +84,189 @@ typedef struct TIMER { } TIMER; -TIMER *Timers = NULL; +/* number of allocated timer slots */ int nTimers = 0; +/* pointer to memory used for storing the timer slots */ +TIMER *Timers = NULL; + + +static void timer_inc(struct timeval *tv, const int interval) +/* Update a timer's trigger by adding the given interval. + + tv (timeval pointer): struct holding current time -static void timer_inc(struct timeval *tv, const int msec) + interval (integer): interval in milliseconds to be added to the + timer's trigger + + return value: void */ { struct timeval diff = { - .tv_sec = msec / 1000, - .tv_usec = (msec % 1000) * 1000 + .tv_sec = interval / 1000, + .tv_usec = (interval % 1000) * 1000 }; timeradd(tv, &diff, tv); } + int timer_remove(void (*callback) (void *data), void *data) +/* Remove a new timer with given callback and data. + + callback (void pointer): function of type callback(void *data); + here, it will be used to identify the timer + + data (void pointer): data which will be passed to the callback + function; here, it will be used to identify the timer + + return value (integer): returns a value of 0 on successful timer + deletion; otherwise returns a value of -1 */ { - int i; + int i; /* current timer's ID */ + + /* loop through the timer slots and try to find the specified + timer slot by looking for its settings */ for (i = 0; i < nTimers; i++) { if (Timers[i].callback == callback && Timers[i].data == data && Timers[i].active) { + /* we have found the timer slot, so mark it as being inactive; + we will not actually delete the timer, so its memory may be + re-used */ Timers[i].active = 0; return 0; } } + /* we have NOT found the timer slot, so signal failure by + returning a value of -1 */ return -1; } -int timer_add_late(void (*callback) (void *data), void *data, const int interval, const int one_shot) -{ - if (!timer_add(callback, data, interval, 1)) { - return -1; - } - if (one_shot) { - return 0; - } - int i; - for (i = 0; i < nTimers; i++) { - if (Timers[i].callback == callback && Timers[i].data == data && Timers[i].active - && Timers[i].interval == interval && Timers[i].one_shot) { - //we forced it to one_shot when adding to make it late (which gives us the alternate behavior) - Timers[i].one_shot = one_shot; - return 0; - } - } - - return -1; -} int timer_add(void (*callback) (void *data), void *data, const int interval, const int one_shot) +/* Create a new timer and add it to the timer queue. + + callback (void pointer): function of type callback(void *data) + which will be called whenever the timer triggers; this pointer + will also be used to identify a specific timer + + data (void pointer): data which will be passed to the callback + function; this pointer will also be used to identify a specific + timer + + interval (integer): specifies the timer's triggering interval in + milliseconds + + one_shot (integer): specifies whether the timer should trigger + indefinitely until it is deleted (value of 0) or only once (all + other values) + + return value (integer): returns a value of 0 on successful timer + creation; otherwise returns a value of -1 */ { - int i; - struct timeval now; + int i; /* current timer's ID */ + struct timeval now; /* struct to hold current time */ - /* find a free slot */ + /* try to minimize memory usage by looping through the timer slots + and looking for an inactive timer */ for (i = 0; i < nTimers; i++) { if (Timers[i].active == 0) + /* we've just found one, so let's reuse it ("i" holds its ID) + by breaking the loop */ break; } - /* none found, allocate a new slot */ + /* no inactive timers found, so we have to add a new timer slot */ if (i >= nTimers) { + /* increment number of timers and (re-)allocate memory used for + storing the timer slots */ nTimers++; Timers = realloc(Timers, nTimers * sizeof(*Timers)); + + /* realloc() has failed */ + if (Timers == NULL) { + /* restore old number of timers and signal unsuccessful timer + creation */ + nTimers--; + return -1; + } } + /* get current time so the timer triggers immediately */ gettimeofday(&now, NULL); - /* fill slot */ + /* fill in timer data */ Timers[i].callback = callback; Timers[i].data = data; Timers[i].when = now; Timers[i].interval = interval; Timers[i].one_shot = one_shot; + + /* set timer to active so that it is processed and not overwritten + by the memory optimisation above */ Timers[i].active = 1; - /* if one-shot timer, don't fire now */ + /* one-shot timers should NOT fire immediately, so delay them by a + single timer interval */ if (one_shot) { timer_inc(&Timers[i].when, interval); } + /* signal successful timer creation */ return 0; } +int timer_add_late(void (*callback) (void *data), void *data, const int interval, const int one_shot) +/* This function creates a new timer and adds it to the timer queue + just as timer_add() does, but the timer will NOT be triggered + immediately (useful for scheduling things). + + callback (void pointer): function of type callback(void *data) + which will be called whenever the timer triggers; this pointer + will also be used to identify a specific timer + + data (void pointer): data which will be passed to the callback + function; this pointer will also be used to identify a specific + timer + + interval (integer): specifies the timer's triggering interval in + milliseconds + + one_shot (integer): specifies whether the timer should trigger + indefinitely until it is deleted (value of 0) or only once (all + other values) + + return value (integer): returns a value of 0 on successful timer + creation; otherwise returns a value of -1 */ +{ + /* create new timer slot and add it to the timer queue; mask it as + one-shot timer for now, so the timer will be delayed by a + single timer interval */ + if (!timer_add(callback, data, interval, 1)) { + /* signal unsuccessful timer creation */ + return -1; + } + + int i; /* current timer's ID */ + + /* loop through the timer slots and try to find the new timer slot + by looking for its settings */ + for (i = 0; i < nTimers; i++) { + if (Timers[i].callback == callback && Timers[i].data == data && Timers[i].active + && Timers[i].interval == interval) { + /* we have found the new timer slot, so unmask it by setting + its "one_shot" variable to the REAL value; then signal + successful timer creation */ + Timers[i].one_shot = one_shot; + return 0; + } + } + + /* we have NOT found the new timer slot for some reason, so signal + failure by returning a value of -1 */ + return -1; +} + + int timer_process(struct timespec *delay) { int i, min; @@ -230,11 +343,16 @@ int timer_process(struct timespec *delay) void timer_exit(void) +/* Release all timers and free the associated memory block. + + return value: void */ { + /* reset number of allocated timer slots */ nTimers = 0; if (Timers != NULL) { - free(Timers);; + /* free memory used for storing the timer slots */ + free(Timers); Timers = NULL; } } -- cgit v1.2.3