]> git.webhop.me Git - lcd4linux.git/commitdiff
finished commenting the timer code
authormzuther <mzuther@3ae390bd-cb1e-0410-b409-cd5a39f66f1f>
Sat, 27 Nov 2010 14:35:10 +0000 (14:35 +0000)
committermzuther <mzuther@3ae390bd-cb1e-0410-b409-cd5a39f66f1f>
Sat, 27 Nov 2010 14:35:10 +0000 (14:35 +0000)
git-svn-id: https://ssl.bulix.org/svn/lcd4linux/trunk@1135 3ae390bd-cb1e-0410-b409-cd5a39f66f1f

timer.c
timer.h

diff --git a/timer.c b/timer.c
index c80e9606809911bb3c0bb65fe592d3532c7022b9..b0b1bc2c4b37b8ef1a3b003ac4c063b00d7725af 100644 (file)
--- a/timer.c
+++ b/timer.c
@@ -23,7 +23,7 @@
  */
 
 /*
- * exported functions:
+ * Exported functions:
  *
  * int timer_add(void (*callback) (void *data), void *data, const int
  *     interval, const int one_shot)
@@ -39,9 +39,9 @@
  *   immediately (useful for scheduling things).
  *
  *
- * int timer_process (struct timespec *delay)
+ * int timer_process(struct timespec *delay)
  *
- *   process timer queue
+ *    Process timer queue.
  *
  *
  * int timer_remove(void (*callback) (void *data), void *data)
 #include <dmalloc.h>
 #endif
 
+/* delay in seconds between timer events that is considered as being
+   induced by clock skew */
 #define CLOCK_SKEW_DETECT_TIME_IN_S 1
 
+/* structure for storing all relevant data of a single timer */
 typedef struct TIMER {
+    /* function of type callback(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);
+
+    /* 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 timers 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;
 
@@ -94,18 +115,23 @@ 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
+    tv (timeval pointer): struct holding the last time the timer has
+    been processed
 
        interval (integer): interval in milliseconds to be added to the
-       timer's trigger
+    the last time the timer has been processed
 
-       return value: void */
+       return value: void
+ */
 {
+    /* split time interval to be added (given in milliseconds) into
+       microseconds and seconds */
     struct timeval diff = {
        .tv_sec = interval / 1000,
        .tv_usec = (interval % 1000) * 1000
     };
 
+    /* add interval to timer and store the result in the timer */
     timeradd(tv, &diff, tv);
 }
 
@@ -113,14 +139,15 @@ static void timer_inc(struct timeval *tv, const int interval)
 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);
+    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
-       deletion; otherwise returns a value of -1 */
+       deletion; otherwise returns a value of -1
+*/
 {
     int i;                     /* current timer's ID */
 
@@ -129,9 +156,11 @@ int timer_remove(void (*callback) (void *data), void *data)
     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 */
+              we will not actually delete the timer, so its allocated
+              memory may be re-used */
            Timers[i].active = 0;
+
+           /* signal successful timer removal */
            return 0;
        }
     }
@@ -144,7 +173,7 @@ int timer_remove(void (*callback) (void *data), void *data)
 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)
+    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
 
@@ -160,7 +189,8 @@ int timer_add(void (*callback) (void *data), void *data, const int interval, con
        other values)
 
        return value (integer): returns a value of 0 on successful timer
-       creation; otherwise returns a value of -1 */
+       creation; otherwise returns a value of -1
+*/
 {
     int i;                     /* current timer's ID */
     struct timeval now;                /* struct to hold current time */
@@ -174,7 +204,8 @@ int timer_add(void (*callback) (void *data), void *data, const int interval, con
            break;
     }
 
-    /* no inactive timers found, so we have to add a new timer slot */
+    /* no inactive timers (or none at all) 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 */
@@ -183,9 +214,10 @@ int timer_add(void (*callback) (void *data), void *data, const int interval, con
 
        /* realloc() has failed */
        if (Timers == NULL) {
-           /* restore old number of timers and signal unsuccessful timer
-              creation */
+           /* restore old number of timers */
            nTimers--;
+
+           /* signal unsuccessful timer creation */
            return -1;
        }
     }
@@ -201,7 +233,7 @@ int timer_add(void (*callback) (void *data), void *data, const int interval, con
     Timers[i].one_shot = one_shot;
 
     /* set timer to active so that it is processed and not overwritten
-       by the memory optimisation above */
+       by the memory optimisation routine above */
     Timers[i].active = 1;
 
     /* one-shot timers should NOT fire immediately, so delay them by a
@@ -220,7 +252,7 @@ int timer_add_late(void (*callback) (void *data), void *data, const int interval
        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)
+       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
 
@@ -236,7 +268,8 @@ int timer_add_late(void (*callback) (void *data), void *data, const int interval
        other values)
 
        return value (integer): returns a value of 0 on successful timer
-       creation; otherwise returns a value of -1 */
+       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
@@ -257,6 +290,8 @@ int timer_add_late(void (*callback) (void *data), void *data, const int interval
               its "one_shot" variable to the REAL value; then signal
               successful timer creation */
            Timers[i].one_shot = one_shot;
+
+           /* signal successful timer creation */
            return 0;
        }
     }
@@ -268,84 +303,138 @@ int timer_add_late(void (*callback) (void *data), void *data, const int interval
 
 
 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
+*/
 {
-    int i, min;
-    struct timeval now;
+    struct timeval now;                /* struct to hold current time */
 
-    /* the current moment */
+    /* get current time to check which timers need processing */
     gettimeofday(&now, NULL);
 
-    /* sanity check */
+    /* sanity check; at least one timer should need processing */
     if (nTimers == 0) {
-       error("huh? not one single timer to process? dazed and confused...");
+       /* otherwise, print an error and return a value of -1 to
+          signal an error */
+       error("Huh? Not one single timer to process? Dazed and confused...");
        return -1;
     }
 
-    /* process expired timers */
+    int i;                     /* current timer's ID */
+
+    /* process all expired timers */
     for (i = 0; i < nTimers; i++) {
+       /* skip inactive (i.e. deleted) timers */
        if (Timers[i].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[i].when, &now, >)) {
-           /* callback */
+           /* if the timer's callback function has been set, call it and
+              pass the corresponding data */
            if (Timers[i].callback != NULL) {
                Timers[i].callback(Timers[i].data);
            }
-           /* respawn or delete timer */
+
+           /* check for one-shot timers */
            if (Timers[i].one_shot) {
+               /* mark one-shot timer as inactive (which means the timer has
+                  been deleted and its allocated memory may be re-used) */
                Timers[i].active = 0;
            } else {
+               /* otherwise, respawn timer by adding one triggering interval
+                  to its triggering time */
                timer_inc(&Timers[i].when, Timers[i].interval);
            }
        }
     }
 
-    /* find next timer */
-    min = -1;
+    int min = -1;              /* ID of the next upcoming timer */
+
+    /* loop through the timer slots and try to find the next upcoming
+       timer */
     for (i = 0; i < nTimers; i++) {
+       /* skip inactive (i.e. deleted) timers */
        if (Timers[i].active == 0)
            continue;
-       if ((min < 0) || timercmp(&Timers[i].when, &Timers[min].when, <))
+
+       /* 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 (min < 0)
+           min = i;
+       /* check whether current timer needs processing prior to the one
+          selected */
+       else if (timercmp(&Timers[i].when, &Timers[min].when, <))
+           /* if so, mark it as the next upcoming timer */
            min = i;
     }
 
+    /* sanity check; we should by now have found the next upcoming
+       timer */
     if (min < 0) {
-       error("huh? not one single timer left? dazed and confused...");
+       /* otherwise, print an error and return a value of -1 to signal an
+          error */
+       error("Huh? Not one single timer left? Dazed and confused...");
        return -1;
     }
 
-    /* update the current moment to compensate for processing delay */
+    /* processing all the timers might have taken a while, so update
+       the current time to compensate for processing delay */
     gettimeofday(&now, NULL);
 
-    /* delay until next timer event */
-    struct timeval diff;
+    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[min].when, &now, &diff);
 
-    /* for negative delays, directly trigger next update */
+    /* for negative delays, set "diff" to the Epoch so the next update
+       is triggered immediately */
     if (diff.tv_sec < 0)
        timerclear(&diff);
 
-    delay->tv_sec = diff.tv_sec;
-    /* microseconds to nanoseconds!! */
-    delay->tv_nsec = diff.tv_usec * 1000;
+    /* check whether the delay in "diff" has been induced by clock
+       skew */
+    if (diff.tv_sec > CLOCK_SKEW_DETECT_TIME_IN_S) {
+       /* set "diff" to the Epoch so the next update is triggered
+          directly */
+       timerclear(&diff);
 
-    /* check if date changed */
-    if ((delay->tv_sec) > CLOCK_SKEW_DETECT_TIME_IN_S) {
-       delay->tv_sec = 0;
-       delay->tv_nsec = 0;
+       /* display an info message to inform the user */
        info("Oops, clock skewed, update timestamp");
+
+       /* update time stamp and timer */
+       /* FIXME: shouldn't we update *all* timers? */
        gettimeofday(&now, NULL);
        Timers[min].when = now;
     }
 
-    return 0;
+    /* finally, set passed timespec "delay" 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 */
+       return value: void
+*/
 {
     /* reset number of allocated timer slots */
     nTimers = 0;
diff --git a/timer.h b/timer.h
index 26f86740db6c47031fb85faf72d7a0d00d90be30..70744d517d89e362d76d16a693abc3ad56a4cd15 100644 (file)
--- a/timer.h
+++ b/timer.h
 #define _TIMER_H_
 
 int timer_add(void (*callback) (void *data), void *data, const int interval, const int one_shot);
-/* exactly the same as timer_add() but does not trigger immediately */
+
 int timer_add_late(void (*callback) (void *data), void *data, const int interval, const int one_shot);
-int timer_remove(void (*callback) (void *data), void *data);
+
 int timer_process(struct timespec *delay);
-void timer_exit();
+
+int timer_remove(void (*callback) (void *data), void *data);
+
+void timer_exit(void);
 
 #endif