From: Mathieu Desnoyers Date: Tue, 22 Sep 2009 21:09:55 +0000 (-0400) Subject: Add inc/dec x86 atomics X-Git-Tag: v0.1~56 X-Git-Url: http://git.liburcu.org/?p=urcu.git;a=commitdiff_plain;h=87322fe8f9e201f9018dba7dfcf786b932cd899c Add inc/dec x86 atomics Signed-off-by: Mathieu Desnoyers --- diff --git a/arch_atomic_x86.h b/arch_atomic_x86.h index 3422cb4..fdd3d6b 100644 --- a/arch_atomic_x86.h +++ b/arch_atomic_x86.h @@ -167,7 +167,8 @@ void _atomic_add(volatile void *addr, unsigned long val, int len) __asm__ __volatile__( "lock; addb %1, %0" : "=m"(*__hp(addr)) - : "q" ((unsigned char)val)); + : "iq" ((unsigned char)val) + : "memory"); return; } case 2: @@ -175,7 +176,8 @@ void _atomic_add(volatile void *addr, unsigned long val, int len) __asm__ __volatile__( "lock; addw %1, %0" : "=m"(*__hp(addr)) - : "r" ((unsigned short)val)); + : "ir" ((unsigned short)val) + : "memory"); return; } case 4: @@ -183,7 +185,8 @@ void _atomic_add(volatile void *addr, unsigned long val, int len) __asm__ __volatile__( "lock; addl %1, %0" : "=m"(*__hp(addr)) - : "r" ((unsigned int)val)); + : "ir" ((unsigned int)val) + : "memory"); return; } #if (BITS_PER_LONG == 64) @@ -192,7 +195,8 @@ void _atomic_add(volatile void *addr, unsigned long val, int len) __asm__ __volatile__( "lock; addq %1, %0" : "=m"(*__hp(addr)) - : "r" ((unsigned long)val)); + : "er" ((unsigned long)val) + : "memory"); return; } #endif diff --git a/tests/test_atomic.c b/tests/test_atomic.c index 47cc319..bf84757 100644 --- a/tests/test_atomic.c +++ b/tests/test_atomic.c @@ -11,10 +11,32 @@ struct testvals { static struct testvals vals; -int main(int argc, void **argv) +#define do_test(ptr) \ +do { \ + __typeof__(*ptr) v; \ + \ + atomic_add(ptr, 10); \ + assert(*ptr == 10); \ + atomic_add(ptr, -11); \ + assert(*ptr == (__typeof__(*ptr))-1U); \ + v = cmpxchg(ptr, -1, 22); \ + assert(*ptr == 22); \ + assert(v == (__typeof__(*ptr))-1U); \ + v = cmpxchg(ptr, 33, 44); \ + assert(*ptr == 22); \ + assert(v == 22); \ + v = xchg(ptr, 55); \ + assert(*ptr == 55); \ + assert(v == 22); \ +} while (0) + +int main(int argc, char **argv) { - atomic_add(&vals.c, 10); - assert(vals.c == 10); - atomic_add(&vals.c, -11); - assert((char)vals.c == -1); + do_test(&vals.c); + do_test(&vals.s); + do_test(&vals.i); + do_test(&vals.l); + printf("Atomic ops test OK\n"); + + return 0; }