aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormzuther <mzuther@3ae390bd-cb1e-0410-b409-cd5a39f66f1f>2011-01-23 17:01:08 +0000
committermzuther <mzuther@3ae390bd-cb1e-0410-b409-cd5a39f66f1f>2011-01-23 17:01:08 +0000
commitc15760b9e502d12e4905ef898e9694436ec3bde3 (patch)
treef8497d464654c9a597ba626a57df1ea2b073cac5
parent72e1f7501bd6806022b7a33e1424ea2cc7fa4059 (diff)
downloadlcd4linux-c15760b9e502d12e4905ef898e9694436ec3bde3.tar.gz
timer.c: skip intermediate timer intervals
"timer_inc()" now checks how many trigger intervals have passed since a given timer has been updated. This might be due to "negative clock skew" (think of summer time) or the fact that some processing took too long (i.e. fetching of a web site). These missed trigger intervals are then skipped and the user is notified so that he may adapt his timer settings. This handling is essential, otherwise unprocessed timers might stack up and would trigger continuously while at the same time becoming notoriously late and unreliable. git-svn-id: https://ssl.bulix.org/svn/lcd4linux/trunk@1141 3ae390bd-cb1e-0410-b409-cd5a39f66f1f
-rw-r--r--drv_PICGraphic.c2
-rw-r--r--timer.c60
2 files changed, 46 insertions, 16 deletions
diff --git a/drv_PICGraphic.c b/drv_PICGraphic.c
index 8586eb6..c33973d 100644
--- a/drv_PICGraphic.c
+++ b/drv_PICGraphic.c
@@ -203,7 +203,7 @@ static void drv_PICGraphic_blit(const int row, const int col, const int height,
delayDone = 0;
int row8, height8;
row8 = 8 * (row / 8);
- height8 = 8 * (height / 8) + ! !(height % 8);
+ height8 = 8 * (height / 8) + !!(height % 8);
info("sending blit");
cmd[0] = 'b';
cmd[1] = row8;
diff --git a/timer.c b/timer.c
index 5dbb379..bd7eeb0 100644
--- a/timer.c
+++ b/timer.c
@@ -113,27 +113,57 @@ int nTimers = 0;
TIMER *Timers = NULL;
-static void timer_inc(struct timeval *tv, const int interval)
-/* Update a timer's trigger by adding the given interval.
+static void timer_inc(const int timer, struct timeval *now)
+/* Update the time a given timer updates next.
- tv (timeval pointer): struct holding the last time the timer has
- been processed
+ timer (integer): internal ID of timer that is to be updated
- interval (integer): interval in milliseconds to be added to the
- the last time the timer has been processed
+ now (timeval pointer): struct holding the "current" time
return value: void
*/
{
- /* split time interval to be added (given in milliseconds) into
- microseconds and seconds */
- struct timeval diff = {
+ /* 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 fDiff = diff.tv_sec + diff.tv_usec / 1000000.0f;
+
+ /* convert time difference to fractional milliseconds */
+ fDiff = fDiff * 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) (fDiff / 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"
+ structure (in seconds and microseconds) */
+ struct timeval tv_interval = {
.tv_sec = interval / 1000,
.tv_usec = (interval % 1000) * 1000
};
- /* add interval to timer and store the result in the timer */
- timeradd(tv, &diff, tv);
+ /* finally, add time difference to the timer's trigger */
+ timeradd(&Timers[timer].when, &tv_interval, &Timers[timer].when);
}
@@ -249,7 +279,7 @@ int timer_add(void (*callback) (void *data), void *data, const int interval, con
/* one-shot timers should NOT fire immediately, so delay them by a
single timer interval */
if (one_shot) {
- timer_inc(&Timers[timer].when, interval);
+ timer_inc(timer, &now);
}
/* signal successful timer creation */
@@ -365,9 +395,9 @@ int timer_process(struct timespec *delay)
been deleted and its allocated memory may be re-used) */
Timers[timer].active = 0;
} else {
- /* otherwise, respawn timer by adding one triggering interval
+ /* otherwise, re-spawn timer by adding one triggering interval
to its triggering time */
- timer_inc(&Timers[timer].when, Timers[timer].interval);
+ timer_inc(timer, &now);
}
}
}
@@ -428,7 +458,7 @@ int timer_process(struct timespec *delay)
timerclear(&diff);
/* display an info message to inform the user */
- info("Oops, clock skewed, update timestamp");
+ info("Oops, clock skewed, update time stamp");
/* update time stamp and timer */
/* FIXME: shouldn't we update *all* timers? */
ee&follow=1'>[lcd4linux @ 2004-05-31 21:05:13 by reinelt]reinelt5-77/+111 fixed lots of bugs in the Cwlinux driver do not emit EAGAIN error on the first retry made plugin_i2c_sensors a bit less 'chatty' moved init and exit functions to the bottom of plugin_pop3 git-svn-id: https://ssl.bulix.org/svn/lcd4linux/trunk@453 3ae390bd-cb1e-0410-b409-cd5a39f66f1f 2004-05-31[lcd4linux @ 2004-05-31 16:39:05 by reinelt]reinelt11-180/+535 added NULL display driver (for debugging/profiling purposes) added backlight/contrast initialisation for matrixOrbital added Backlight initialisation for Cwlinux git-svn-id: https://ssl.bulix.org/svn/lcd4linux/trunk@452 3ae390bd-cb1e-0410-b409-cd5a39f66f1f 2004-05-31[lcd4linux @ 2004-05-31 06:27:34 by reinelt]reinelt1-0/+40 ChangeLog update git-svn-id: https://ssl.bulix.org/svn/lcd4linux/trunk@451 3ae390bd-cb1e-0410-b409-cd5a39f66f1f 2004-05-31[lcd4linux @ 2004-05-31 06:24:42 by reinelt]reinelt2-7/+29 fixed symlink security issue with the image driver git-svn-id: https://ssl.bulix.org/svn/lcd4linux/trunk@450 3ae390bd-cb1e-0410-b409-cd5a39f66f1f 2004-05-31[lcd4linux @ 2004-05-31 05:38:02 by reinelt]reinelt8-42/+94 fixed possible bugs with user-defined chars (clear high bits) thanks to Andy Baxter for debugging the MilfordInstruments driver! git-svn-id: https://ssl.bulix.org/svn/lcd4linux/trunk@449 3ae390bd-cb1e-0410-b409-cd5a39f66f1f 2004-05-31[lcd4linux @ 2004-05-31 01:31:01 by andy-b]andy-b1-10/+12 fixed bug in Milford Instruments driver which drew extra graphics chars in odd places when drawing double bars. (the display doesn't like it if you put the escape character 0xfe inside a define char sequence). git-svn-id: https://ssl.bulix.org/svn/lcd4linux/trunk@448 3ae390bd-cb1e-0410-b409-cd5a39f66f1f 2004-05-30[lcd4linux @ 2004-05-30 08:25:50 by reinelt]reinelt2-30/+92 Crystalfontz 631 driver finished git-svn-id: https://ssl.bulix.org/svn/lcd4linux/trunk@447 3ae390bd-cb1e-0410-b409-cd5a39f66f1f 2004-05-29[lcd4linux @ 2004-05-29 23:30:20 by reinelt]reinelt1-1/+9 fixed a compiler issue with drv_Image.c (thanks to Frank Stratmann) git-svn-id: https://ssl.bulix.org/svn/lcd4linux/trunk@446 3ae390bd-cb1e-0410-b409-cd5a39f66f1f 2004-05-29[lcd4linux @ 2004-05-29 15:53:28 by reinelt]reinelt3-9/+25 M50530: reset parport signals on exit plugin_ppp: ppp() has two parameters, not three lcd4linux.conf.sample: diskstats() corrected git-svn-id: https://ssl.bulix.org/svn/lcd4linux/trunk@445 3ae390bd-cb1e-0410-b409-cd5a39f66f1f 2004-05-29[lcd4linux @ 2004-05-29 01:07:56 by reinelt]reinelt2-21/+25 bug in plugin_diskstats fixed git-svn-id: https://ssl.bulix.org/svn/lcd4linux/trunk@444 3ae390bd-cb1e-0410-b409-cd5a39f66f1f 2004-05-29[lcd4linux @ 2004-05-29 00:27:14 by reinelt]reinelt8-11/+214 added plugin_diskstats.c git-svn-id: https://ssl.bulix.org/svn/lcd4linux/trunk@443 3ae390bd-cb1e-0410-b409-cd5a39f66f1f 2004-05-28[lcd4linux @ 2004-05-28 14:38:10 by reinelt]reinelt2-1/+41 Status and Changelog Update git-svn-id: https://ssl.bulix.org/svn/lcd4linux/trunk@442 3ae390bd-cb1e-0410-b409-cd5a39f66f1f