aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGiovanni Di Sirio <gdisirio@gmail.com>2015-03-15 11:51:46 +0000
committerGiovanni Di Sirio <gdisirio@gmail.com>2015-03-15 11:51:46 +0000
commit953eab4dbf1d0c3971935d1eca5d172209e80384 (patch)
tree5436e9e3bff9aa416a2e73a882c5dbdd53856077
parent2bf792d2a5138fc1fa0a2eb2fd304d819115a7ab (diff)
downloadChibiOS-953eab4dbf1d0c3971935d1eca5d172209e80384.tar.gz
ChibiOS-953eab4dbf1d0c3971935d1eca5d172209e80384.tar.bz2
ChibiOS-953eab4dbf1d0c3971935d1eca5d172209e80384.zip
Tickless Mode improvements and more assertions added.
git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@7771 35acf78f-673a-0410-8e92-d51de3d6d3f4
-rw-r--r--os/rt/include/chvt.h47
-rw-r--r--testhal/STM32/STM32F4xx/IRQ_STORM/main.c1
2 files changed, 27 insertions, 21 deletions
diff --git a/os/rt/include/chvt.h b/os/rt/include/chvt.h
index 01cfbdeee..80465fbcd 100644
--- a/os/rt/include/chvt.h
+++ b/os/rt/include/chvt.h
@@ -448,10 +448,10 @@ static inline void chVTDoTickI(void) {
#if CH_CFG_ST_TIMEDELTA == 0
ch.vtlist.vt_systime++;
if (&ch.vtlist != (virtual_timers_list_t *)ch.vtlist.vt_next) {
- virtual_timer_t *vtp;
-
+ /* The list is not empty, processing elements on top.*/
--ch.vtlist.vt_next->vt_delta;
while (ch.vtlist.vt_next->vt_delta == (systime_t)0) {
+ virtual_timer_t *vtp;
vtfunc_t fn;
vtp = ch.vtlist.vt_next;
@@ -466,11 +466,17 @@ static inline void chVTDoTickI(void) {
}
#else /* CH_CFG_ST_TIMEDELTA > 0 */
virtual_timer_t *vtp;
- systime_t now;
+ systime_t now, delta;
+
+ /* The list is assumed to be non-empty because an tick interrupt just
+ occurred.*/
+ chDbgAssert(&ch.vtlist != (virtual_timers_list_t *)ch.vtlist.vt_next,
+ "timers list empty");
+ /* Timers processing loop.*/
+ vtp = ch.vtlist.vt_next;
while (true) {
vtfunc_t fn;
- systime_t delta;
/* Getting the current system time and calculating the time window since
the last time has expired.*/
@@ -479,13 +485,11 @@ static inline void chVTDoTickI(void) {
/* The next element is outside the current time window, the loop
is stopped here.*/
- vtp = ch.vtlist.vt_next;
if (vtp->vt_delta > delta) {
break;
}
/* The "last time" becomes this timer's expiration time.*/
- delta -= vtp->vt_delta;
ch.vtlist.vt_lasttime += vtp->vt_delta;
/* The timer is removed from the list and marked as non-armed.*/
@@ -493,27 +497,28 @@ static inline void chVTDoTickI(void) {
ch.vtlist.vt_next = vtp->vt_next;
fn = vtp->vt_func;
vtp->vt_func = NULL;
+ chSysUnlockFromISR();
/* The callback is invoked outside the kernel critical zone.*/
- chSysUnlockFromISR();
fn(vtp->vt_par);
+
+ /* Next element in the list, if the list is empty then the timer is
+ stopped.*/
chSysLockFromISR();
- }
- if (&ch.vtlist == (virtual_timers_list_t *)ch.vtlist.vt_next) {
- /* The list is empty, no tick event needed so the alarm timer
- is stopped.*/
- port_timer_stop_alarm();
- }
- else {
- /* Updating the alarm to the next deadline, deadline that must not be
- closer in time than the minimum time delta.*/
- if (vtp->vt_delta >= (systime_t)CH_CFG_ST_TIMEDELTA) {
- port_timer_set_alarm(now + vtp->vt_delta);
- }
- else {
- port_timer_set_alarm(now + (systime_t)CH_CFG_ST_TIMEDELTA);
+ vtp = ch.vtlist.vt_next;
+ if (&ch.vtlist == (virtual_timers_list_t *)vtp) {
+ port_timer_stop_alarm();
+ 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 */
}
diff --git a/testhal/STM32/STM32F4xx/IRQ_STORM/main.c b/testhal/STM32/STM32F4xx/IRQ_STORM/main.c
index 581a1142a..0b5ae9c00 100644
--- a/testhal/STM32/STM32F4xx/IRQ_STORM/main.c
+++ b/testhal/STM32/STM32F4xx/IRQ_STORM/main.c
@@ -302,6 +302,7 @@ int main(void) {
print("#");
if (threshold == 0)
threshold = interval;
+ break;
}
}
/* Gives the worker threads a chance to empty the mailboxes before next