PICK_FUNCTION() is similar to the other PICK_OP style macros, and was created to replace them all. I used variable argument macros to handle PICK_FUNC_2ARG/PICK_FUNC_1ARG. Otherwise the marcos are similar to the original macros used for semaphores. The entire system is used to do a compile time switch between two different locking APIs. For example, real spinlocks (raw_spinlock_t) and mutexes (or sleeping spinlocks). This new macro replaces all the duplication from lock type to lock type. The result of this patch, and the next two, is a fairly nice simplification, and consolidation. Although the seqlock changes are larger than the originals I think over all the patchset is worth while. Signed-off-by: Daniel Walker --- include/linux/pickop.h | 32 +++++++++++ include/linux/rt_lock.h | 129 +++++++++++++++--------------------------------- 2 files changed, 73 insertions(+), 88 deletions(-) Index: linux-2.6.22/include/linux/pickop.h =================================================================== --- /dev/null +++ linux-2.6.22/include/linux/pickop.h @@ -0,0 +1,32 @@ +#ifndef _LINUX_PICKOP_H +#define _LINUX_PICKOP_H + +#undef TYPE_EQUAL +#define TYPE_EQUAL(var, type) \ + __builtin_types_compatible_p(typeof(var), type *) + +extern int __bad_func_type(void); + +#define PICK_FUNCTION(type1, type2, func1, func2, arg0, ...) \ +do { \ + if (TYPE_EQUAL((arg0), type1)) \ + func1((type1 *)(arg0), ##__VA_ARGS__); \ + else if (TYPE_EQUAL((arg0), type2)) \ + func2((type2 *)(arg0), ##__VA_ARGS__); \ + else __bad_func_type(); \ +} while (0) + +#define PICK_FUNCTION_RET(type1, type2, func1, func2, arg0, ...) \ +({ \ + unsigned long __ret; \ + \ + if (TYPE_EQUAL((arg0), type1)) \ + __ret = func1((type1 *)(arg0), ##__VA_ARGS__); \ + else if (TYPE_EQUAL((arg0), type2)) \ + __ret = func2((type2 *)(arg0), ##__VA_ARGS__); \ + else __ret = __bad_func_type(); \ + \ + __ret; \ +}) + +#endif /* _LINUX_PICKOP_H */ Index: linux-2.6.22/include/linux/rt_lock.h =================================================================== --- linux-2.6.22.orig/include/linux/rt_lock.h +++ linux-2.6.22/include/linux/rt_lock.h @@ -156,76 +156,40 @@ extern void fastcall rt_up(struct semaph extern int __bad_func_type(void); -#undef TYPE_EQUAL -#define TYPE_EQUAL(var, type) \ - __builtin_types_compatible_p(typeof(var), type *) - -#define PICK_FUNC_1ARG(type1, type2, func1, func2, arg) \ -do { \ - if (TYPE_EQUAL((arg), type1)) \ - func1((type1 *)(arg)); \ - else if (TYPE_EQUAL((arg), type2)) \ - func2((type2 *)(arg)); \ - else __bad_func_type(); \ -} while (0) +#include -#define PICK_FUNC_1ARG_RET(type1, type2, func1, func2, arg) \ -({ \ - unsigned long __ret; \ - \ - if (TYPE_EQUAL((arg), type1)) \ - __ret = func1((type1 *)(arg)); \ - else if (TYPE_EQUAL((arg), type2)) \ - __ret = func2((type2 *)(arg)); \ - else __ret = __bad_func_type(); \ - \ - __ret; \ -}) - -#define PICK_FUNC_2ARG(type1, type2, func1, func2, arg0, arg1) \ -do { \ - if (TYPE_EQUAL((arg0), type1)) \ - func1((type1 *)(arg0), arg1); \ - else if (TYPE_EQUAL((arg0), type2)) \ - func2((type2 *)(arg0), arg1); \ - else __bad_func_type(); \ -} while (0) +/* + * PICK_SEM_OP() is a small redirector to allow less typing of the lock + * types struct compat_semaphore, struct semaphore, at the front of the + * PICK_FUNCTION macro. + */ +#define PICK_SEM_OP(...) PICK_FUNCTION(struct compat_semaphore, \ + struct semaphore, ##__VA_ARGS__) +#define PICK_SEM_OP_RET(...) PICK_FUNCTION_RET(struct compat_semaphore,\ + struct semaphore, ##__VA_ARGS__) #define sema_init(sem, val) \ - PICK_FUNC_2ARG(struct compat_semaphore, struct semaphore, \ - compat_sema_init, rt_sema_init, sem, val) + PICK_SEM_OP(compat_sema_init, rt_sema_init, sem, val) -#define init_MUTEX(sem) \ - PICK_FUNC_1ARG(struct compat_semaphore, struct semaphore, \ - compat_init_MUTEX, rt_init_MUTEX, sem) +#define init_MUTEX(sem) PICK_SEM_OP(compat_init_MUTEX, rt_init_MUTEX, sem) #define init_MUTEX_LOCKED(sem) \ - PICK_FUNC_1ARG(struct compat_semaphore, struct semaphore, \ - compat_init_MUTEX_LOCKED, rt_init_MUTEX_LOCKED, sem) + PICK_SEM_OP(compat_init_MUTEX_LOCKED, rt_init_MUTEX_LOCKED, sem) -#define down(sem) \ - PICK_FUNC_1ARG(struct compat_semaphore, struct semaphore, \ - compat_down, rt_down, sem) +#define down(sem) PICK_SEM_OP(compat_down, rt_down, sem) #define down_interruptible(sem) \ - PICK_FUNC_1ARG_RET(struct compat_semaphore, struct semaphore, \ - compat_down_interruptible, rt_down_interruptible, sem) + PICK_SEM_OP_RET(compat_down_interruptible, rt_down_interruptible, sem) #define down_trylock(sem) \ - PICK_FUNC_1ARG_RET(struct compat_semaphore, struct semaphore, \ - compat_down_trylock, rt_down_trylock, sem) + PICK_SEM_OP_RET(compat_down_trylock, rt_down_trylock, sem) -#define up(sem) \ - PICK_FUNC_1ARG(struct compat_semaphore, struct semaphore, \ - compat_up, rt_up, sem) +#define up(sem) PICK_SEM_OP(compat_up, rt_up, sem) #define sem_is_locked(sem) \ - PICK_FUNC_1ARG_RET(struct compat_semaphore, struct semaphore, \ - compat_sem_is_locked, rt_sem_is_locked, sem) + PICK_SEM_OP_RET(compat_sem_is_locked, rt_sem_is_locked, sem) -#define sema_count(sem) \ - PICK_FUNC_1ARG_RET(struct compat_semaphore, struct semaphore, \ - compat_sema_count, rt_sema_count, sem) +#define sema_count(sem) PICK_SEM_OP_RET(compat_sema_count, rt_sema_count, sem) /* * rwsems: @@ -272,58 +236,47 @@ extern void fastcall rt_downgrade_write( # define rt_rwsem_is_locked(rws) (rt_mutex_is_locked(&(rws)->lock)) -#define init_rwsem(rwsem) \ - PICK_FUNC_1ARG(struct compat_rw_semaphore, struct rw_semaphore, \ - compat_init_rwsem, rt_init_rwsem, rwsem) - -#define down_read(rwsem) \ - PICK_FUNC_1ARG(struct compat_rw_semaphore, struct rw_semaphore, \ - compat_down_read, rt_down_read, rwsem) +#define PICK_RWSEM_OP(...) PICK_FUNCTION(struct compat_rw_semaphore, \ + struct rw_semaphore, ##__VA_ARGS__) +#define PICK_RWSEM_OP_RET(...) PICK_FUNCTION_RET(struct compat_rw_semaphore,\ + struct rw_semaphore, ##__VA_ARGS__) + +#define init_rwsem(rwsem) PICK_RWSEM_OP(compat_init_rwsem, rt_init_rwsem, rwsem) + +#define down_read(rwsem) PICK_RWSEM_OP(compat_down_read, rt_down_read, rwsem) #define down_read_non_owner(rwsem) \ - PICK_FUNC_1ARG(struct compat_rw_semaphore, struct rw_semaphore, \ - compat_down_read_non_owner, rt_down_read_non_owner, rwsem) + PICK_RWSEM_OP(compat_down_read_non_owner, rt_down_read_non_owner, rwsem) #define down_read_trylock(rwsem) \ - PICK_FUNC_1ARG_RET(struct compat_rw_semaphore, struct rw_semaphore, \ - compat_down_read_trylock, rt_down_read_trylock, rwsem) + PICK_RWSEM_OP_RET(compat_down_read_trylock, rt_down_read_trylock, rwsem) -#define down_write(rwsem) \ - PICK_FUNC_1ARG(struct compat_rw_semaphore, struct rw_semaphore, \ - compat_down_write, rt_down_write, rwsem) +#define down_write(rwsem) PICK_RWSEM_OP(compat_down_write, rt_down_write, rwsem) #define down_read_nested(rwsem, subclass) \ - PICK_FUNC_2ARG(struct compat_rw_semaphore, struct rw_semaphore, \ - compat_down_read_nested, rt_down_read_nested, rwsem, subclass) - + PICK_RWSEM_OP(compat_down_read_nested, rt_down_read_nested, \ + rwsem, subclass) #define down_write_nested(rwsem, subclass) \ - PICK_FUNC_2ARG(struct compat_rw_semaphore, struct rw_semaphore, \ - compat_down_write_nested, rt_down_write_nested, rwsem, subclass) + PICK_RWSEM_OP(compat_down_write_nested, rt_down_write_nested, \ + rwsem, subclass) #define down_write_trylock(rwsem) \ - PICK_FUNC_1ARG_RET(struct compat_rw_semaphore, struct rw_semaphore, \ - compat_down_write_trylock, rt_down_write_trylock, rwsem) + PICK_RWSEM_OP_RET(compat_down_write_trylock, rt_down_write_trylock,\ + rwsem) -#define up_read(rwsem) \ - PICK_FUNC_1ARG(struct compat_rw_semaphore, struct rw_semaphore, \ - compat_up_read, rt_up_read, rwsem) +#define up_read(rwsem) PICK_RWSEM_OP(compat_up_read, rt_up_read, rwsem) #define up_read_non_owner(rwsem) \ - PICK_FUNC_1ARG(struct compat_rw_semaphore, struct rw_semaphore, \ - compat_up_read_non_owner, rt_up_read_non_owner, rwsem) + PICK_RWSEM_OP(compat_up_read_non_owner, rt_up_read_non_owner, rwsem) -#define up_write(rwsem) \ - PICK_FUNC_1ARG(struct compat_rw_semaphore, struct rw_semaphore, \ - compat_up_write, rt_up_write, rwsem) +#define up_write(rwsem) PICK_RWSEM_OP(compat_up_write, rt_up_write, rwsem) #define downgrade_write(rwsem) \ - PICK_FUNC_1ARG(struct compat_rw_semaphore, struct rw_semaphore, \ - compat_downgrade_write, rt_downgrade_write, rwsem) + PICK_RWSEM_OP(compat_downgrade_write, rt_downgrade_write, rwsem) #define rwsem_is_locked(rwsem) \ - PICK_FUNC_1ARG_RET(struct compat_rw_semaphore, struct rw_semaphore, \ - compat_rwsem_is_locked, rt_rwsem_is_locked, rwsem) + PICK_RWSEM_OP_RET(compat_rwsem_is_locked, rt_rwsem_is_locked, rwsem) #endif /* CONFIG_PREEMPT_RT */ -- - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/