diff options
-rw-r--r-- | ChangeLog | 6 | ||||
-rw-r--r-- | sysdeps/i386/i486/bits/atomic.h | 22 | ||||
-rw-r--r-- | sysdeps/x86_64/bits/atomic.h | 24 |
3 files changed, 41 insertions, 11 deletions
diff --git a/ChangeLog b/ChangeLog index 05e4a43dea..c3703cb1ed 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,11 @@ 2007-01-12 Ulrich Drepper <drepper@redhat.com> + * sysdeps/i386/i486/bits/atomic.h: Define + atomic_compare_and_exchange_val_acq, + atomic_compare_and_exchange_bool_acq, and atomic_exchange_and_add + using __sync_* built-ins for gcc >= 4.1. + * sysdeps/x86_64/bits/atomic.h: Likewise. + [BZ #3840] * scripts/check-local-headers.sh: Restrict to testing .o.d, .os.d, and .oS.d files. diff --git a/sysdeps/i386/i486/bits/atomic.h b/sysdeps/i386/i486/bits/atomic.h index a27734c37e..4577499d58 100644 --- a/sysdeps/i386/i486/bits/atomic.h +++ b/sysdeps/i386/i486/bits/atomic.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2002, 2003, 2004, 2006 Free Software Foundation, Inc. +/* Copyright (C) 2002, 2003, 2004, 2006, 2007 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper <drepper@redhat.com>, 2002. @@ -56,26 +56,33 @@ typedef uintmax_t uatomic_max_t; #endif -#define __arch_compare_and_exchange_val_8_acq(mem, newval, oldval) \ +#if __GNUC_PREREQ (4, 1) +# define atomic_compare_and_exchange_val_acq(mem, newval, oldval) \ + __sync_val_compare_and_swap (mem, oldval, newval) +# define atomic_compare_and_exchange_bool_acq(mem, newval, oldval) \ + (! __sync_bool_compare_and_swap (mem, oldval, newval)) +#else +# define __arch_compare_and_exchange_val_8_acq(mem, newval, oldval) \ ({ __typeof (*mem) ret; \ __asm __volatile (LOCK_PREFIX "cmpxchgb %b2, %1" \ : "=a" (ret), "=m" (*mem) \ : "q" (newval), "m" (*mem), "0" (oldval)); \ ret; }) -#define __arch_compare_and_exchange_val_16_acq(mem, newval, oldval) \ +# define __arch_compare_and_exchange_val_16_acq(mem, newval, oldval) \ ({ __typeof (*mem) ret; \ __asm __volatile (LOCK_PREFIX "cmpxchgw %w2, %1" \ : "=a" (ret), "=m" (*mem) \ : "r" (newval), "m" (*mem), "0" (oldval)); \ ret; }) -#define __arch_compare_and_exchange_val_32_acq(mem, newval, oldval) \ +# define __arch_compare_and_exchange_val_32_acq(mem, newval, oldval) \ ({ __typeof (*mem) ret; \ __asm __volatile (LOCK_PREFIX "cmpxchgl %2, %1" \ : "=a" (ret), "=m" (*mem) \ : "r" (newval), "m" (*mem), "0" (oldval)); \ ret; }) +#endif #define __arch_c_compare_and_exchange_val_8_acq(mem, newval, oldval) \ @@ -240,8 +247,13 @@ typedef uintmax_t uatomic_max_t; } \ __result; }) -#define atomic_exchange_and_add(mem, value) \ +#if __GNUC_PREREQ (4, 1) +# define atomic_exchange_and_add(mem, value) \ + __sync_fetch_and_add (mem, value) +#else +# define atomic_exchange_and_add(mem, value) \ __arch_exchange_and_add_body (LOCK_PREFIX, __arch, mem, value) +#endif #define __arch_exchange_and_add_cprefix \ "cmpl $0, %%gs:%P4\n\tje 0f\n\tlock\n0:\t" diff --git a/sysdeps/x86_64/bits/atomic.h b/sysdeps/x86_64/bits/atomic.h index 65d6b02008..80e8a0bccb 100644 --- a/sysdeps/x86_64/bits/atomic.h +++ b/sysdeps/x86_64/bits/atomic.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2002, 2003, 2004, 2006 Free Software Foundation, Inc. +/* Copyright (C) 2002, 2003, 2004, 2006, 2007 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper <drepper@redhat.com>, 2002. @@ -56,34 +56,41 @@ typedef uintmax_t uatomic_max_t; #endif -#define __arch_compare_and_exchange_val_8_acq(mem, newval, oldval) \ +#if __GNUC_PREREQ (4, 1) +# define atomic_compare_and_exchange_val_acq(mem, newval, oldval) \ + __sync_val_compare_and_swap (mem, oldval, newval) +# define atomic_compare_and_exchange_bool_acq(mem, newval, oldval) \ + (! __sync_bool_compare_and_swap (mem, oldval, newval)) +#else +# define __arch_compare_and_exchange_val_8_acq(mem, newval, oldval) \ ({ __typeof (*mem) ret; \ __asm __volatile (LOCK_PREFIX "cmpxchgb %b2, %1" \ : "=a" (ret), "=m" (*mem) \ : "q" (newval), "m" (*mem), "0" (oldval)); \ ret; }) -#define __arch_compare_and_exchange_val_16_acq(mem, newval, oldval) \ +# define __arch_compare_and_exchange_val_16_acq(mem, newval, oldval) \ ({ __typeof (*mem) ret; \ __asm __volatile (LOCK_PREFIX "cmpxchgw %w2, %1" \ : "=a" (ret), "=m" (*mem) \ : "r" (newval), "m" (*mem), "0" (oldval)); \ ret; }) -#define __arch_compare_and_exchange_val_32_acq(mem, newval, oldval) \ +# define __arch_compare_and_exchange_val_32_acq(mem, newval, oldval) \ ({ __typeof (*mem) ret; \ __asm __volatile (LOCK_PREFIX "cmpxchgl %2, %1" \ : "=a" (ret), "=m" (*mem) \ : "r" (newval), "m" (*mem), "0" (oldval)); \ ret; }) -#define __arch_compare_and_exchange_val_64_acq(mem, newval, oldval) \ +# define __arch_compare_and_exchange_val_64_acq(mem, newval, oldval) \ ({ __typeof (*mem) ret; \ __asm __volatile (LOCK_PREFIX "cmpxchgq %q2, %1" \ : "=a" (ret), "=m" (*mem) \ : "r" ((long int) (newval)), "m" (*mem), \ "0" ((long int) (oldval))); \ ret; }) +#endif #define __arch_c_compare_and_exchange_val_8_acq(mem, newval, oldval) \ @@ -178,8 +185,13 @@ typedef uintmax_t uatomic_max_t; "i" (offsetof (tcbhead_t, multiple_threads))); \ result; }) -#define atomic_exchange_and_add(mem, value) \ +#if __GNUC_PREREQ (4, 1) +# define atomic_exchange_and_add(mem, value) \ + __sync_fetch_and_add (mem, value) +#else +# define atomic_exchange_and_add(mem, value) \ __arch_exchange_and_add_body (LOCK_PREFIX, mem, value) +#endif #define __arch_exchange_and_add_cprefix \ "cmpl $0, %%fs:%P4\n\tje 0f\n\tlock\n0:\t" |