Module: xenomai-2.5
Branch: master
Commit: ce2301aa3a734d92c1b05e8b32564cd35020a4e0
URL:    
http://git.xenomai.org/?p=xenomai-2.5.git;a=commit;h=ce2301aa3a734d92c1b05e8b32564cd35020a4e0

Author: Philippe Gerum <r...@xenomai.org>
Date:   Fri Aug 20 07:51:59 2010 +0200

nucleus: requeue blocked non-periodic timers properly

Single-stepping into a Xenomai application should freeze timers to
avoid overruns, until the program is continued. Unfortunately,
non-periodic timers are not requeued when the time base is unblocked,
preventing their timeout handler to be fired, thus causing the tasks
pending on them to hang indefinitely.

This patch requeues those timers properly, by interval of 250 ms,
until the timebase is unlocked.

---

 ksrc/nucleus/timer.c |   23 +++++++++++++++--------
 1 files changed, 15 insertions(+), 8 deletions(-)

diff --git a/ksrc/nucleus/timer.c b/ksrc/nucleus/timer.c
index d813c4f..bb38fea 100644
--- a/ksrc/nucleus/timer.c
+++ b/ksrc/nucleus/timer.c
@@ -342,10 +342,10 @@ void xntimer_tick_aperiodic(void)
 {
        xnsched_t *sched = xnpod_current_sched();
        xntimerq_t *timerq = &sched->timerqueue;
+       xnticks_t now, interval;
        xntimerh_t *holder;
        xntimer_t *timer;
        xnsticks_t delta;
-       xnticks_t now;
 
        /*
         * Optimisation: any local timer reprogramming triggered by
@@ -389,13 +389,18 @@ void xntimer_tick_aperiodic(void)
                                __setbits(timer->status, XNTIMER_FIRED);
                        } else if (likely(!testbits(timer->status, 
XNTIMER_PERIODIC))) {
                                /*
-                                * Postpone the next tick to a
-                                * reasonable date in the future,
-                                * waiting for the timebase to be
-                                * unlocked at some point.
+                                * Make the blocked timer elapse again
+                                * at a reasonably close date in the
+                                * future, waiting for the timebase to
+                                * be unlocked at some point. Timers
+                                * are blocked when single-stepping
+                                * into an application using a
+                                * debugger, so it is fine to wait for
+                                * 250 ms for the user to continue
+                                * program execution.
                                 */
-                               xntimerh_date(&timer->aplink) = 
xntimerh_date(&sched->htimer.aplink);
-                               continue;
+                               interval = xnarch_ns_to_tsc(250000000ULL);
+                               goto requeue;
                        }
                } else {
                        /*
@@ -411,8 +416,10 @@ void xntimer_tick_aperiodic(void)
                                continue;
                }
 
+               interval = timer->interval;
+       requeue:
                do {
-                       xntimerh_date(&timer->aplink) += timer->interval;
+                       xntimerh_date(&timer->aplink) += interval;
                } while (xntimerh_date(&timer->aplink) < now + nklatency);
                xntimer_enqueue_aperiodic(timer);
        }


_______________________________________________
Xenomai-git mailing list
Xenomai-git@gna.org
https://mail.gna.org/listinfo/xenomai-git

Reply via email to