Enable generalization of all variants of CAS via fetch_compare_and_swap
authorIvan Maidanski <ivmai@mail.ru>
Thu, 3 Jan 2013 15:18:11 +0000 (19:18 +0400)
committerIvan Maidanski <ivmai@mail.ru>
Thu, 3 Jan 2013 18:18:46 +0000 (22:18 +0400)
* src/atomic_ops/generalize.h (AO_compare_and_swap_full,
AO_compare_and_swap_acquire, AO_compare_and_swap_release,
AO_compare_and_swap, AO_TS_COMPARE_AND_SWAP_FULL,
AO_TS_COMPARE_AND_SWAP_ACQUIRE, AO_TS_COMPARE_AND_SWAP_RELEASE,
AO_TS_COMPARE_AND_SWAP): Define (in this file) only if required for
AO_test_and_set_X generalization.
* src/atomic_ops/generalize-arithm.template
(AO_XSIZE_compare_and_swap_write, AO_XSIZE_compare_and_swap_read,
AO_XSIZE_compare_and_swap_release_write,
AO_XSIZE_compare_and_swap_acquire_read,
AO_XSIZE_compare_and_swap_dd_acquire_read): Add missing variant of
generalized template CAS primitives based fetch_compare_and_swap; add
the corresponding AO_HAVE_XSIZE_compare_and_swap_X macros.
* src/atomic_ops/generalize-arithm.h: Regenerate.

src/atomic_ops/generalize-arithm.h
src/atomic_ops/generalize-arithm.template
src/atomic_ops/generalize.h

index 00d35a8..a50c697 100644 (file)
 # define AO_HAVE_char_compare_and_swap_release
 #endif
 
+#if defined(AO_HAVE_char_fetch_compare_and_swap_write) \
+    && !defined(AO_HAVE_char_compare_and_swap_write)
+  AO_INLINE int
+  AO_char_compare_and_swap_write(volatile unsigned/**/char *addr, unsigned/**/char old_val,
+                                  unsigned/**/char new_val)
+  {
+    return AO_char_fetch_compare_and_swap_write(addr, old_val, new_val)
+             == old_val;
+  }
+# define AO_HAVE_char_compare_and_swap_write
+#endif
+
+#if defined(AO_HAVE_char_fetch_compare_and_swap_read) \
+    && !defined(AO_HAVE_char_compare_and_swap_read)
+  AO_INLINE int
+  AO_char_compare_and_swap_read(volatile unsigned/**/char *addr, unsigned/**/char old_val,
+                                 unsigned/**/char new_val)
+  {
+    return AO_char_fetch_compare_and_swap_read(addr, old_val, new_val)
+             == old_val;
+  }
+# define AO_HAVE_char_compare_and_swap_read
+#endif
+
 #if defined(AO_HAVE_char_fetch_compare_and_swap) \
     && !defined(AO_HAVE_char_compare_and_swap)
   AO_INLINE int
 # define AO_HAVE_char_compare_and_swap
 #endif
 
+#if defined(AO_HAVE_char_fetch_compare_and_swap_release_write) \
+    && !defined(AO_HAVE_char_compare_and_swap_release_write)
+  AO_INLINE int
+  AO_char_compare_and_swap_release_write(volatile unsigned/**/char *addr,
+                                          unsigned/**/char old_val, unsigned/**/char new_val)
+  {
+    return AO_char_fetch_compare_and_swap_release_write(addr, old_val,
+                                                         new_val) == old_val;
+  }
+# define AO_HAVE_char_compare_and_swap_release_write
+#endif
+
+#if defined(AO_HAVE_char_fetch_compare_and_swap_acquire_read) \
+    && !defined(AO_HAVE_char_compare_and_swap_acquire_read)
+  AO_INLINE int
+  AO_char_compare_and_swap_acquire_read(volatile unsigned/**/char *addr,
+                                         unsigned/**/char old_val, unsigned/**/char new_val)
+  {
+    return AO_char_fetch_compare_and_swap_acquire_read(addr, old_val,
+                                                        new_val) == old_val;
+  }
+# define AO_HAVE_char_compare_and_swap_acquire_read
+#endif
+
+#if defined(AO_HAVE_char_fetch_compare_and_swap_dd_acquire_read) \
+    && !defined(AO_HAVE_char_compare_and_swap_dd_acquire_read)
+  AO_INLINE int
+  AO_char_compare_and_swap_dd_acquire_read(volatile unsigned/**/char *addr,
+                                            unsigned/**/char old_val, unsigned/**/char new_val)
+  {
+    return AO_char_fetch_compare_and_swap_dd_acquire_read(addr, old_val,
+                                                           new_val) == old_val;
+  }
+# define AO_HAVE_char_compare_and_swap_dd_acquire_read
+#endif
+
 /* char_fetch_and_add */
 /* We first try to implement fetch_and_add variants in terms of the     */
 /* corresponding compare_and_swap variants to minimize adding barriers. */
 # define AO_HAVE_short_compare_and_swap_release
 #endif
 
+#if defined(AO_HAVE_short_fetch_compare_and_swap_write) \
+    && !defined(AO_HAVE_short_compare_and_swap_write)
+  AO_INLINE int
+  AO_short_compare_and_swap_write(volatile unsigned/**/short *addr, unsigned/**/short old_val,
+                                  unsigned/**/short new_val)
+  {
+    return AO_short_fetch_compare_and_swap_write(addr, old_val, new_val)
+             == old_val;
+  }
+# define AO_HAVE_short_compare_and_swap_write
+#endif
+
+#if defined(AO_HAVE_short_fetch_compare_and_swap_read) \
+    && !defined(AO_HAVE_short_compare_and_swap_read)
+  AO_INLINE int
+  AO_short_compare_and_swap_read(volatile unsigned/**/short *addr, unsigned/**/short old_val,
+                                 unsigned/**/short new_val)
+  {
+    return AO_short_fetch_compare_and_swap_read(addr, old_val, new_val)
+             == old_val;
+  }
+# define AO_HAVE_short_compare_and_swap_read
+#endif
+
 #if defined(AO_HAVE_short_fetch_compare_and_swap) \
     && !defined(AO_HAVE_short_compare_and_swap)
   AO_INLINE int
 # define AO_HAVE_short_compare_and_swap
 #endif
 
+#if defined(AO_HAVE_short_fetch_compare_and_swap_release_write) \
+    && !defined(AO_HAVE_short_compare_and_swap_release_write)
+  AO_INLINE int
+  AO_short_compare_and_swap_release_write(volatile unsigned/**/short *addr,
+                                          unsigned/**/short old_val, unsigned/**/short new_val)
+  {
+    return AO_short_fetch_compare_and_swap_release_write(addr, old_val,
+                                                         new_val) == old_val;
+  }
+# define AO_HAVE_short_compare_and_swap_release_write
+#endif
+
+#if defined(AO_HAVE_short_fetch_compare_and_swap_acquire_read) \
+    && !defined(AO_HAVE_short_compare_and_swap_acquire_read)
+  AO_INLINE int
+  AO_short_compare_and_swap_acquire_read(volatile unsigned/**/short *addr,
+                                         unsigned/**/short old_val, unsigned/**/short new_val)
+  {
+    return AO_short_fetch_compare_and_swap_acquire_read(addr, old_val,
+                                                        new_val) == old_val;
+  }
+# define AO_HAVE_short_compare_and_swap_acquire_read
+#endif
+
+#if defined(AO_HAVE_short_fetch_compare_and_swap_dd_acquire_read) \
+    && !defined(AO_HAVE_short_compare_and_swap_dd_acquire_read)
+  AO_INLINE int
+  AO_short_compare_and_swap_dd_acquire_read(volatile unsigned/**/short *addr,
+                                            unsigned/**/short old_val, unsigned/**/short new_val)
+  {
+    return AO_short_fetch_compare_and_swap_dd_acquire_read(addr, old_val,
+                                                           new_val) == old_val;
+  }
+# define AO_HAVE_short_compare_and_swap_dd_acquire_read
+#endif
+
 /* short_fetch_and_add */
 /* We first try to implement fetch_and_add variants in terms of the     */
 /* corresponding compare_and_swap variants to minimize adding barriers. */
 # define AO_HAVE_int_compare_and_swap_release
 #endif
 
+#if defined(AO_HAVE_int_fetch_compare_and_swap_write) \
+    && !defined(AO_HAVE_int_compare_and_swap_write)
+  AO_INLINE int
+  AO_int_compare_and_swap_write(volatile unsigned *addr, unsigned old_val,
+                                  unsigned new_val)
+  {
+    return AO_int_fetch_compare_and_swap_write(addr, old_val, new_val)
+             == old_val;
+  }
+# define AO_HAVE_int_compare_and_swap_write
+#endif
+
+#if defined(AO_HAVE_int_fetch_compare_and_swap_read) \
+    && !defined(AO_HAVE_int_compare_and_swap_read)
+  AO_INLINE int
+  AO_int_compare_and_swap_read(volatile unsigned *addr, unsigned old_val,
+                                 unsigned new_val)
+  {
+    return AO_int_fetch_compare_and_swap_read(addr, old_val, new_val)
+             == old_val;
+  }
+# define AO_HAVE_int_compare_and_swap_read
+#endif
+
 #if defined(AO_HAVE_int_fetch_compare_and_swap) \
     && !defined(AO_HAVE_int_compare_and_swap)
   AO_INLINE int
 # define AO_HAVE_int_compare_and_swap
 #endif
 
+#if defined(AO_HAVE_int_fetch_compare_and_swap_release_write) \
+    && !defined(AO_HAVE_int_compare_and_swap_release_write)
+  AO_INLINE int
+  AO_int_compare_and_swap_release_write(volatile unsigned *addr,
+                                          unsigned old_val, unsigned new_val)
+  {
+    return AO_int_fetch_compare_and_swap_release_write(addr, old_val,
+                                                         new_val) == old_val;
+  }
+# define AO_HAVE_int_compare_and_swap_release_write
+#endif
+
+#if defined(AO_HAVE_int_fetch_compare_and_swap_acquire_read) \
+    && !defined(AO_HAVE_int_compare_and_swap_acquire_read)
+  AO_INLINE int
+  AO_int_compare_and_swap_acquire_read(volatile unsigned *addr,
+                                         unsigned old_val, unsigned new_val)
+  {
+    return AO_int_fetch_compare_and_swap_acquire_read(addr, old_val,
+                                                        new_val) == old_val;
+  }
+# define AO_HAVE_int_compare_and_swap_acquire_read
+#endif
+
+#if defined(AO_HAVE_int_fetch_compare_and_swap_dd_acquire_read) \
+    && !defined(AO_HAVE_int_compare_and_swap_dd_acquire_read)
+  AO_INLINE int
+  AO_int_compare_and_swap_dd_acquire_read(volatile unsigned *addr,
+                                            unsigned old_val, unsigned new_val)
+  {
+    return AO_int_fetch_compare_and_swap_dd_acquire_read(addr, old_val,
+                                                           new_val) == old_val;
+  }
+# define AO_HAVE_int_compare_and_swap_dd_acquire_read
+#endif
+
 /* int_fetch_and_add */
 /* We first try to implement fetch_and_add variants in terms of the     */
 /* corresponding compare_and_swap variants to minimize adding barriers. */
 # define AO_HAVE_compare_and_swap_release
 #endif
 
+#if defined(AO_HAVE_fetch_compare_and_swap_write) \
+    && !defined(AO_HAVE_compare_and_swap_write)
+  AO_INLINE int
+  AO_compare_and_swap_write(volatile AO_t *addr, AO_t old_val,
+                                  AO_t new_val)
+  {
+    return AO_fetch_compare_and_swap_write(addr, old_val, new_val)
+             == old_val;
+  }
+# define AO_HAVE_compare_and_swap_write
+#endif
+
+#if defined(AO_HAVE_fetch_compare_and_swap_read) \
+    && !defined(AO_HAVE_compare_and_swap_read)
+  AO_INLINE int
+  AO_compare_and_swap_read(volatile AO_t *addr, AO_t old_val,
+                                 AO_t new_val)
+  {
+    return AO_fetch_compare_and_swap_read(addr, old_val, new_val)
+             == old_val;
+  }
+# define AO_HAVE_compare_and_swap_read
+#endif
+
 #if defined(AO_HAVE_fetch_compare_and_swap) \
     && !defined(AO_HAVE_compare_and_swap)
   AO_INLINE int
 # define AO_HAVE_compare_and_swap
 #endif
 
+#if defined(AO_HAVE_fetch_compare_and_swap_release_write) \
+    && !defined(AO_HAVE_compare_and_swap_release_write)
+  AO_INLINE int
+  AO_compare_and_swap_release_write(volatile AO_t *addr,
+                                          AO_t old_val, AO_t new_val)
+  {
+    return AO_fetch_compare_and_swap_release_write(addr, old_val,
+                                                         new_val) == old_val;
+  }
+# define AO_HAVE_compare_and_swap_release_write
+#endif
+
+#if defined(AO_HAVE_fetch_compare_and_swap_acquire_read) \
+    && !defined(AO_HAVE_compare_and_swap_acquire_read)
+  AO_INLINE int
+  AO_compare_and_swap_acquire_read(volatile AO_t *addr,
+                                         AO_t old_val, AO_t new_val)
+  {
+    return AO_fetch_compare_and_swap_acquire_read(addr, old_val,
+                                                        new_val) == old_val;
+  }
+# define AO_HAVE_compare_and_swap_acquire_read
+#endif
+
+#if defined(AO_HAVE_fetch_compare_and_swap_dd_acquire_read) \
+    && !defined(AO_HAVE_compare_and_swap_dd_acquire_read)
+  AO_INLINE int
+  AO_compare_and_swap_dd_acquire_read(volatile AO_t *addr,
+                                            AO_t old_val, AO_t new_val)
+  {
+    return AO_fetch_compare_and_swap_dd_acquire_read(addr, old_val,
+                                                           new_val) == old_val;
+  }
+# define AO_HAVE_compare_and_swap_dd_acquire_read
+#endif
+
 /* fetch_and_add */
 /* We first try to implement fetch_and_add variants in terms of the     */
 /* corresponding compare_and_swap variants to minimize adding barriers. */
index b7c5c7d..93750c8 100644 (file)
 # define AO_HAVE_XSIZE_compare_and_swap_release
 #endif
 
+#if defined(AO_HAVE_XSIZE_fetch_compare_and_swap_write) \
+    && !defined(AO_HAVE_XSIZE_compare_and_swap_write)
+  AO_INLINE int
+  AO_XSIZE_compare_and_swap_write(volatile XCTYPE *addr, XCTYPE old_val,
+                                  XCTYPE new_val)
+  {
+    return AO_XSIZE_fetch_compare_and_swap_write(addr, old_val, new_val)
+             == old_val;
+  }
+# define AO_HAVE_XSIZE_compare_and_swap_write
+#endif
+
+#if defined(AO_HAVE_XSIZE_fetch_compare_and_swap_read) \
+    && !defined(AO_HAVE_XSIZE_compare_and_swap_read)
+  AO_INLINE int
+  AO_XSIZE_compare_and_swap_read(volatile XCTYPE *addr, XCTYPE old_val,
+                                 XCTYPE new_val)
+  {
+    return AO_XSIZE_fetch_compare_and_swap_read(addr, old_val, new_val)
+             == old_val;
+  }
+# define AO_HAVE_XSIZE_compare_and_swap_read
+#endif
+
 #if defined(AO_HAVE_XSIZE_fetch_compare_and_swap) \
     && !defined(AO_HAVE_XSIZE_compare_and_swap)
   AO_INLINE int
 # define AO_HAVE_XSIZE_compare_and_swap
 #endif
 
+#if defined(AO_HAVE_XSIZE_fetch_compare_and_swap_release_write) \
+    && !defined(AO_HAVE_XSIZE_compare_and_swap_release_write)
+  AO_INLINE int
+  AO_XSIZE_compare_and_swap_release_write(volatile XCTYPE *addr,
+                                          XCTYPE old_val, XCTYPE new_val)
+  {
+    return AO_XSIZE_fetch_compare_and_swap_release_write(addr, old_val,
+                                                         new_val) == old_val;
+  }
+# define AO_HAVE_XSIZE_compare_and_swap_release_write
+#endif
+
+#if defined(AO_HAVE_XSIZE_fetch_compare_and_swap_acquire_read) \
+    && !defined(AO_HAVE_XSIZE_compare_and_swap_acquire_read)
+  AO_INLINE int
+  AO_XSIZE_compare_and_swap_acquire_read(volatile XCTYPE *addr,
+                                         XCTYPE old_val, XCTYPE new_val)
+  {
+    return AO_XSIZE_fetch_compare_and_swap_acquire_read(addr, old_val,
+                                                        new_val) == old_val;
+  }
+# define AO_HAVE_XSIZE_compare_and_swap_acquire_read
+#endif
+
+#if defined(AO_HAVE_XSIZE_fetch_compare_and_swap_dd_acquire_read) \
+    && !defined(AO_HAVE_XSIZE_compare_and_swap_dd_acquire_read)
+  AO_INLINE int
+  AO_XSIZE_compare_and_swap_dd_acquire_read(volatile XCTYPE *addr,
+                                            XCTYPE old_val, XCTYPE new_val)
+  {
+    return AO_XSIZE_fetch_compare_and_swap_dd_acquire_read(addr, old_val,
+                                                           new_val) == old_val;
+  }
+# define AO_HAVE_XSIZE_compare_and_swap_dd_acquire_read
+#endif
+
 /* XSIZE_fetch_and_add */
 /* We first try to implement fetch_and_add variants in terms of the     */
 /* corresponding compare_and_swap variants to minimize adding barriers. */
index 7755575..3e66341 100644 (file)
 # error This file should not be included directly.
 #endif
 
-/* Emulate AO_compare_and_swap() via AO_fetch_compare_and_swap().       */
-#if defined(AO_HAVE_fetch_compare_and_swap) \
-    && !defined(AO_HAVE_compare_and_swap)
-  AO_INLINE int
-  AO_compare_and_swap(volatile AO_t *addr, AO_t old_val, AO_t new_val)
-  {
-    return AO_fetch_compare_and_swap(addr, old_val, new_val) == old_val;
-  }
-# define AO_HAVE_compare_and_swap
-#endif
+/* Generate test_and_set_full, if necessary and possible.       */
+#if !defined(AO_HAVE_test_and_set) && !defined(AO_HAVE_test_and_set_release) \
+    && !defined(AO_HAVE_test_and_set_acquire) \
+    && !defined(AO_HAVE_test_and_set_read) \
+    && !defined(AO_HAVE_test_and_set_full)
 
-#if defined(AO_HAVE_fetch_compare_and_swap_full) \
-    && !defined(AO_HAVE_compare_and_swap_full)
-  AO_INLINE int
-  AO_compare_and_swap_full(volatile AO_t *addr, AO_t old_val, AO_t new_val)
-  {
-    return AO_fetch_compare_and_swap_full(addr, old_val, new_val) == old_val;
-  }
-# define AO_HAVE_compare_and_swap_full
-#endif
+  /* Emulate AO_compare_and_swap() via AO_fetch_compare_and_swap().     */
+# if defined(AO_HAVE_fetch_compare_and_swap) \
+     && !defined(AO_HAVE_compare_and_swap)
+    AO_INLINE int
+    AO_compare_and_swap(volatile AO_t *addr, AO_t old_val, AO_t new_val)
+    {
+      return AO_fetch_compare_and_swap(addr, old_val, new_val) == old_val;
+    }
+#   define AO_HAVE_compare_and_swap
+# endif
 
-#if defined(AO_HAVE_fetch_compare_and_swap_acquire) \
-    && !defined(AO_HAVE_compare_and_swap_acquire)
-  AO_INLINE int
-  AO_compare_and_swap_acquire(volatile AO_t *addr, AO_t old_val, AO_t new_val)
-  {
-    return AO_fetch_compare_and_swap_acquire(addr, old_val, new_val)
-             == old_val;
-  }
-# define AO_HAVE_compare_and_swap_acquire
-#endif
+# if defined(AO_HAVE_fetch_compare_and_swap_full) \
+     && !defined(AO_HAVE_compare_and_swap_full)
+    AO_INLINE int
+    AO_compare_and_swap_full(volatile AO_t *addr, AO_t old_val, AO_t new_val)
+    {
+      return AO_fetch_compare_and_swap_full(addr, old_val, new_val)
+               == old_val;
+    }
+#   define AO_HAVE_compare_and_swap_full
+# endif
 
-#if defined(AO_HAVE_fetch_compare_and_swap_release) \
-    && !defined(AO_HAVE_compare_and_swap_release)
-  AO_INLINE int
-  AO_compare_and_swap_release(volatile AO_t *addr, AO_t old_val, AO_t new_val)
-  {
-    return AO_fetch_compare_and_swap_release(addr, old_val, new_val)
-             == old_val;
-  }
-# define AO_HAVE_compare_and_swap_release
-#endif
+# if defined(AO_HAVE_fetch_compare_and_swap_acquire) \
+     && !defined(AO_HAVE_compare_and_swap_acquire)
+    AO_INLINE int
+    AO_compare_and_swap_acquire(volatile AO_t *addr, AO_t old_val,
+                                AO_t new_val)
+    {
+      return AO_fetch_compare_and_swap_acquire(addr, old_val, new_val)
+               == old_val;
+    }
+#   define AO_HAVE_compare_and_swap_acquire
+# endif
 
-#if AO_CHAR_TS_T
-# define AO_TS_COMPARE_AND_SWAP_FULL(a,o,n) \
+# if defined(AO_HAVE_fetch_compare_and_swap_release) \
+     && !defined(AO_HAVE_compare_and_swap_release)
+    AO_INLINE int
+    AO_compare_and_swap_release(volatile AO_t *addr, AO_t old_val,
+                                AO_t new_val)
+    {
+      return AO_fetch_compare_and_swap_release(addr, old_val, new_val)
+               == old_val;
+    }
+#   define AO_HAVE_compare_and_swap_release
+# endif
+
+# if AO_CHAR_TS_T
+#   define AO_TS_COMPARE_AND_SWAP_FULL(a,o,n) \
                                 AO_char_compare_and_swap_full(a,o,n)
-# define AO_TS_COMPARE_AND_SWAP_ACQUIRE(a,o,n) \
+#   define AO_TS_COMPARE_AND_SWAP_ACQUIRE(a,o,n) \
                                 AO_char_compare_and_swap_acquire(a,o,n)
-# define AO_TS_COMPARE_AND_SWAP_RELEASE(a,o,n) \
+#   define AO_TS_COMPARE_AND_SWAP_RELEASE(a,o,n) \
                                 AO_char_compare_and_swap_release(a,o,n)
-# define AO_TS_COMPARE_AND_SWAP(a,o,n) AO_char_compare_and_swap(a,o,n)
-#endif
+#   define AO_TS_COMPARE_AND_SWAP(a,o,n) AO_char_compare_and_swap(a,o,n)
+# endif
 
-#if AO_AO_TS_T
-# define AO_TS_COMPARE_AND_SWAP_FULL(a,o,n) AO_compare_and_swap_full(a,o,n)
-# define AO_TS_COMPARE_AND_SWAP_ACQUIRE(a,o,n) \
-                                        AO_compare_and_swap_acquire(a,o,n)
-# define AO_TS_COMPARE_AND_SWAP_RELEASE(a,o,n) \
-                                        AO_compare_and_swap_release(a,o,n)
-# define AO_TS_COMPARE_AND_SWAP(a,o,n) AO_compare_and_swap(a,o,n)
-#endif
+# if AO_AO_TS_T
+#   define AO_TS_COMPARE_AND_SWAP_FULL(a,o,n) AO_compare_and_swap_full(a,o,n)
+#   define AO_TS_COMPARE_AND_SWAP_ACQUIRE(a,o,n) \
+                                AO_compare_and_swap_acquire(a,o,n)
+#   define AO_TS_COMPARE_AND_SWAP_RELEASE(a,o,n) \
+                                AO_compare_and_swap_release(a,o,n)
+#   define AO_TS_COMPARE_AND_SWAP(a,o,n) AO_compare_and_swap(a,o,n)
+# endif
 
-/* Generate test_and_set_full, if necessary and possible.       */
-#if !defined(AO_HAVE_test_and_set) && !defined(AO_HAVE_test_and_set_release) \
-    && !defined(AO_HAVE_test_and_set_acquire) \
-    && !defined(AO_HAVE_test_and_set_read) \
-    && !defined(AO_HAVE_test_and_set_full)
 # if (AO_AO_TS_T && defined(AO_HAVE_compare_and_swap_full)) \
      || (AO_CHAR_TS_T && defined(AO_HAVE_char_compare_and_swap_full))
     AO_INLINE AO_TS_VAL_t