aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGiovanni Di Sirio <gdisirio@gmail.com>2015-03-23 10:08:41 +0000
committerGiovanni Di Sirio <gdisirio@gmail.com>2015-03-23 10:08:41 +0000
commitac82171cfe9a05f6f8902bb77341cff94fd2450a (patch)
tree32360710b7f8669c95fbbffc4af0f47127e384d2
parentab86eaaf02aacf4b371ce52b080e61dd51edb1cb (diff)
downloadChibiOS-ac82171cfe9a05f6f8902bb77341cff94fd2450a.tar.gz
ChibiOS-ac82171cfe9a05f6f8902bb77341cff94fd2450a.tar.bz2
ChibiOS-ac82171cfe9a05f6f8902bb77341cff94fd2450a.zip
Optimization in tickless mode handling.
git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@7796 35acf78f-673a-0410-8e92-d51de3d6d3f4
-rw-r--r--os/rt/include/chvt.h55
1 files changed, 33 insertions, 22 deletions
diff --git a/os/rt/include/chvt.h b/os/rt/include/chvt.h
index 80465fbcd..1bc83d908 100644
--- a/os/rt/include/chvt.h
+++ b/os/rt/include/chvt.h
@@ -473,21 +473,18 @@ static inline void chVTDoTickI(void) {
chDbgAssert(&ch.vtlist != (virtual_timers_list_t *)ch.vtlist.vt_next,
"timers list empty");
- /* Timers processing loop.*/
+ /* First timer to be processed, its time is assumed to be between
+ "vt_lasttime" and "now".*/
vtp = ch.vtlist.vt_next;
- while (true) {
- vtfunc_t fn;
- /* Getting the current system time and calculating the time window since
- the last time has expired.*/
- now = chVTGetSystemTimeX();
- delta = now - ch.vtlist.vt_lasttime;
+ chDbgAssert(chVTIsTimeWithinX(ch.vtlist.vt_lasttime + vtp->vt_delta,
+ ch.vtlist.vt_lasttime,
+ chVTGetSystemTimeX() + 1),
+ "out of time window");
- /* The next element is outside the current time window, the loop
- is stopped here.*/
- if (vtp->vt_delta > delta) {
- break;
- }
+ /* Timers processing loop.*/
+ while (true) {
+ vtfunc_t fn;
/* The "last time" becomes this timer's expiration time.*/
ch.vtlist.vt_lasttime += vtp->vt_delta;
@@ -502,23 +499,37 @@ static inline void chVTDoTickI(void) {
/* The callback is invoked outside the kernel critical zone.*/
fn(vtp->vt_par);
- /* Next element in the list, if the list is empty then the timer is
- stopped.*/
+ /* Re-entering the critical zone in order to continue the exploration
+ of the list.*/
chSysLockFromISR();
+
+ /* Next element in the list, if the list is empty then ending the loop.*/
vtp = ch.vtlist.vt_next;
if (&ch.vtlist == (virtual_timers_list_t *)vtp) {
port_timer_stop_alarm();
return;
}
+
+ /* Getting the current system time and calculating the time window since
+ the last time has expired.*/
+ now = chVTGetSystemTimeX();
+ delta = now - ch.vtlist.vt_lasttime;
+
+ /* The next element is outside the current time window, the loop
+ is stopped here.*/
+ if (vtp->vt_delta > delta) {
+ /* Updating the alarm to the next deadline, deadline that must not be
+ closer in time than the minimum time delta.*/
+ delta = (vtp->vt_delta >= (systime_t)CH_CFG_ST_TIMEDELTA) ?
+ vtp->vt_delta : (systime_t)CH_CFG_ST_TIMEDELTA;
+ port_timer_set_alarm(now + delta);
+
+ chDbgAssert((chVTGetSystemTimeX() - ch.vtlist.vt_lasttime) < delta,
+ "exceeding delta");
+
+ return;
+ }
}
- /* Updating the alarm to the next deadline, deadline that must not be
- closer in time than the minimum time delta.*/
- delta = (vtp->vt_delta >= (systime_t)CH_CFG_ST_TIMEDELTA) ?
- vtp->vt_delta : (systime_t)CH_CFG_ST_TIMEDELTA;
- port_timer_set_alarm(now + delta);
-
- chDbgAssert((chVTGetSystemTimeX() - ch.vtlist.vt_lasttime) < delta,
- "exceeding delta");
#endif /* CH_CFG_ST_TIMEDELTA > 0 */
}