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

Author: Philippe Gerum <r...@xenomai.org>
Date:   Sun May 17 12:19:21 2009 +0200

Make sure to always propagate the host tick in time.

- do not delay a tick whenever the root thread is RPI-boosted, and
  preempts a real-time thread from the clock tick handler.

- do not miss a tick if the preempted real-time (kernel-based) thread
  is never scheduled in again (suspension/deletion).

---

 include/nucleus/intr.h |    4 ++++
 ksrc/nucleus/intr.c    |   22 ++++++++++++++--------
 ksrc/nucleus/pod.c     |    2 ++
 3 files changed, 20 insertions(+), 8 deletions(-)

diff --git a/include/nucleus/intr.h b/include/nucleus/intr.h
index 0321e7d..f68ea08 100644
--- a/include/nucleus/intr.h
+++ b/include/nucleus/intr.h
@@ -42,6 +42,8 @@
 #include <nucleus/types.h>
 #include <nucleus/stat.h>
 
+struct xnsched;
+
 typedef struct xnintr {
 
 #ifdef CONFIG_XENO_OPT_SHIRQ
@@ -98,6 +100,8 @@ int xnintr_mount(void);
 
 void xnintr_clock_handler(void);
 
+void xnintr_host_tick(struct xnsched *sched);
+
 int xnintr_irq_proc(unsigned int irq, char *str);
 
     /* Public interface. */
diff --git a/ksrc/nucleus/intr.c b/ksrc/nucleus/intr.c
index dba3b26..bdd3666 100644
--- a/ksrc/nucleus/intr.c
+++ b/ksrc/nucleus/intr.c
@@ -83,6 +83,12 @@ static inline void xnintr_sync_stat_references(xnintr_t 
*intr) {}
 
 static void xnintr_irq_handler(unsigned irq, void *cookie);
 
+void xnintr_host_tick(struct xnsched *sched) /* Interrupts off. */
+{
+       __clrbits(sched->status, XNHTICK);
+       xnarch_relay_tick();
+}
+
 /* Low-level clock irq handler. */
 
 void xnintr_clock_handler(void)
@@ -114,16 +120,16 @@ void xnintr_clock_handler(void)
                __clrbits(sched->status, XNINIRQ);
                xnpod_schedule();
        }
-
        /*
-        * Since the host tick is low priority, we can wait for
-        * returning from the rescheduling procedure before actually
-        * calling the propagation service, if it is pending.
+        * If the clock interrupt preempted a real-time thread, any
+        * transition to the root thread has already triggered a host
+        * tick propagation from xnpod_schedule(), so at this point,
+        * we only need to propagate the host tick in case the
+        * interrupt preempted the root thread.
         */
-       if (testbits(sched->status, XNHTICK)) {
-               __clrbits(sched->status, XNHTICK);
-               xnarch_relay_tick();
-       }
+       if (testbits(sched->status, XNHTICK) &&
+           xnthread_test_state(sched->curr, XNROOT))
+               xnintr_host_tick(sched);
 
        trace_mark(xn_nucleus, irq_exit, "irq %u", XNARCH_TIMER_IRQ);
        xnstat_exectime_switch(sched, prev);
diff --git a/ksrc/nucleus/pod.c b/ksrc/nucleus/pod.c
index d051c59..8a91790 100644
--- a/ksrc/nucleus/pod.c
+++ b/ksrc/nucleus/pod.c
@@ -2193,6 +2193,8 @@ void __xnpod_schedule(struct xnsched *sched)
        if (xnthread_test_state(prev, XNROOT))
                xnarch_leave_root(xnthread_archtcb(prev));
        else if (xnthread_test_state(next, XNROOT)) {
+               if (testbits(sched->status, XNHTICK))
+                       xnintr_host_tick(sched);
                if (testbits(sched->status, XNHDEFER))
                        xntimer_next_local_shot(sched);
                xnarch_enter_root(xnthread_archtcb(next));


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

Reply via email to