Use XADD to implement add_local(). Signed-off-by: Christoph Lameter --- arch/x86/include/asm/add-local.h | 56 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 55 insertions(+), 1 deletion(-) Index: linux-2.6/arch/x86/include/asm/add-local.h =================================================================== --- linux-2.6.orig/arch/x86/include/asm/add-local.h 2010-01-05 15:29:11.000000000 -0600 +++ linux-2.6/arch/x86/include/asm/add-local.h 2010-01-05 15:33:59.000000000 -0600 @@ -1,2 +1,56 @@ -#include +#ifndef __ASM_X86_ADD_LOCAL_H +#define __ASM_X86_ADD_LOCAL_H + +#include +#include + +static inline unsigned long __add_return_local(volatile void *ptr, + unsigned long value, int size) +{ + unsigned long r; + +#ifdef CONFIG_M386 + if (unlikely(boot_cpu_data.x86 <= 3)) + return __add_return_local_generic(ptr, value, size); +#endif + + /* + * Sanity checking, compile-time. + */ + if (size == 8 && sizeof(unsigned long) != 8) + wrong_size_add_local(ptr); + + r = value; + switch (size) { + case 1: + asm volatile("xaddb %0, %1;": "+r" (r), "+m" (*((u8 *)ptr)): + : "memory"); + break; + case 2: + asm volatile("xaddw %0, %1;": "+r" (r), "+m" (*((u16 *)ptr)): + : "memory"); + break; + case 4: + asm volatile("xaddl %0, %1;": "+r" (r), "+m" (*((u32 *)ptr)): + : "memory"); + break; + case 8: + asm volatile("xaddq %0, %1;": "+r" (r), "+m" (*((u64 *)ptr)): + : "memory"); + break; + default: + wrong_size_add_local(ptr); + } + return r + value; +} + +#define add_return_local(ptr, v) \ + ((__typeof__(*(ptr)))__add_return_local((ptr), (unsigned long)(v), \ + sizeof(*(ptr)))) + +#define add_local(ptr, v) (void)__add_return_local((ptr), (unsigned long)(v), \ + sizeof(*(ptr))) + + +#endif -- -- 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/