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

Author: Gilles Chanteperdrix <gilles.chanteperd...@xenomai.org>
Date:   Sat Nov 12 22:42:12 2011 +0100

nucleus: preserve xnsynch spare bits even for fast operations

---

 include/cobalt/nucleus/synch.h |   28 +++++++++++++++++++++-------
 kernel/cobalt/nucleus/synch.c  |   27 +++++++++++++++------------
 2 files changed, 36 insertions(+), 19 deletions(-)

diff --git a/include/cobalt/nucleus/synch.h b/include/cobalt/nucleus/synch.h
index bcfb4d3..3cb6e3f 100644
--- a/include/cobalt/nucleus/synch.h
+++ b/include/cobalt/nucleus/synch.h
@@ -37,6 +37,7 @@
 #endif /* CONFIG_XENO_OPT_DEBUG_SYNCH_RELAX */
 
 #ifdef CONFIG_XENO_FASTSYNCH
+#define XNSYNCH_FLCLAIM XN_HANDLE_SPARE3 /* Corresponding bit in fast lock */
 
 /* Fast lock API */
 static inline int xnsynch_fast_owner_check(xnarch_atomic_t *fastlock,
@@ -46,13 +47,24 @@ static inline int xnsynch_fast_owner_check(xnarch_atomic_t 
*fastlock,
                0 : -EPERM;
 }
 
+static inline int xnsynch_fast_check_spares(xnarch_atomic_t *fastlock,
+                                           unsigned spares)
+{
+       return (xnhandle_test_spares(xnarch_atomic_get(fastlock), spares));
+}
+
+
 static inline int xnsynch_fast_acquire(xnarch_atomic_t *fastlock,
                                       xnhandle_t new_ownerh)
 {
-       xnhandle_t lock_state =
-           xnarch_atomic_cmpxchg(fastlock, XN_NO_HANDLE, new_ownerh);
+       xnhandle_t lock_state, old, spares;
+
+       spares = xnhandle_get_spares(xnarch_atomic_get(fastlock),
+                                    XN_HANDLE_SPARE_MASK);
+       old = XN_NO_HANDLE | spares;
+       lock_state = xnarch_atomic_cmpxchg(fastlock, old, new_ownerh | spares);
 
-       if (likely(lock_state == XN_NO_HANDLE))
+       if (likely(lock_state == old))
                return 0;
 
        if (xnhandle_mask_spares(lock_state) == new_ownerh)
@@ -64,8 +76,12 @@ static inline int xnsynch_fast_acquire(xnarch_atomic_t 
*fastlock,
 static inline int xnsynch_fast_release(xnarch_atomic_t *fastlock,
                                       xnhandle_t cur_ownerh)
 {
-       return (xnarch_atomic_cmpxchg(fastlock, cur_ownerh, XN_NO_HANDLE) ==
-               cur_ownerh);
+       xnhandle_t spares = xnhandle_get_spares(xnarch_atomic_get(fastlock),
+                                               XN_HANDLE_SPARE_MASK &
+                                               ~XNSYNCH_FLCLAIM);
+       cur_ownerh |= spares;
+       return (xnarch_atomic_cmpxchg(fastlock, cur_ownerh,
+                                     XN_NO_HANDLE | spares) == cur_ownerh);
 }
 
 #else /* !CONFIG_XENO_FASTSYNCH */
@@ -88,8 +104,6 @@ static inline int xnsynch_fast_release(xnarch_atomic_t 
*fastlock,
 
 #define XNSYNCH_CLAIMED 0x10   /* Claimed by other thread(s) w/ PIP */
 
-#define XNSYNCH_FLCLAIM XN_HANDLE_SPARE3 /* Corresponding bit in fast lock */
-
 /* Spare flags usable by upper interfaces */
 #define XNSYNCH_SPARE0  0x01000000
 #define XNSYNCH_SPARE1  0x02000000
diff --git a/kernel/cobalt/nucleus/synch.c b/kernel/cobalt/nucleus/synch.c
index 8dc1c52..9c8a8fb 100644
--- a/kernel/cobalt/nucleus/synch.c
+++ b/kernel/cobalt/nucleus/synch.c
@@ -401,7 +401,7 @@ xnflags_t xnsynch_acquire(struct xnsynch *synch, xnticks_t 
timeout,
                          xntmode_t timeout_mode)
 {
        struct xnthread *thread = xnpod_current_thread(), *owner;
-       xnhandle_t threadh = xnthread_handle(thread), fastlock, old;
+       xnhandle_t threadh = xnthread_handle(thread), fastlock, old, spares;
        const int use_fastlock = xnsynch_fastlock_p(synch);
        spl_t s;
 
@@ -414,10 +414,12 @@ xnflags_t xnsynch_acquire(struct xnsynch *synch, 
xnticks_t timeout,
        if (use_fastlock) {
                xnarch_atomic_t *lockp = xnsynch_fastlock(synch);
 
-               fastlock = xnarch_atomic_cmpxchg(lockp,
-                                                XN_NO_HANDLE, threadh);
+               spares = xnhandle_get_spares(xnarch_atomic_get(lockp),
+                                            XN_HANDLE_SPARE_MASK);
+               old = XN_NO_HANDLE | spares;
+               fastlock = xnarch_atomic_cmpxchg(lockp, old, threadh | spares);
 
-               if (likely(fastlock == XN_NO_HANDLE)) {
+               if (likely(fastlock == old)) {
                        if (xnthread_test_state(thread, XNOTHER))
                                xnthread_inc_rescnt(thread);
                        xnthread_clear_info(thread,
@@ -543,13 +545,12 @@ xnflags_t xnsynch_acquire(struct xnsynch *synch, 
xnticks_t timeout,
                        xnarch_atomic_t *lockp = xnsynch_fastlock(synch);
                        /* We are the new owner, update the fastlock
                           accordingly. */
-                       fastlock = threadh |
-                               xnhandle_get_spares(xnarch_atomic_get(lockp),
-                                                   XN_HANDLE_SPARE_MASK);
-                       fastlock =
-                               xnsynch_fast_set_claimed(fastlock,
+                       threah |= xnhandle_get_spares(xnarch_atomic_get(lockp),
+                                                      XN_HANDLE_SPARE_MASK);
+                       threadh;
+                               xnsynch_fast_set_claimed(threadh,
                                                         
xnsynch_pended_p(synch));
-                       xnarch_atomic_set(lockp, fastlock);
+                       xnarch_atomic_set(lockp, threadh);
                }
        }
 
@@ -719,8 +720,10 @@ xnsynch_release_thread(struct xnsynch *synch, struct 
xnthread *lastowner)
        }
        if (use_fastlock) {
                xnarch_atomic_t *lockp = xnsynch_fastlock(synch);
-               newownerh |= xnhandle_get_spares(xnarch_atomic_get(lockp),
-                                                XN_HANDLE_SPARE_MASK & 
~XNSYNCH_FLCLAIM);
+               newownerh |=
+                       xnhandle_get_spares(xnarch_atomic_get(lockp),
+                                           XN_HANDLE_SPARE_MASK
+                                           & ~XNSYNCH_FLCLAIM);
                xnarch_atomic_set(lockp, newownerh);
        }
 


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

Reply via email to