mutex subsystem, add asm-generic/mutex-[dec|xchg|null].h implementations
PATCH 2/11 mutex subsystem, add asm-generic/mutex-[dec|xchg|null].h implementations
Add three (generic) mutex fastpath implementations.
The mutex-xchg.h implementation is atomic_xchg() based, and should work fine on every architecture.
The mutex-dec.h implementation is atomic_dec_return() based - this one too should work on every architecture, but might not perform the most optimally on architectures that have no atomic-dec/inc instructions.
The mutex-null.h implementation forces all calls into the slowpath. This is used for mutex debugging, but it can also be used on platforms that do not want (or need) a fastpath at all.
Signed-off-by Ingo Molnar <[email protected]>
Signed-off-by Arjan van de Ven <[email protected]>
----
include/asm-generic/mutex-dec.h | 66 +++++++++++++++++++++++++++++++++++ include/asm-generic/mutex-null.h | 23 ++++++++++++ include/asm-generic/mutex-xchg.h | 72 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 161 insertions(+)
include/asm-generic/mutex-dec.h new file +66 -0
@@ -0,0 +1,66 @@ +/* +* asm-generic/mutex-dec.h +* +* Generic implementation of the mutex fastpath, based on atomic +* decrement/increment. +*/ +#ifndef _ASM_GENERIC_MUTEX_DEC_H +#define _ASM_GENERIC_MUTEX_DEC_H + +/** +* __mutex_fastpath_lock - try to take the lock by moving the count +* from 1 to a 0 value +* @count: pointer of type atomic_t +* @fn: function to call if the original value was not 1 +* +* Change the count from 1 to a value lower than 1, and call <fn> if it +* wasn't 1 originally. This function MUST leave the value lower than 1 +* even when the "1" assertion wasn't true. +*/ +#define __mutex_fastpath_lock (count, fn) \ +do { \ + if (unlikely(atomic_dec_return(count) < 0)) \ + fn(count); \ +} while (0) + +/** +* __mutex_fastpath_lock_retval - try to take the lock by moving the count +* from 1 to a 0 value +* @count: pointer of type atomic_t +* @fn: function to call if the original value was not 1 +* +* Change the count from 1 to a value lower than 1, and call <fn> if it +* wasn't 1 originally. This function returns 0 if the fastpath succeeds, +* or anything the slow path function returns. +*/ +static inline int +__mutex_fastpath_lock_retval (atomic_t *count,int (*fn)(atomic_t *)) +{ +if (unlikely (atomic_dec_return (count) <0 )) +return fn (count); +else +return 0 ; +} + +/** +* __mutex_fastpath_unlock - try to promote the count from 0 to 1 +* @count: pointer of type atomic_t +* @fn: function to call if the original value was not 0 +* +* Try to promote the count from 0 to 1. If it wasn't 0, call <fn>. +* In the failure case, this function is allowed to either set the value to +* 1, or to set it to a value lower than 1. +* +* If the implementation sets it to a value of lower than 1, then the +* __mutex_slowpath_needs_to_unlock() macro needs to return 1, it needs +* to return 0 otherwise. +*/ +#define __mutex_fastpath_unlock (count, fn) \ +do { \ + if (unlikely(atomic_inc_return(count) <= 0)) \ + fn(count); \ +} while (0) + +#define __mutex_slowpath_needs_to_unlock () 1 + +#endif
include/asm-generic/mutex-null.h new file +23 -0
@@ -0,0 +1,23 @@ +/* +* asm-generic/mutex-null.h +* +* Generic implementation of the mutex fastpath, based on NOP :-) +* +* This is used by the mutex-debugging infrastructure, but it can also +* be used by architectures that (for whatever reason) want to use the +* spinlock based slowpath. +*/ +#ifndef _ASM_GENERIC_MUTEX_NULL_H +#define _ASM_GENERIC_MUTEX_NULL_H + +/* extra parameter only needed for mutex debugging: */ +#ifndef __IP__ +# define __IP__ +#endif + +#define __mutex_fastpath_lock (count, fn_name) fn_name(count __IP__) +#define __mutex_fastpath_lock_retval (count, fn_name) fn_name(count __IP__) +#define __mutex_fastpath_unlock (count, fn_name) fn_name(count __IP__) +#define __mutex_slowpath_needs_to_unlock () 1 + +#endif
include/asm-generic/mutex-xchg.h new file +72 -0
72 lines not on this page · raw message