This is an optimisation patch, long pending in my repos, aiming at
making the aperiodic timer tick handling more predictable. It suppresses
any xntimer_next_local_shot() as long as the tick handler is running.
This avoids potential multiple (costly) timer reprogramming when timer
handlers make use of xntimer_start.

Jan


---
 include/nucleus/pod.h |    1 +
 ksrc/nucleus/timer.c  |   15 ++++++++++++---
 2 files changed, 13 insertions(+), 3 deletions(-)

Index: xenomai/include/nucleus/pod.h
===================================================================
--- xenomai.orig/include/nucleus/pod.h
+++ xenomai/include/nucleus/pod.h
@@ -46,6 +46,7 @@
 #define XNKCOUT  0x80000000    /* Sched callout context */
 #define XNHTICK  0x40000000    /* Host tick pending  */
 #define XNRPICK  0x20000000    /* Check RPI state */
+#define XNINTCK  0x10000000    /* In master tick handler context */
 
 /* These flags are available to the real-time interfaces */
 #define XNPOD_SPARE0  0x01000000
Index: xenomai/ksrc/nucleus/timer.c
===================================================================
--- xenomai.orig/ksrc/nucleus/timer.c
+++ xenomai/ksrc/nucleus/timer.c
@@ -54,14 +54,16 @@ static inline void xntimer_dequeue_aperi
        __setbits(timer->status, XNTIMER_DEQUEUED);
 }
 
-static inline void xntimer_next_local_shot(xnsched_t *this_sched)
+static void xntimer_next_local_shot(xnsched_t *this_sched)
 {
        xntimerh_t *holder = xntimerq_head(&this_sched->timerqueue);
        xnticks_t now, delay, xdate;
        xntimer_t *timer;
 
-       if (!holder)
-               return;         /* No pending timer. */
+       /* Do not reprogram locally when inside the tick handler - will be
+          done on exit anyway. Also exit if there is no pending timer. */
+       if (testbits(this_sched->status, XNINTCK) || !holder)
+               return;
 
        timer = aplink2timer(holder);
 
@@ -184,6 +186,11 @@ void xntimer_tick_aperiodic(void)
        xntimer_t *timer;
        xnticks_t now;
 
+       /* Optimisation: any local timer reprogramming triggered by invoked
+          timer handlers can wait until we leave the tick handler. Use this
+          status flag as hint to xntimer_start_aperiodic. */
+       __setbits(sched->status, XNINTCK);
+
        now = xnarch_get_cpu_tsc();
        while ((holder = xntimerq_head(timerq)) != NULL) {
                timer = aplink2timer(holder);
@@ -237,6 +244,8 @@ void xntimer_tick_aperiodic(void)
                xntimer_enqueue_aperiodic(timer);
        }
 
+       __clrbits(sched->status, XNINTCK);
+
        xntimer_next_local_shot(sched);
 }
 

Attachment: signature.asc
Description: OpenPGP digital signature

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

Reply via email to