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

Author: Philippe Gerum <r...@xenomai.org>
Date:   Sat Aug 28 12:52:55 2010 +0200

hal/generic: inline APC scheduling code

rthal_apc_schedule() may be called on the hot path, its implementation
is simple and we need it to be as fast as possible. This patch inlines
it.

In the same move, error checking on the APC parameter is either
removed (APC scheduling) or converted to a BUG_ON() assertion, since
that interface is way too internal for recovering sanely from such a
misuse.

---

 include/asm-generic/hal.h |   22 +++++++-
 ksrc/arch/generic/hal.c   |  123 +++++++++++++++++----------------------------
 2 files changed, 67 insertions(+), 78 deletions(-)

diff --git a/include/asm-generic/hal.h b/include/asm-generic/hal.h
index f90cafa..34f8ea1 100644
--- a/include/asm-generic/hal.h
+++ b/include/asm-generic/hal.h
@@ -440,6 +440,10 @@ extern rthal_trap_handler_t rthal_trap_handler;
 
 extern unsigned rthal_realtime_faults[RTHAL_NR_CPUS][RTHAL_NR_FAULTS];
 
+extern unsigned long rthal_apc_pending[RTHAL_NR_CPUS];
+
+extern unsigned int rthal_apc_virq;
+
 extern int rthal_arch_init(void);
 
 extern void rthal_arch_cleanup(void);
@@ -517,9 +521,23 @@ int rthal_apc_alloc(const char *name,
                    void (*handler)(void *cookie),
                    void *cookie);
 
-int rthal_apc_free(int apc);
+void rthal_apc_free(int apc);
+
+static inline void __rthal_apc_schedule(int apc)
+{
+       int cpu = rthal_processor_id();
+       if (!__test_and_set_bit(apc, &rthal_apc_pending[cpu]))
+               rthal_schedule_irq_root(rthal_apc_virq);
+}
+
+static inline void rthal_apc_schedule(int apc)
+{
+       unsigned long flags;
 
-int rthal_apc_schedule(int apc);
+       rthal_local_irq_save(flags);
+       __rthal_apc_schedule(apc);
+       rthal_local_irq_restore(flags);
+}
 
 int rthal_irq_affinity(unsigned irq,
                       cpumask_t cpumask,
diff --git a/ksrc/arch/generic/hal.c b/ksrc/arch/generic/hal.c
index 8a5ec39..4667f70 100644
--- a/ksrc/arch/generic/hal.c
+++ b/ksrc/arch/generic/hal.c
@@ -80,12 +80,8 @@ static struct {
 
 static int rthal_init_done;
 
-static unsigned rthal_apc_virq;
-
 static unsigned long rthal_apc_map;
 
-static unsigned long rthal_apc_pending[RTHAL_NR_CPUS];
-
 static rthal_spinlock_t rthal_apc_lock = RTHAL_SPIN_LOCK_UNLOCKED;
 
 static atomic_t rthal_sync_count = ATOMIC_INIT(1);
@@ -100,6 +96,10 @@ unsigned 
rthal_realtime_faults[RTHAL_NR_CPUS][RTHAL_NR_FAULTS];
 
 volatile int rthal_sync_op;
 
+unsigned long rthal_apc_pending[RTHAL_NR_CPUS];
+
+unsigned int rthal_apc_virq;
+
 unsigned long rthal_critical_enter(void (*synch) (void))
 {
     unsigned long flags = rthal_grab_superlock(synch);
@@ -517,26 +517,28 @@ void rthal_apc_kicker(unsigned virq, void *cookie)
 int rthal_apc_alloc(const char *name,
                     void (*handler) (void *cookie), void *cookie)
 {
-    unsigned long flags;
-    int apc;
+       unsigned long flags;
+       int apc;
 
-    if (handler == NULL)
-        return -EINVAL;
+       if (handler == NULL)
+               return -EINVAL;
 
-    rthal_spin_lock_irqsave(&rthal_apc_lock, flags);
+       rthal_spin_lock_irqsave(&rthal_apc_lock, flags);
 
-    if (rthal_apc_map != ~0) {
-        apc = ffz(rthal_apc_map);
-        __set_bit(apc, &rthal_apc_map);
-        rthal_apc_table[apc].handler = handler;
-        rthal_apc_table[apc].cookie = cookie;
-        rthal_apc_table[apc].name = name;
-    } else
-        apc = -EBUSY;
+       if (rthal_apc_map == ~0) {
+               apc = -EBUSY;
+               goto out;
+       }
 
-    rthal_spin_unlock_irqrestore(&rthal_apc_lock, flags);
+       apc = ffz(rthal_apc_map);
+       __set_bit(apc, &rthal_apc_map);
+       rthal_apc_table[apc].handler = handler;
+       rthal_apc_table[apc].cookie = cookie;
+       rthal_apc_table[apc].name = name;
+out:
+       rthal_spin_unlock_irqrestore(&rthal_apc_lock, flags);
 
-    return apc;
+       return apc;
 }
 
 /**
@@ -549,10 +551,6 @@ int rthal_apc_alloc(const char *name,
  * @param apc The APC id. to release, as returned by a successful call
  * to the rthal_apc_alloc() service.
  *
- * @return 0 is returned upon success. Otherwise:
- *
- * - -EINVAL is returned if @a apc is invalid.
- *
  * Environments:
  *
  * This service can be called from:
@@ -560,59 +558,10 @@ int rthal_apc_alloc(const char *name,
  * - Any domain context.
  */
 
-int rthal_apc_free(int apc)
+void rthal_apc_free(int apc)
 {
-    if (apc < 0 || apc >= RTHAL_NR_APCS ||
-        !test_and_clear_bit(apc, &rthal_apc_map))
-        return -EINVAL;
-
-    return 0;
-}
-
-/**
- * @fn int rthal_apc_schedule (int apc)
- *
- * @brief Schedule an APC invocation.
- *
- * This service marks the APC as pending for the Linux domain, so that
- * its handler will be called as soon as possible, when the Linux
- * domain gets back in control.
- *
- * When posted from the Linux domain, the APC handler is fired as soon
- * as the interrupt mask is explicitly cleared by some kernel
- * code. When posted from the Xenomai domain, the APC handler is
- * fired as soon as the Linux domain is resumed, i.e. after Xenomai has
- * completed all its pending duties.
- *
- * @param apc The APC id. to schedule.
- *
- * @return 0 is returned upon success. Otherwise:
- *
- * - -EINVAL is returned if @a apc is invalid.
- *
- * Environments:
- *
- * This service can be called from:
- *
- * - Any domain context, albeit the usual calling place is from the
- * Xenomai domain.
- */
-
-int rthal_apc_schedule(int apc)
-{
-    unsigned long flags;
-
-    if (apc < 0 || apc >= RTHAL_NR_APCS)
-        return -EINVAL;
-
-    rthal_local_irq_save(flags);
-
-    if (!__test_and_set_bit(apc, &rthal_apc_pending[rthal_processor_id()]))
-           rthal_schedule_irq_root(rthal_apc_virq);
-
-    rthal_local_irq_restore(flags);
-
-    return 0;
+       BUG_ON(apc < 0 || apc >= RTHAL_NR_APCS);
+        clear_bit(apc, &rthal_apc_map);
 }
 
 #ifdef CONFIG_PROC_FS
@@ -1100,6 +1049,29 @@ unsigned long long 
__rthal_generic_full_divmod64(unsigned long long a,
  * - Linux domain context.
  */
 
+/**
+ * @fn int rthal_apc_schedule (int apc)
+ *
+ * @brief Schedule an APC invocation.
+ *
+ * This service marks the APC as pending for the Linux domain, so that
+ * its handler will be called as soon as possible, when the Linux
+ * domain gets back in control.
+ *
+ * When posted from the Linux domain, the APC handler is fired as soon
+ * as the interrupt mask is explicitly cleared by some kernel
+ * code. When posted from the Xenomai domain, the APC handler is
+ * fired as soon as the Linux domain is resumed, i.e. after Xenomai has
+ * completed all its pending duties.
+ *
+ * @param apc The APC id. to schedule.
+ *
+ * This service can be called from:
+ *
+ * - Any domain context, albeit the usual calling place is from the
+ * Xenomai domain.
+ */
+
 /*...@}*/
 
 EXPORT_SYMBOL(rthal_irq_request);
@@ -1116,7 +1088,6 @@ EXPORT_SYMBOL(rthal_timer_release);
 EXPORT_SYMBOL(rthal_timer_calibrate);
 EXPORT_SYMBOL(rthal_apc_alloc);
 EXPORT_SYMBOL(rthal_apc_free);
-EXPORT_SYMBOL(rthal_apc_schedule);
 
 EXPORT_SYMBOL(rthal_critical_enter);
 EXPORT_SYMBOL(rthal_critical_exit);


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

Reply via email to