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

Author: Philippe Gerum <r...@xenomai.org>
Date:   Sun May 17 23:07:03 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    |   25 ++++++++++++++++---------
 ksrc/nucleus/pod.c     |    4 ++++
 3 files changed, 24 insertions(+), 9 deletions(-)

diff --git a/include/nucleus/intr.h b/include/nucleus/intr.h
index 4475048..c66d65b 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
@@ -81,6 +83,8 @@ extern "C" {
 
 int xnintr_mount(void);
 
+void xnintr_host_tick(struct xnsched *sched);
+
 void xnintr_clock_handler(void);
 
 int xnintr_irq_proc(unsigned int irq, char *str);
diff --git a/ksrc/nucleus/intr.c b/ksrc/nucleus/intr.c
index f65ee5b..121a96e 100644
--- a/ksrc/nucleus/intr.c
+++ b/ksrc/nucleus/intr.c
@@ -84,6 +84,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)
@@ -112,15 +118,16 @@ void xnintr_clock_handler(void)
 
        if (--sched->inesting == 0 && xnsched_resched_p())
                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 (testbits(sched->status, XNHTICK)) {
-               __clrbits(sched->status, XNHTICK);
-               xnarch_relay_tick();
-       }
+       /*
+        * 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) &&
+           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 41b52f2..113c9bf 100644
--- a/ksrc/nucleus/pod.c
+++ b/ksrc/nucleus/pod.c
@@ -562,6 +562,8 @@ static inline void xnpod_switch_zombie(xnthread_t 
*threadout,
        if (xnthread_test_state(threadin, XNROOT)) {
                xnpod_reset_watchdog(sched);
                xnfreesync();
+               if (testbits(sched->status, XNHTICK))
+                       xnintr_host_tick(sched);
                xnarch_enter_root(xnthread_archtcb(threadin));
        }
 
@@ -2506,6 +2508,8 @@ void xnpod_schedule(void)
        else if (xnthread_test_state(threadin, XNROOT)) {
                xnpod_reset_watchdog(sched);
                xnfreesync();
+               if (testbits(sched->status, XNHTICK))
+                       xnintr_host_tick(sched);
                xnarch_enter_root(xnthread_archtcb(threadin));
        }
 


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

Reply via email to