From f977dca8aa6873891937442198cdbe5479ce52cd Mon Sep 17 00:00:00 2001 From: Ivan Maidanski Date: Thu, 27 Oct 2011 10:16:21 +0400 Subject: Implement most AO_fetch_compare_and_swap primitives * src/atomic_ops.c (AO_fetch_compare_and_swap_emulation): Implement. * src/atomic_ops.h: Remove FIXME for AO_fetch_compare_and_swap. * src/atomic_ops/generalize.h (AO_fetch_compare_and_swap_acquire, AO_fetch_compare_and_swap_release, AO_fetch_compare_and_swap_acquire, AO_fetch_compare_and_swap_write, AO_fetch_compare_and_swap_read, AO_fetch_compare_and_swap, AO_fetch_compare_and_swap_full, AO_fetch_compare_and_swap_release_write, AO_fetch_compare_and_swap_acquire_read, AO_fetch_compare_and_swap_dd_acquire_read): Implement; define the corresponding AO_HAVE_... macro. * src/atomic_ops/sysdeps/ao_t_is_int.h (AO_int_fetch_compare_and_swap_full, AO_int_fetch_compare_and_swap_acquire, AO_int_fetch_compare_and_swap_release, AO_int_fetch_compare_and_swap_write, AO_int_fetch_compare_and_swap_read, AO_int_fetch_compare_and_swap): Likewise. * src/atomic_ops/sysdeps/armcc/arm_v6.h (AO_fetch_compare_and_swap): Likewise. * src/atomic_ops/sysdeps/emul_cas.h (AO_fetch_compare_and_swap_full): Likewise. * src/atomic_ops/sysdeps/gcc/arm.h (AO_fetch_compare_and_swap): Likewise. * src/atomic_ops/sysdeps/gcc/hexagon.h (AO_fetch_compare_and_swap): Likewise. * src/atomic_ops/sysdeps/gcc/ia64.h (AO_fetch_compare_and_swap_acquire, AO_fetch_compare_and_swap_release, AO_char_fetch_compare_and_swap_acquire, AO_char_fetch_compare_and_swap_release, AO_short_fetch_compare_and_swap_acquire, AO_short_fetch_compare_and_swap_release, AO_int_fetch_compare_and_swap_acquire, AO_int_fetch_compare_and_swap_release): Likewise. * src/atomic_ops/sysdeps/gcc/powerpc.h (AO_fetch_compare_and_swap, AO_fetch_compare_and_swap_acquire, AO_fetch_compare_and_swap_release, AO_fetch_compare_and_swap_full): Likewise. * src/atomic_ops/sysdeps/gcc/x86.h (AO_fetch_compare_and_swap_full): Likewise. * src/atomic_ops/sysdeps/gcc/x86_64.h (AO_fetch_compare_and_swap_full): Likewise. * src/atomic_ops/sysdeps/generic_pthread.h (AO_fetch_compare_and_swap_full): Likewise. * src/atomic_ops/sysdeps/hpc/ia64.h (AO_fetch_compare_and_swap_acquire, AO_fetch_compare_and_swap_release, AO_char_fetch_compare_and_swap_acquire, AO_char_fetch_compare_and_swap_release, AO_short_fetch_compare_and_swap_acquire, AO_short_fetch_compare_and_swap_release): Likewise. * src/atomic_ops/sysdeps/icc/ia64.h (AO_fetch_compare_and_swap_acquire, AO_fetch_compare_and_swap_release, AO_char_fetch_compare_and_swap_acquire, AO_char_fetch_compare_and_swap_release, AO_short_fetch_compare_and_swap_acquire, AO_short_fetch_compare_and_swap_release, AO_int_fetch_compare_and_swap_acquire, AO_int_fetch_compare_and_swap_release): Likewise. * src/atomic_ops/sysdeps/msftc/common32_defs.h (AO_fetch_compare_and_swap_full): Likewise. * src/atomic_ops/sysdeps/msftc/x86_64.h (AO_fetch_compare_and_swap_full): Likewise. * src/atomic_ops/sysdeps/sunc/x86.h (AO_fetch_compare_and_swap_full): Likewise. * src/atomic_ops/sysdeps/sunc/x86_64.h (AO_fetch_compare_and_swap_full): Likewise. * src/atomic_ops/sysdeps/emul_cas.h (AO_fetch_compare_and_swap_emulation): Declare the function. * src/atomic_ops/sysdeps/gcc/mips.h: Adjust FIXME. * src/atomic_ops/sysdeps/gcc/sparc.h: Likewise. * src/atomic_ops/sysdeps/ibmc/powerpc.h (AO_fetch_compare_and_swap, AO_fetch_compare_and_swap_acquire, AO_fetch_compare_and_swap_release, AO_fetch_compare_and_swap_full): Add implementation stub. * tests/list_atomic.template (list_atomicXX): Add AO_fetch_compare_and_swapXX call. * tests/test_atomic_include.template (test_atomicXX): Likewise. --- src/atomic_ops.c | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) (limited to 'src/atomic_ops.c') diff --git a/src/atomic_ops.c b/src/atomic_ops.c index bd77bba..fb262b8 100644 --- a/src/atomic_ops.c +++ b/src/atomic_ops.c @@ -211,7 +211,26 @@ int AO_compare_and_swap_emulation(volatile AO_t *addr, AO_t old, return result; } -/* FIXME: implement AO_fetch_compare_and_swap */ +AO_t AO_fetch_compare_and_swap_emulation(volatile AO_t *addr, AO_t old_val, + AO_t new_val) +{ + AO_TS_t *my_lock = AO_locks + AO_HASH(addr); + AO_t fetched_val; + +# ifndef AO_USE_NO_SIGNALS + sigset_t old_sigs; + block_all_signals(&old_sigs); +# endif + lock(my_lock); + fetched_val = *addr; + if (fetched_val == old_val) + *addr = new_val; + unlock(my_lock); +# ifndef AO_USE_NO_SIGNALS + sigprocmask(SIG_SETMASK, &old_sigs, NULL); +# endif + return fetched_val; +} int AO_compare_double_and_swap_double_emulation(volatile AO_double_t *addr, AO_t old_val1, AO_t old_val2, -- cgit v1.2.1