diff options
Diffstat (limited to 'oncology/dpfhack_display/lcd4linux/.svn/text-base/timer.c.svn-base')
| -rw-r--r-- | oncology/dpfhack_display/lcd4linux/.svn/text-base/timer.c.svn-base | 513 |
1 files changed, 0 insertions, 513 deletions
diff --git a/oncology/dpfhack_display/lcd4linux/.svn/text-base/timer.c.svn-base b/oncology/dpfhack_display/lcd4linux/.svn/text-base/timer.c.svn-base deleted file mode 100644 index d4545cbd..00000000 --- a/oncology/dpfhack_display/lcd4linux/.svn/text-base/timer.c.svn-base +++ /dev/null @@ -1,513 +0,0 @@ -/* $Id$ - * $URL$ - * - * Generic timer handling. - * - * Copyright (C) 2003, 2004 Michael Reinelt <michael@reinelt.co.at> - * Copyright (C) 2004 The LCD4Linux Team <lcd4linux-devel@users.sourceforge.net> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - */ - -/* - * Exported functions: - * - * 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) - * - * Process timer queue. - * - * - * int timer_remove(void (*callback) (void *data), void *data) - * - * Remove a new timer with given callback and data. - * - * - * void timer_exit(void) - * - * Release all timers and free the associated memory block. - * - */ - - -#include "config.h" - -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include <sys/time.h> -#include <time.h> - -#include "debug.h" -#include "cfg.h" -#include "timer.h" - -#ifdef WITH_DMALLOC -#include <dmalloc.h> -#endif - -/* threshold in milliseconds that differentiates between clock skew - and clock jitter */ -#define CLOCK_SKEW_DETECT_TIME_IN_MS 1000 - -/* structure for storing all relevant data of a single timer */ -typedef struct TIMER { - /* pointer to function of type void func(void *data) that will be - called when the timer is processed; it will also be used to - identify a specific timer */ - void (*callback) (void *data); - - /* pointer to data which will be passed to the callback function; - it will also be used to identify a specific timer */ - void *data; - - /* struct to hold the time (in seconds and milliseconds since the - Epoch) when the timer will be processed for the next time */ - struct timeval when; - - /* specifies the timer's triggering interval in milliseconds */ - int interval; - - /* specifies whether the timer should trigger indefinitely until - it is deleted (value of 0) or only once (all other values) */ - int one_shot; - - /* marks timer as being active (so it will get processed) or - inactive (which means the timer has been deleted and its - allocated memory may be re-used) */ - int active; -} TIMER; - -/* number of allocated timer slots */ -int nTimers = 0; - -/* pointer to memory allocated for storing the timer slots */ -TIMER *Timers = NULL; - - -static void timer_inc(const int timer, struct timeval *now) -/* Update the time a given timer updates next. - - timer (integer): internal ID of timer that is to be updated - - now (timeval pointer): struct holding the "current" time - - return value: void - */ -{ - /* calculate the time difference between the last time the given - timer has been processed and the current time */ - struct timeval diff; - timersub(now, &Timers[timer].when, &diff); - - /* convert this time difference to fractional seconds */ - float time_difference = diff.tv_sec + diff.tv_usec / 1000000.0f; - - /* convert time difference to fractional milliseconds */ - time_difference = time_difference * 1000.0f; - - /* calculate the number of timer intervals that have passed since - the last timer the given timer has been processed -- value is - truncated (rounded down) to an integer */ - int number_of_intervals = (int) (time_difference / Timers[timer].interval); - - /* notify the user in case one or more timer intervals have been - missed */ - if (number_of_intervals > 0) - info("Timer #%d skipped %d interval(s) or %d ms.", timer, number_of_intervals, - number_of_intervals * Timers[timer].interval); - - /* increment the number of passed intervals in order to skip all - missed intervals -- thereby avoiding that unprocessed timers - stack up, continuously update and are notoriously late (certain - railway companies might learn a lesson from us <g>) */ - number_of_intervals++; - - /* calculate time difference between the last time the timer has - been processed and the next time it will be processed */ - int interval = Timers[timer].interval * number_of_intervals; - - /* convert time difference (in milliseconds) to a "timeval" - struct (in seconds and microseconds) */ - struct timeval tv_interval = { - .tv_sec = interval / 1000, - .tv_usec = (interval % 1000) * 1000 - }; - - /* finally, add time difference to the timer's trigger */ - timeradd(&Timers[timer].when, &tv_interval, &Timers[timer].when); -} - - -int timer_remove(void (*callback) (void *data), void *data) -/* Remove a timer with given callback and data. - - callback (void pointer): function of type void func(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 - removal; otherwise returns a value of -1 -*/ -{ - int timer; /* current timer's ID */ - - /* loop through the timer slots and try to find the specified - timer slot by looking for its settings */ - for (timer = 0; timer < nTimers; timer++) { - /* skip inactive (i.e. deleted) timers */ - if (Timers[timer].active == 0) - continue; - - if (Timers[timer].callback == callback && Timers[timer].data == data) { - /* we have found the timer slot, so mark it as being inactive; - we will not actually delete the slot, so its allocated - memory may be re-used */ - Timers[timer].active = 0; - - /* signal successful timer removal */ - return 0; - } - } - - /* we have NOT found the timer slot, so signal failure by - returning a value of -1 */ - 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 void func(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 timer; /* current timer's ID */ - struct timeval now; /* struct to hold current time */ - - /* try to minimize memory usage by looping through the timer slots - and looking for an inactive timer */ - for (timer = 0; timer < nTimers; timer++) { - if (Timers[timer].active == 0) { - /* we've just found one, so let's reuse it ("timer" holds its - ID) by breaking the loop */ - break; - } - } - - /* no inactive timers (or none at all) found, so we have to add a - new timer slot */ - if (timer >= nTimers) { - /* increment number of timers and (re-)allocate memory used for - storing the timer slots */ - nTimers++; - Timers = realloc(Timers, nTimers * sizeof(*Timers)); - - /* make sure "timer" points to valid memory */ - timer = nTimers - 1; - - /* realloc() has failed */ - if (Timers == NULL) { - /* restore old number of timers */ - nTimers--; - - /* signal unsuccessful timer creation */ - return -1; - } - } - - /* get current time so the timer triggers immediately */ - gettimeofday(&now, NULL); - - /* initialize timer data */ - Timers[timer].callback = callback; - Timers[timer].data = data; - Timers[timer].when = now; - Timers[timer].interval = interval; - Timers[timer].one_shot = one_shot; - - /* set timer to active so that it is processed and not overwritten - by the memory optimization routine above */ - Timers[timer].active = 1; - - /* one-shot timers should NOT fire immediately, so delay them by a - single timer interval */ - if (one_shot) { - timer_inc(timer, &now); - } - - /* 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 void func(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 timer; /* current timer's ID */ - - /* loop through the timer slots and try to find the new timer slot - by looking for its settings */ - for (timer = 0; timer < nTimers; timer++) { - /* skip inactive (i.e. deleted) timers */ - if (Timers[timer].active == 0) - continue; - - if (Timers[timer].callback == callback && Timers[timer].data == data && Timers[timer].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[timer].one_shot = one_shot; - - /* signal successful timer creation */ - 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) -/* Process timer queue. - - delay (timespec pointer): struct holding delay till the next - upcoming timer event - - return value (integer): returns a value of 0 when timers have been - processed successfully; otherwise returns a value of -1 -*/ -{ - struct timeval now; /* struct to hold current time */ - - /* get current time to check which timers need processing */ - gettimeofday(&now, NULL); - - /* sanity check; by now, at least one timer should be - instantiated */ - if (nTimers <= 0) { - /* otherwise, print an error and return a value of -1 to - signal an error */ - error("Huh? Not even a single timer to process? Dazed and confused..."); - return -1; - } - - int timer; /* current timer's ID */ - - /* process all expired timers */ - for (timer = 0; timer < nTimers; timer++) { - /* skip inactive (i.e. deleted) timers */ - if (Timers[timer].active == 0) - continue; - - /* check whether current timer needs to be processed, i.e. the - timer's triggering time is less than or equal to the current - time; according to the man page of timercmp(), this avoids - using the operators ">=", "<=" and "==" which might be broken - on some systems */ - if (!timercmp(&Timers[timer].when, &now, >)) { - /* if the timer's callback function has been set, call it and - pass the corresponding data */ - if (Timers[timer].callback != NULL) { - Timers[timer].callback(Timers[timer].data); - } - - /* check for one-shot timers */ - if (Timers[timer].one_shot) { - /* mark one-shot timer as inactive (which means the timer has - been deleted and its allocated memory may be re-used) */ - Timers[timer].active = 0; - } else { - /* otherwise, re-spawn timer by adding one triggering interval - to its triggering time */ - timer_inc(timer, &now); - } - } - } - - int next_timer = -1; /* ID of the next upcoming timer */ - - /* loop through the timer slots and try to find the next upcoming - timer */ - for (timer = 0; timer < nTimers; timer++) { - /* skip inactive (i.e. deleted) timers */ - if (Timers[timer].active == 0) - continue; - - /* if this is the first timer that we check, mark it as the next - upcoming timer; otherwise, we'll have nothing to compare - against in this loop */ - if (next_timer < 0) - next_timer = timer; - /* check whether current timer needs processing prior to the one - selected */ - else if (timercmp(&Timers[timer].when, &Timers[next_timer].when, <)) { - /* if so, mark it as the next upcoming timer */ - next_timer = timer; - } - } - - /* sanity check; we should by now have found the next upcoming - timer */ - if (next_timer < 0) { - /* otherwise, print an error and return a value of -1 to signal an - error */ - error("Huh? Not even a single timer left? Dazed and confused..."); - return -1; - } - - /* processing all the timers might have taken a while, so update - the current time to compensate for processing delay */ - gettimeofday(&now, NULL); - - struct timeval diff; /* struct holding the time difference - between current time and the triggering time of the - next upcoming timer event */ - - /* calculate delay to the next upcoming timer event and store it - in "diff" */ - timersub(&Timers[next_timer].when, &now, &diff); - - /* convert "diff" to milliseconds */ - int time_difference = (diff.tv_sec * 1000.0f) + (diff.tv_usec / 1000.0f); - - /* a notable negative delay has occurred (positive clock skew or - some timers are faster than the time needed for processing - their callbacks) */ - if (time_difference < (-CLOCK_SKEW_DETECT_TIME_IN_MS)) { - /* zero "diff" so the next update is triggered immediately */ - timerclear(&diff); - } else { - /* if there is a notable difference between "time_difference" and - the next upcoming timer's interval, assume clock skew */ - if (time_difference > (Timers[next_timer].interval + CLOCK_SKEW_DETECT_TIME_IN_MS)) { - /* extract clock skew from "time_difference" by eliminating - the timer's triggering interval */ - int skew = time_difference - Timers[next_timer].interval; - - /* display an info message to inform the user */ - info("Oops, clock skewed by %d ms, updating timestamps...", skew); - - /* convert clock skew from milliseconds to "timeval" - structure */ - struct timeval clock_skew = { - .tv_sec = skew / 1000, - .tv_usec = (skew % 1000) * 1000 - }; - - /* process all timers */ - for (timer = 0; timer < nTimers; timer++) { - /* skip inactive (i.e. deleted) timers */ - if (Timers[timer].active == 0) - continue; - - /* correct timer's time stamp by clock skew */ - timersub(&Timers[timer].when, &clock_skew, &Timers[timer].when); - } - - /* finally, zero "diff" so the next update is triggered - immediately */ - timerclear(&diff); - } - } - - /* set timespec "delay" passed by calling function to "diff" */ - delay->tv_sec = diff.tv_sec; - /* timespec uses nanoseconds instead of microseconds!!! */ - delay->tv_nsec = diff.tv_usec * 1000; - - /* signal successful timer processing */ - return 0; -} - - -void timer_exit(void) -/* Release all timers and free the associated memory block. - - return value: void -*/ -{ - /* reset number of allocated timer slots */ - nTimers = 0; - - /* free memory used for storing the timer slots */ - if (Timers != NULL) { - free(Timers); - Timers = NULL; - } -} |
