]> granicus.if.org Git - libatomic_ops/commitdiff
Add FIXMEs to add AO_fetch_compare_and_swap primitives
authorIvan Maidanski <ivmai@mail.ru>
Fri, 21 Oct 2011 08:23:03 +0000 (12:23 +0400)
committerIvan Maidanski <ivmai@mail.ru>
Fri, 11 Nov 2011 12:36:16 +0000 (16:36 +0400)
31 files changed:
ChangeLog
TODO
doc/README.txt
src/atomic_ops.c
src/atomic_ops.h
src/atomic_ops/generalize.h
src/atomic_ops/sysdeps/ao_t_is_int.h
src/atomic_ops/sysdeps/armcc/arm_v6.h
src/atomic_ops/sysdeps/emul_cas.h
src/atomic_ops/sysdeps/gcc/alpha.h
src/atomic_ops/sysdeps/gcc/arm.h
src/atomic_ops/sysdeps/gcc/avr32.h
src/atomic_ops/sysdeps/gcc/hexagon.h
src/atomic_ops/sysdeps/gcc/ia64.h
src/atomic_ops/sysdeps/gcc/m68k.h
src/atomic_ops/sysdeps/gcc/mips.h
src/atomic_ops/sysdeps/gcc/powerpc.h
src/atomic_ops/sysdeps/gcc/s390.h
src/atomic_ops/sysdeps/gcc/sparc.h
src/atomic_ops/sysdeps/gcc/x86.h
src/atomic_ops/sysdeps/gcc/x86_64.h
src/atomic_ops/sysdeps/generic_pthread.h
src/atomic_ops/sysdeps/hpc/ia64.h
src/atomic_ops/sysdeps/ibmc/powerpc.h
src/atomic_ops/sysdeps/icc/ia64.h
src/atomic_ops/sysdeps/msftc/common32_defs.h
src/atomic_ops/sysdeps/msftc/x86_64.h
src/atomic_ops/sysdeps/sunc/x86.h
src/atomic_ops/sysdeps/sunc/x86_64.h
tests/list_atomic.template
tests/test_atomic_include.template

index 60d6ab2074c636e7643402dc3582bd2e7ef232a2..770ae4e4429418d507f8f815a6506db09bbe3c3c 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -4,6 +4,7 @@
 
 * Add '-no-undefined' to LDFLAGS in src/Makefile.am.
 * Add AO_and, AO_xor atomic operations.
+* Add AO_fetch_compare_and_swap primitives.
 * Add and fill in AUTHORS, TODO files.
 * Add atomic_ops.pc.in and atomic_ops-uninstalled.pc.in to pkgconfig folder.
 * Adjust AO_..._H macros in public headers.
diff --git a/TODO b/TODO
index 58114c562c608743e588aee60172348bf6e6eb20..d2452250d47bab2fc03ec23f30d53266fd588d85 100644 (file)
--- a/TODO
+++ b/TODO
@@ -1,8 +1,6 @@
 TODO tasks
 ==========
 
-Add equivalent of __sync_val_compare_and_swap. Add tests.
-
 Add C++0x ATM (atomic memory operations) layer.
 
 
index 26a4f7fc55a0b9e708f2b9e3630602611a316fa5..348247d6c864fd98d2eabf91d751f1d21148bc4a 100644 (file)
@@ -100,6 +100,9 @@ int compare_and_swap(volatile AO_t * addr, AO_t old_val, AO_t new_val)
         Atomically compare *addr to old_val, and replace *addr by new_val
         if the first comparison succeeds.  Returns nonzero if the comparison
         succeeded and *addr was updated.
+AO_t fetch_compare_and_swap(volatile AO_t * addr, AO_t old_val, AO_t new_val)
+        Atomically compare *addr to old_val, and replace *addr by new_val
+        if the first comparison succeeds; returns the original value of *addr.
 AO_TS_VAL_t test_and_set(volatile AO_TS_t * addr)
         Atomically read the binary value at *addr, and set it.  AO_TS_VAL_t
         is an enumeration type which includes two values AO_TS_SET and
index 3b86371a4b478a2319b63932c84ba06d2d325088..bd77bbaa1813b7a600e1e5a8d629f99e88d34c79 100644 (file)
@@ -195,6 +195,7 @@ int AO_compare_and_swap_emulation(volatile AO_t *addr, AO_t old,
     sigset_t old_sigs;
     block_all_signals(&old_sigs);
 # endif
+
   lock(my_lock);
   if (*addr == old)
     {
@@ -210,6 +211,8 @@ int AO_compare_and_swap_emulation(volatile AO_t *addr, AO_t old,
   return result;
 }
 
+/* FIXME: implement AO_fetch_compare_and_swap */
+
 int AO_compare_double_and_swap_double_emulation(volatile AO_double_t *addr,
                                                 AO_t old_val1, AO_t old_val2,
                                                 AO_t new_val1, AO_t new_val2)
index 334dba0accb1e73c7596af994461fa3c1912a950..ca3a21a1e669cb1f531c93d02900ab9dc1975d25 100644 (file)
@@ -77,6 +77,7 @@
 /* AO_or                                                        */
 /* AO_xor                                                       */
 /* AO_compare_and_swap                                          */
+/* AO_fetch_compare_and_swap                                    */
 /*                                                              */
 /* Note that atomicity guarantees are valid only if both        */
 /* readers and writers use AO_ operations to access the         */
 /* or can only be read concurrently, then x can be accessed     */
 /* via ordinary references and assignments.                     */
 /*                                                              */
-/* Compare_and_exchange takes an address and an expected old    */
-/* value and a new value, and returns an int.  Nonzero          */
+/* AO_compare_and_swap takes an address and an expected old     */
+/* value and a new value, and returns an int.  Non-zero result  */
 /* indicates that it succeeded.                                 */
+/* AO_fetch_compare_and_swap takes an address and an expected   */
+/* old value and a new value, and returns the real old value.   */
+/* The operation succeeded if and only if the expected old      */
+/* value matches the old value returned.                        */
+/*                                                              */
 /* Test_and_set takes an address, atomically replaces it by     */
 /* AO_TS_SET, and returns the prior value.                      */
 /* An AO_TS_t location can be reset with the                    */
 # else
 #  error Cannot implement AO_compare_and_swap_full on this architecture.
 # endif
+/* FIXME: same for AO_fetch_compare_and_swap */
 #endif /* AO_REQUIRE_CAS && !AO_HAVE_compare_and_swap ... */
 
 /* The most common way to clear a test-and-set location         */
index 91a96fe7d34bf5a54e218eaf2f35a790b94161d8..2131685b94488147bae07b9965d58ba9885c3ea5 100644 (file)
 # endif
 #endif /* AO_HAVE_compare_and_swap_full */
 
+/* FIXME: implement AO_fetch_compare_and_swap */
+
 #if !defined(AO_HAVE_compare_and_swap) \
     && defined(AO_HAVE_compare_and_swap_release)
 # define AO_compare_and_swap(addr,old,new_val) \
index 3b6f165f08c5d676590dbf55bbb251ccf4c4aa96..33d3e4d79b6b5ae1792a0832aa904085ce5159ec 100644 (file)
@@ -72,6 +72,8 @@
 # define AO_HAVE_int_compare_and_swap
 #endif
 
+/* FIXME: implement AO_fetch_compare_and_swap */
+
 /* AO_load */
 #if defined(AO_HAVE_load_acquire) \
     && !defined(AO_HAVE_int_load_acquire)
index 7b43151716e4175e5eb0d4de5b675a60e4ebb7b3..16e7f1a3b17c1cdbffa0f9df7e8474e4c85d1f98 100644 (file)
@@ -198,6 +198,8 @@ __asm__ {
 }
 #define AO_HAVE_compare_and_swap
 
+/* FIXME: implement AO_fetch_compare_and_swap */
+
 /* helper functions for the Realview compiler: LDREXD is not usable
  * with inline assembler, so use the "embedded" assembler as
  * suggested by ARM Dev. support (June 2008). */
index 1aa34d96709514a353b85f38bb25282bd782ba78..fa93141c56d5cb7a02193c9a9c9a0bb0ea0f3cde 100644 (file)
@@ -64,6 +64,8 @@ void AO_store_full_emulation(volatile AO_t *addr, AO_t val);
 # define AO_HAVE_compare_double_and_swap_double_full
 #endif
 
+/* FIXME: implement AO_fetch_compare_and_swap */
+
 #undef AO_store
 #undef AO_HAVE_store
 #undef AO_store_write
index 61d0433b1c9d62325daf3dcecea0ee4983d36320..016e4d19beb397b891e92102d82163a7f9d34459 100644 (file)
@@ -61,3 +61,5 @@ AO_compare_and_swap(volatile AO_t *addr,
   return (int)was_equal;
 }
 #define AO_HAVE_compare_and_swap
+
+/* FIXME: implement AO_fetch_compare_and_swap */
index 3e5fd02cf7a0042882249b479a9970ae491cf520..5a53d4e6176e17a36595e758eb147c82121d2e9f 100644 (file)
@@ -265,6 +265,8 @@ AO_compare_and_swap(volatile AO_t *addr, AO_t old_val, AO_t new_val)
 }
 #define AO_HAVE_compare_and_swap
 
+/* FIXME: implement AO_fetch_compare_and_swap */
+
 #if !defined(__ARM_ARCH_6__) && !defined(__ARM_ARCH_6J__) \
     && !defined(__ARM_ARCH_6T2__) && !defined(__ARM_ARCH_6Z__) \
     && !defined(__ARM_ARCH_6ZT2__) && (!defined(__thumb__) \
index 7a2fbed195d424fbbc3d76bffb75ed1bc9b99f8f..c1bf56c15d7ae23d06bcf8f3b652f7ada6094ef3 100644 (file)
@@ -63,3 +63,5 @@ AO_compare_and_swap_full(volatile AO_t *addr, AO_t old, AO_t new_val)
        return (int)ret;
 }
 #define AO_HAVE_compare_and_swap_full
+
+/* FIXME: implement AO_fetch_compare_and_swap */
index fdc9e56e9b9551cfad647c4ffa135c791818590b..9dff708d91460d699ecfaca722a8b63e4e8ec72b 100644 (file)
@@ -92,4 +92,6 @@ AO_compare_and_swap(volatile AO_t *addr, AO_t old, AO_t new_val)
 }
 #define AO_HAVE_compare_and_swap
 
+/* FIXME: implement AO_fetch_compare_and_swap */
+
 #include "../ao_t_is_int.h"
index 60c7a7e4c629ac14b8b50aaff18b0eaafc993884..086f314bca1bc861f2092bdeea771931b47f9964 100644 (file)
@@ -189,6 +189,8 @@ AO_compare_and_swap_release(volatile AO_t *addr,
 }
 #define AO_HAVE_compare_and_swap_release
 
+/* FIXME: implement AO_fetch_compare_and_swap */
+
 AO_INLINE int
 AO_char_compare_and_swap_acquire(volatile unsigned char *addr,
                                  unsigned char old, unsigned char new_val)
index c8980821eacf958b3042986ef398b6e3b1bc82e0..a00afe7000ddd08f48191ad366d59f5687ee281e 100644 (file)
@@ -63,4 +63,6 @@ AO_compare_and_swap_full(volatile AO_t *addr,
 }
 #define AO_HAVE_compare_and_swap_full
 
+/* FIXME: implement AO_fetch_compare_and_swap */
+
 #include "../ao_t_is_int.h"
index 527a34741a663fab11582e0bfbab36120533c90a..a91426c03db2f5f78290f8173dbb5122f53bec5b 100644 (file)
@@ -94,6 +94,8 @@ AO_compare_and_swap_full(volatile AO_t *addr, AO_t old, AO_t new_val) {
 }
 #define AO_HAVE_compare_and_swap_full
 
+/* FIXME: implement AO_fetch_compare_and_swap */
+
 /*
  * FIXME: We should also implement fetch_and_add and or primitives
  * directly.
index 69ec05b14897f9b66c0cda35faeff7400a0d8a56..5312a8e8be8d4c206e3db998f7f7735e2a08e9be 100644 (file)
@@ -225,6 +225,8 @@ AO_compare_and_swap_full(volatile AO_t *addr, AO_t old, AO_t new_val) {
 }
 #define AO_HAVE_compare_and_swap_full
 
+/* FIXME: implement AO_fetch_compare_and_swap */
+
 AO_INLINE AO_t
 AO_fetch_and_add(volatile AO_t *addr, AO_t incr) {
   AO_t oldval;
index c05dc85eea98f53896a3bc18a23407f814dfa8de..fadf944584270e2d4ece9958226e01d5c70ae53c 100644 (file)
@@ -59,4 +59,6 @@ AO_INLINE int AO_compare_and_swap_full(volatile AO_t *addr,
 }
 #define AO_HAVE_compare_and_swap_full
 
+/* FIXME: implement AO_fetch_compare_and_swap */
+
 /* FIXME: Add double-wide compare-and-swap for 32-bit executables.      */
index 41bc2f5d97820fb021cae5c6490b867518da3f08..7647893a11c7b51f7832239cf3f1ce47f4df2b4b 100644 (file)
@@ -63,6 +63,8 @@ AO_compare_and_swap_full(volatile AO_t *addr, AO_t old, AO_t new_val) {
 #define AO_HAVE_compare_and_swap_full
 #endif /* !AO_NO_SPARC_V9 */
 
+/* FIXME: implement AO_fetch_compare_and_swap */
+
 /* FIXME: This needs to be extended for SPARC v8 and v9.        */
 /* SPARC V8 also has swap.  V9 has CAS.                         */
 /* There are barriers like membar #LoadStore.                   */
index b304dd0455a33c79aee746902426b69088888c40..c408dbcbaa5739377c74020d7d5e4f39e35f0764 100644 (file)
@@ -149,6 +149,8 @@ AO_compare_and_swap_full(volatile AO_t *addr, AO_t old, AO_t new_val)
 }
 #define AO_HAVE_compare_and_swap_full
 
+/* FIXME: implement AO_fetch_compare_and_swap */
+
 /* Returns nonzero if the comparison succeeded. */
 /* Really requires at least a Pentium.          */
 AO_INLINE int
index 92252707cf8ee98a3d74b0ea3ee6935f7601e1fb..de68c0f496e72767b49d50d8e653fe2a15861991 100644 (file)
@@ -143,6 +143,8 @@ AO_compare_and_swap_full(volatile AO_t *addr, AO_t old, AO_t new_val)
 }
 #define AO_HAVE_compare_and_swap_full
 
+/* FIXME: implement AO_fetch_compare_and_swap */
+
 #ifdef AO_CMPXCHG16B_AVAILABLE
 
 /* NEC LE-IT: older AMD Opterons are missing this instruction.
index 8c8a91a948e6134143b217d3b47a63943a52f8fb..f051fc9a2b3dfa4010fe9e135564c342f7776e39 100644 (file)
@@ -233,6 +233,8 @@ AO_compare_and_swap_full(volatile AO_t *addr, AO_t old, AO_t new_val)
 }
 #define AO_HAVE_compare_and_swap_full
 
+/* FIXME: implement AO_fetch_compare_and_swap */
+
 /* Unlike real architectures, we define both double-width CAS variants. */
 
 typedef struct {
index b793fcbdfb73534960f253e9997c4dde047ce00f..68e78cd8b37ac336c66e628f11481c1d411465f2 100644 (file)
@@ -107,6 +107,8 @@ AO_compare_and_swap_release(volatile AO_t *addr,
 }
 #define AO_HAVE_compare_and_swap_release
 
+/* FIXME: implement AO_fetch_compare_and_swap */
+
 AO_INLINE int
 AO_char_compare_and_swap_acquire(volatile unsigned char *addr,
                                  unsigned char old, unsigned char new_val)
index 4378dca47f68082ff716f4bea279fa814f90ae6e..a51c3d5ed620ed4abaf4914ebf4a068ba94c941a 100644 (file)
@@ -120,5 +120,5 @@ AO_compare_and_swap_full(volatile AO_t *addr, AO_t old, AO_t new_val)
 }
 #define AO_HAVE_compare_and_swap_full
 
-/* FIXME: We should also implement fetch_and_add and or primitives      */
-/* directly.                                                            */
+/* FIXME: We should also implement AO_fetch_compare_and_swap,           */
+/* AO_fetch_and_add, AO_and/or/xor primitives directly.                 */
index cfa20732412e34190c756a2d00b5e68c04ac050d..956226585b7208965b19527f9c2f10c83a685081 100644 (file)
@@ -152,6 +152,8 @@ AO_compare_and_swap_release(volatile AO_t *addr,
 }
 #define AO_HAVE_compare_and_swap_release
 
+/* FIXME: implement AO_fetch_compare_and_swap */
+
 AO_INLINE int
 AO_char_compare_and_swap_acquire(volatile unsigned char *addr,
                                  unsigned char old, unsigned char new_val)
index 5d519f09f7dbb6b53ebb10d7af58685f303246a5..3b5c782cafef9303a7f3e95931e56513991866b1 100644 (file)
@@ -115,4 +115,6 @@ AO_compare_and_swap_full(volatile AO_t *addr, AO_t old, AO_t new_val)
 # endif
 }
 # define AO_HAVE_compare_and_swap_full
+
+/* FIXME: implement AO_fetch_compare_and_swap */
 #endif /* AO_ASSUME_WINDOWS98 */
index 135a053ced68f1fd81800271e24c71cfba69a329..3b1054357320b4675e72fc1ef327cb5e0474bfcf 100644 (file)
@@ -85,6 +85,8 @@ AO_compare_and_swap_full(volatile AO_t *addr,
 }
 #define AO_HAVE_compare_and_swap_full
 
+/* FIXME: implement AO_fetch_compare_and_swap */
+
 /* As far as we can tell, the lfence and sfence instructions are not    */
 /* currently needed or useful for cached memory accesses.               */
 
index 9abd8a00057a315b117bd2513b797e833cfdfcc2..8db585192932b870c9e06d9edf0fede55ecacd84 100644 (file)
@@ -142,6 +142,8 @@ AO_compare_and_swap_full (volatile AO_t *addr, AO_t old, AO_t new_val)
 }
 #define AO_HAVE_compare_and_swap_full
 
+/* FIXME: implement AO_fetch_compare_and_swap */
+
 #if 0
 /* FIXME: not tested (and probably wrong). Besides,     */
 /* it tickles a bug in Sun C 5.10 (when optimizing).    */
index 5be6d9a4cfb5d8527d91a2b771be55a449665dc1..d888a5d6343336a6515180485e66cb5bd9b770d1 100644 (file)
@@ -142,6 +142,8 @@ AO_compare_and_swap_full (volatile AO_t *addr, AO_t old, AO_t new_val)
 }
 #define AO_HAVE_compare_and_swap_full
 
+/* FIXME: implement AO_fetch_compare_and_swap */
+
 #ifdef AO_CMPXCHG16B_AVAILABLE
 /* NEC LE-IT: older AMD Opterons are missing this instruction.
  * On these machines SIGILL will be thrown.
index 7fdef11424b1dc721df0ce28a1e8dcccb6325edf..1c1d632d4082fdea0d27cd0ad2e886b975e18e2e 100644 (file)
@@ -65,4 +65,5 @@ void list_atomicXX(void)
 # else
     "No AO_compare_and_swapXX";
 # endif
+/* FIXME: test AO_fetch_compare_and_swap */
 }
index 9fec3f9101a6b10fbb1126d4da442da138e24086..ea1f14c207a9db17de8b6cdf22ce820f1e6d8456 100644 (file)
@@ -170,6 +170,7 @@ void test_atomicXX(void)
     MISSING(AO_compare_and_swap);
     if (x == 13) x = 42;
 # endif
+/* FIXME: test AO_fetch_compare_and_swap */
 # if defined(AO_HAVE_orXX)
     AO_orXX(&x, 66);
     TA_assert(x == 106);