aboutsummaryrefslogtreecommitdiffstats
path: root/os/rt/src
diff options
context:
space:
mode:
authorGiovanni Di Sirio <gdisirio@gmail.com>2016-10-07 12:19:12 +0000
committerGiovanni Di Sirio <gdisirio@gmail.com>2016-10-07 12:19:12 +0000
commit9763494076146ee7547bcce0627b68457529effb (patch)
tree2ffb293c4e1f662fe493c7459574ef1a81036564 /os/rt/src
parent257a19753d0e1129d2b8c3d087a5f825e0d15e28 (diff)
downloadChibiOS-9763494076146ee7547bcce0627b68457529effb.tar.gz
ChibiOS-9763494076146ee7547bcce0627b68457529effb.tar.bz2
ChibiOS-9763494076146ee7547bcce0627b68457529effb.zip
Tickless mode tentative fix: http://www.chibios.com/forum/viewtopic.php?f=35&t=3532
git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@9854 35acf78f-673a-0410-8e92-d51de3d6d3f4
Diffstat (limited to 'os/rt/src')
-rw-r--r--os/rt/src/chvt.c27
1 files changed, 20 insertions, 7 deletions
diff --git a/os/rt/src/chvt.c b/os/rt/src/chvt.c
index 965c79121..51db54cc3 100644
--- a/os/rt/src/chvt.c
+++ b/os/rt/src/chvt.c
@@ -131,23 +131,36 @@ void chVTDoSetI(virtual_timer_t *vtp, systime_t delay,
return;
}
- /* Special case where the timer will be placed as first element in a
- non-empty list, the alarm needs to be recalculated.*/
- delta = now + delay - ch.vtlist.lasttime;
- if (delta < ch.vtlist.next->delta) {
-
- /* New alarm deadline.*/
+ /* Pointer to the first element in the delta list, which is non-empty.*/
+ p = ch.vtlist.next;
+
+ /* Delay as delta from 'lasttime'. Note, it can overflow and the value
+ becomes lower than 'now'.*/
+ delta = now - ch.vtlist.lasttime + delay;
+
+ if (delta < now - ch.vtlist.lasttime) {
+ /* Scenario where a very large delay excedeed the numeric range, it
+ requires a special handling. We need to skip the first element and
+ adjust the delta to wrap back in the previous numeric range.*/
+ delta -= p->delta;
+ p = p->next;
+ }
+ else if (delta < p->delta) {
+ /* A small delay that will become the first element in the delta list
+ and next deadline.*/
port_timer_set_alarm(ch.vtlist.lasttime + delta);
}
}
#else /* CH_CFG_ST_TIMEDELTA == 0 */
/* Delta is initially equal to the specified delay.*/
delta = delay;
+
+ /* Pointer to the first element in the delta list.*/
+ p = ch.vtlist.next;
#endif /* CH_CFG_ST_TIMEDELTA == 0 */
/* The delta list is scanned in order to find the correct position for
this timer. */
- p = ch.vtlist.next;
while (p->delta < delta) {
delta -= p->delta;
p = p->next;