Module: xenomai-gch Branch: for-forge Commit: b250877880c19921dc552dc4df0351f04ab73ff4 URL: http://git.xenomai.org/?p=xenomai-gch.git;a=commit;h=b250877880c19921dc552dc4df0351f04ab73ff4
Author: Gilles Chanteperdrix <[email protected]> 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 [email protected] https://mail.gna.org/listinfo/xenomai-git
