Reprogram timer once per tick
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
@@ -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
@@ -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); }