Skip to contentSkip to conversation

Reprogram timer once per tick

RFC PATCH New Jan Kiszka 1 participant 1 message Apr 9, 2007

lore
Share & tools
lore

Jan Kiszka

author
#0 lore raw

RFC PATCH 1/2 Reprogram timer once per tick

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(-)
include/nucleus/pod.h +1 -0
Index: 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
ksrc/nucleus/timer.c +12 -3
Index: 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);
 }