Messages in this thread Patch in this message |  | | | Date | Tue, 05 Jan 2010 16:04:20 -0600 | | From | Christoph Lameter <> | | Subject | [RFC local_t removal V1 3/4] Optimized add_local() |
| |
Use XADD to implement add_local().
Signed-off-by: Christoph Lameter <cl@linux-foundation.org>
--- 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 <asm-generic/add-local.h> +#ifndef __ASM_X86_ADD_LOCAL_H +#define __ASM_X86_ADD_LOCAL_H + +#include <linux/types.h> +#include <asm-generic/add-local-generic.h> + +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 --
|  |