Module: xenomai-gch
Branch: for-forge
Commit: 87d6615a4572e945bdaaf6609e47e82235606d6f
URL:    
http://git.xenomai.org/?p=xenomai-gch.git;a=commit;h=87d6615a4572e945bdaaf6609e47e82235606d6f

Author: Gilles Chanteperdrix <gilles.chanteperd...@xenomai.org>
Date:   Mon Feb 24 01:21:08 2014 +0100

cobalt/xnlock: allow moving out-of-line

And use the ipipe_smp_p predicate to allow self-modifying code to disable
the xnlocks when running an SMP kernel on an UP machine.

---

 include/cobalt/kernel/lock.h   |   45 +++++++++++++++++++++++++++++++---------
 kernel/cobalt/arch/arm/Kconfig |    4 ++++
 kernel/cobalt/lock.c           |   17 +++++++++++++--
 3 files changed, 54 insertions(+), 12 deletions(-)

diff --git a/include/cobalt/kernel/lock.h b/include/cobalt/kernel/lock.h
index ea7cfed..25644f8 100644
--- a/include/cobalt/kernel/lock.h
+++ b/include/cobalt/kernel/lock.h
@@ -153,27 +153,27 @@ static inline void xnlock_init (struct xnlock *lock)
 #define DEFINE_XNLOCK(lock)            struct xnlock lock = 
XNARCH_LOCK_UNLOCKED
 #define DEFINE_PRIVATE_XNLOCK(lock)    static DEFINE_XNLOCK(lock)
 
-void __xnlock_spin(struct xnlock *lock /*, */ XNLOCK_DBG_CONTEXT_ARGS);
+void __xnlock_spin(int cpu, struct xnlock *lock /*, */ 
XNLOCK_DBG_CONTEXT_ARGS);
 
-static inline int __xnlock_get(struct xnlock *lock /*, */ 
XNLOCK_DBG_CONTEXT_ARGS)
+static inline int ____xnlock_get(struct xnlock *lock /*, */ 
XNLOCK_DBG_CONTEXT_ARGS)
 {
        int cpu = ipipe_processor_id();
        unsigned long long start;
 
        if (atomic_read(&lock->owner) == cpu)
-               return 1;
+               return 2;
 
        xnlock_dbg_prepare_acquire(&start);
 
        if (unlikely(atomic_cmpxchg(&lock->owner, ~0, cpu) != ~0))
-               __xnlock_spin(lock /*, */ XNLOCK_DBG_PASS_CONTEXT);
+               __xnlock_spin(cpu, lock /*, */ XNLOCK_DBG_PASS_CONTEXT);
 
        xnlock_dbg_acquired(lock, cpu, &start /*, */ XNLOCK_DBG_PASS_CONTEXT);
 
        return 0;
 }
 
-static inline void __xnlock_put(struct xnlock *lock /*, */ 
XNLOCK_DBG_CONTEXT_ARGS)
+static inline void ____xnlock_put(struct xnlock *lock /*, */ 
XNLOCK_DBG_CONTEXT_ARGS)
 {
        if (xnlock_dbg_release(lock /*, */ XNLOCK_DBG_PASS_CONTEXT))
                return;
@@ -186,6 +186,15 @@ static inline void __xnlock_put(struct xnlock *lock /*, */ 
XNLOCK_DBG_CONTEXT_AR
        atomic_set(&lock->owner, ~0);
 }
 
+#ifndef CONFIG_XENO_HW_OUTOFLINE_XNLOCK
+#define ___xnlock_get ____xnlock_get
+#define ___xnlock_put ____xnlock_put
+#else /* out of line xnlock */
+int ___xnlock_get(struct xnlock *lock /*, */ XNLOCK_DBG_CONTEXT_ARGS);
+
+void ___xnlock_put(struct xnlock *lock /*, */ XNLOCK_DBG_CONTEXT_ARGS);
+#endif /* out of line xnlock */
+
 static inline spl_t
 __xnlock_get_irqsave(struct xnlock *lock /*, */ XNLOCK_DBG_CONTEXT_ARGS)
 {
@@ -193,8 +202,8 @@ __xnlock_get_irqsave(struct xnlock *lock /*, */ 
XNLOCK_DBG_CONTEXT_ARGS)
 
        splhigh(flags);
 
-       if (__xnlock_get(lock /*, */ XNLOCK_DBG_PASS_CONTEXT))
-               flags |= 2;     /* Recursive acquisition */
+       if (ipipe_smp_p)
+               flags |= ___xnlock_get(lock /*, */ XNLOCK_DBG_PASS_CONTEXT);
 
        return flags;
 }
@@ -203,15 +212,31 @@ static inline void __xnlock_put_irqrestore(struct xnlock 
*lock, spl_t flags
                                           /*, */ XNLOCK_DBG_CONTEXT_ARGS)
 {
        /* Only release the lock if we didn't take it recursively. */
-       if (!(flags & 2))
-               __xnlock_put(lock /*, */ XNLOCK_DBG_PASS_CONTEXT);
+       if (ipipe_smp_p && !(flags & 2))
+               ___xnlock_put(lock /*, */ XNLOCK_DBG_PASS_CONTEXT);
 
        splexit(flags & 1);
 }
 
 static inline int xnlock_is_owner(struct xnlock *lock)
 {
-       return atomic_read(&lock->owner) == ipipe_processor_id();
+       if (ipipe_smp_p)
+               return atomic_read(&lock->owner) == ipipe_processor_id();
+       return hard_irqs_disabled();
+}
+
+static inline int __xnlock_get(struct xnlock *lock /*, */ 
XNLOCK_DBG_CONTEXT_ARGS)
+{
+       if (ipipe_smp_p)
+               return ___xnlock_get(lock /* , */ XNLOCK_DBG_PASS_CONTEXT);
+
+       return 0;
+}
+
+static inline void __xnlock_put(struct xnlock *lock /*, */ 
XNLOCK_DBG_CONTEXT_ARGS)
+{
+       if (ipipe_smp_p)
+               ___xnlock_put(lock /*, */ XNLOCK_DBG_PASS_CONTEXT);     
 }
 
 #else /* !(CONFIG_SMP || XENO_DEBUG(XNLOCK) */
diff --git a/kernel/cobalt/arch/arm/Kconfig b/kernel/cobalt/arch/arm/Kconfig
index 001ed1d..f8c2223 100644
--- a/kernel/cobalt/arch/arm/Kconfig
+++ b/kernel/cobalt/arch/arm/Kconfig
@@ -38,6 +38,10 @@ config XENO_HW_UNLOCKED_SWITCH
        You definitely want to enable that option on low-end ARM
        platforms.
 
+config XENO_HW_OUTOFLINE_XNLOCK
+       bool
+       default y
+
 endmenu
 
 source "kernel/xenomai/Kconfig"
diff --git a/kernel/cobalt/lock.c b/kernel/cobalt/lock.c
index edc250c..dd87c66 100644
--- a/kernel/cobalt/lock.c
+++ b/kernel/cobalt/lock.c
@@ -30,9 +30,8 @@ DEFINE_XNLOCK(nklock);
 #if defined(CONFIG_SMP) || XENO_DEBUG(XNLOCK)
 EXPORT_SYMBOL_GPL(nklock);
 
-void __xnlock_spin(struct xnlock *lock /*, */ XNLOCK_DBG_CONTEXT_ARGS)
+void __xnlock_spin(int cpu, struct xnlock *lock /*, */ XNLOCK_DBG_CONTEXT_ARGS)
 {
-       int cpu = ipipe_processor_id();
        unsigned int spin_limit;
 
        xnlock_dbg_prepare_spin(&spin_limit);
@@ -45,6 +44,20 @@ void __xnlock_spin(struct xnlock *lock /*, */ 
XNLOCK_DBG_CONTEXT_ARGS)
                } while(atomic_read(&lock->owner) != ~0);
 }
 EXPORT_SYMBOL_GPL(__xnlock_spin);
+
+#ifdef CONFIG_XENO_HW_OUTOFLINE_XNLOCK
+int ___xnlock_get(struct xnlock *lock /*, */ XNLOCK_DBG_CONTEXT_ARGS)
+{
+       return ____xnlock_get(lock /* , */ XNLOCK_DBG_PASS_CONTEXT);
+}
+EXPORT_SYMBOL_GPL(___xnlock_get);
+
+void ___xnlock_put(struct xnlock *lock /*, */ XNLOCK_DBG_CONTEXT_ARGS)
+{
+       ____xnlock_put(lock /* , */ XNLOCK_DBG_PASS_CONTEXT);
+}
+EXPORT_SYMBOL_GPL(___xnlock_put);
+#endif /* out of line xnlock */
 #endif /* CONFIG_SMP || XENO_DEBUG(XNLOCK) */
 
 #if XENO_DEBUG(XNLOCK)


_______________________________________________
Xenomai-git mailing list
Xenomai-git@xenomai.org
http://www.xenomai.org/mailman/listinfo/xenomai-git

Reply via email to