aboutsummaryrefslogtreecommitdiffstats
path: root/timer.c
diff options
context:
space:
mode:
authormzuther <mzuther@3ae390bd-cb1e-0410-b409-cd5a39f66f1f>2010-11-20 20:22:05 +0000
committermzuther <mzuther@3ae390bd-cb1e-0410-b409-cd5a39f66f1f>2010-11-20 20:22:05 +0000
commit20e4961f9eb3ea712a4d101d5984a6e0e68a23bd (patch)
treefa9ff8ccfcdcd2b207cf41bf6492652c22437f72 /timer.c
parent4447e1d46ca5cdb1839c9ece0426fd26db1b2817 (diff)
downloadlcd4linux-20e4961f9eb3ea712a4d101d5984a6e0e68a23bd.tar.gz
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
Diffstat (limited to 'timer.c')
-rw-r--r--timer.c202
1 files changed, 160 insertions, 42 deletions
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;
}
}