]> granicus.if.org Git - libatomic_ops/commitdiff
Add AO_store generalization based on CAS
authorIvan Maidanski <ivmai@mail.ru>
Sat, 12 Jan 2013 19:52:34 +0000 (23:52 +0400)
committerIvan Maidanski <ivmai@mail.ru>
Sat, 12 Jan 2013 19:52:34 +0000 (23:52 +0400)
* src/atomic_ops/generalize-small.template (AO_XSIZE_store_write,
AO_XSIZE_store, AO_XSIZE_store_release, AO_XSIZE_store_full): Add
generalization template primitive based on CAS.
* src/atomic_ops/generalize-small.h: Regenerate.

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

index dfc3c8c5486a9123a873c22c2c0a6e73c2f7910c..2bcee36eb653df07105b1ace46617d58f6171d47 100644 (file)
 # define AO_HAVE_char_store_release_write
 #endif
 
+#if defined(AO_HAVE_char_compare_and_swap_write) \
+    && !defined(AO_HAVE_char_store_write)
+  AO_INLINE void
+  AO_char_store_write(volatile unsigned/**/char *addr, unsigned/**/char new_val)
+  {
+    unsigned/**/char old_val;
+
+    do {
+      old_val = *(unsigned/**/char *)addr;
+    } while (AO_EXPECT_FALSE(!AO_char_compare_and_swap_write(addr, old_val,
+                                                              new_val)));
+  }
+# define AO_HAVE_char_store_write
+#endif
+
 #if defined(AO_HAVE_char_store_release) && defined(AO_HAVE_nop_full) \
     && !defined(AO_HAVE_char_store_full)
 # define AO_char_store_full(addr, val) \
                                  AO_nop_full())
 # define AO_HAVE_char_store_full
 #endif
+
+#if defined(AO_HAVE_char_compare_and_swap) && !defined(AO_HAVE_char_store)
+  AO_INLINE void
+  AO_char_store(volatile unsigned/**/char *addr, unsigned/**/char new_val)
+  {
+    unsigned/**/char old_val;
+
+    do {
+      old_val = *(unsigned/**/char *)addr;
+    } while (AO_EXPECT_FALSE(!AO_char_compare_and_swap(addr,
+                                                        old_val, new_val)));
+  }
+# define AO_HAVE_char_store
+#endif
+
+#if defined(AO_HAVE_char_compare_and_swap_release) \
+    && !defined(AO_HAVE_char_store_release)
+  AO_INLINE void
+  AO_char_store_release(volatile unsigned/**/char *addr, unsigned/**/char new_val)
+  {
+    unsigned/**/char old_val;
+
+    do {
+      old_val = *(unsigned/**/char *)addr;
+    } while (AO_EXPECT_FALSE(!AO_char_compare_and_swap_release(addr, old_val,
+                                                                new_val)));
+  }
+# define AO_HAVE_char_store_release
+#endif
+
+#if defined(AO_HAVE_char_compare_and_swap_full) \
+    && !defined(AO_HAVE_char_store_full)
+  AO_INLINE void
+  AO_char_store_full(volatile unsigned/**/char *addr, unsigned/**/char new_val)
+  {
+    unsigned/**/char old_val;
+
+    do {
+      old_val = *(unsigned/**/char *)addr;
+    } while (AO_EXPECT_FALSE(!AO_char_compare_and_swap_full(addr, old_val,
+                                                             new_val)));
+  }
+# define AO_HAVE_char_store_full
+#endif
 /*
  * Copyright (c) 2003-2011 Hewlett-Packard Development Company, L.P.
  *
 # define AO_HAVE_short_store_release_write
 #endif
 
+#if defined(AO_HAVE_short_compare_and_swap_write) \
+    && !defined(AO_HAVE_short_store_write)
+  AO_INLINE void
+  AO_short_store_write(volatile unsigned/**/short *addr, unsigned/**/short new_val)
+  {
+    unsigned/**/short old_val;
+
+    do {
+      old_val = *(unsigned/**/short *)addr;
+    } while (AO_EXPECT_FALSE(!AO_short_compare_and_swap_write(addr, old_val,
+                                                              new_val)));
+  }
+# define AO_HAVE_short_store_write
+#endif
+
 #if defined(AO_HAVE_short_store_release) && defined(AO_HAVE_nop_full) \
     && !defined(AO_HAVE_short_store_full)
 # define AO_short_store_full(addr, val) \
                                  AO_nop_full())
 # define AO_HAVE_short_store_full
 #endif
+
+#if defined(AO_HAVE_short_compare_and_swap) && !defined(AO_HAVE_short_store)
+  AO_INLINE void
+  AO_short_store(volatile unsigned/**/short *addr, unsigned/**/short new_val)
+  {
+    unsigned/**/short old_val;
+
+    do {
+      old_val = *(unsigned/**/short *)addr;
+    } while (AO_EXPECT_FALSE(!AO_short_compare_and_swap(addr,
+                                                        old_val, new_val)));
+  }
+# define AO_HAVE_short_store
+#endif
+
+#if defined(AO_HAVE_short_compare_and_swap_release) \
+    && !defined(AO_HAVE_short_store_release)
+  AO_INLINE void
+  AO_short_store_release(volatile unsigned/**/short *addr, unsigned/**/short new_val)
+  {
+    unsigned/**/short old_val;
+
+    do {
+      old_val = *(unsigned/**/short *)addr;
+    } while (AO_EXPECT_FALSE(!AO_short_compare_and_swap_release(addr, old_val,
+                                                                new_val)));
+  }
+# define AO_HAVE_short_store_release
+#endif
+
+#if defined(AO_HAVE_short_compare_and_swap_full) \
+    && !defined(AO_HAVE_short_store_full)
+  AO_INLINE void
+  AO_short_store_full(volatile unsigned/**/short *addr, unsigned/**/short new_val)
+  {
+    unsigned/**/short old_val;
+
+    do {
+      old_val = *(unsigned/**/short *)addr;
+    } while (AO_EXPECT_FALSE(!AO_short_compare_and_swap_full(addr, old_val,
+                                                             new_val)));
+  }
+# define AO_HAVE_short_store_full
+#endif
 /*
  * Copyright (c) 2003-2011 Hewlett-Packard Development Company, L.P.
  *
 # define AO_HAVE_int_store_release_write
 #endif
 
+#if defined(AO_HAVE_int_compare_and_swap_write) \
+    && !defined(AO_HAVE_int_store_write)
+  AO_INLINE void
+  AO_int_store_write(volatile unsigned *addr, unsigned new_val)
+  {
+    unsigned old_val;
+
+    do {
+      old_val = *(unsigned *)addr;
+    } while (AO_EXPECT_FALSE(!AO_int_compare_and_swap_write(addr, old_val,
+                                                              new_val)));
+  }
+# define AO_HAVE_int_store_write
+#endif
+
 #if defined(AO_HAVE_int_store_release) && defined(AO_HAVE_nop_full) \
     && !defined(AO_HAVE_int_store_full)
 # define AO_int_store_full(addr, val) \
                                  AO_nop_full())
 # define AO_HAVE_int_store_full
 #endif
+
+#if defined(AO_HAVE_int_compare_and_swap) && !defined(AO_HAVE_int_store)
+  AO_INLINE void
+  AO_int_store(volatile unsigned *addr, unsigned new_val)
+  {
+    unsigned old_val;
+
+    do {
+      old_val = *(unsigned *)addr;
+    } while (AO_EXPECT_FALSE(!AO_int_compare_and_swap(addr,
+                                                        old_val, new_val)));
+  }
+# define AO_HAVE_int_store
+#endif
+
+#if defined(AO_HAVE_int_compare_and_swap_release) \
+    && !defined(AO_HAVE_int_store_release)
+  AO_INLINE void
+  AO_int_store_release(volatile unsigned *addr, unsigned new_val)
+  {
+    unsigned old_val;
+
+    do {
+      old_val = *(unsigned *)addr;
+    } while (AO_EXPECT_FALSE(!AO_int_compare_and_swap_release(addr, old_val,
+                                                                new_val)));
+  }
+# define AO_HAVE_int_store_release
+#endif
+
+#if defined(AO_HAVE_int_compare_and_swap_full) \
+    && !defined(AO_HAVE_int_store_full)
+  AO_INLINE void
+  AO_int_store_full(volatile unsigned *addr, unsigned new_val)
+  {
+    unsigned old_val;
+
+    do {
+      old_val = *(unsigned *)addr;
+    } while (AO_EXPECT_FALSE(!AO_int_compare_and_swap_full(addr, old_val,
+                                                             new_val)));
+  }
+# define AO_HAVE_int_store_full
+#endif
 /*
  * Copyright (c) 2003-2011 Hewlett-Packard Development Company, L.P.
  *
 # define AO_HAVE_store_release_write
 #endif
 
+#if defined(AO_HAVE_compare_and_swap_write) \
+    && !defined(AO_HAVE_store_write)
+  AO_INLINE void
+  AO_store_write(volatile AO_t *addr, AO_t new_val)
+  {
+    AO_t old_val;
+
+    do {
+      old_val = *(AO_t *)addr;
+    } while (AO_EXPECT_FALSE(!AO_compare_and_swap_write(addr, old_val,
+                                                              new_val)));
+  }
+# define AO_HAVE_store_write
+#endif
+
 #if defined(AO_HAVE_store_release) && defined(AO_HAVE_nop_full) \
     && !defined(AO_HAVE_store_full)
 # define AO_store_full(addr, val) \
                                  AO_nop_full())
 # define AO_HAVE_store_full
 #endif
+
+#if defined(AO_HAVE_compare_and_swap) && !defined(AO_HAVE_store)
+  AO_INLINE void
+  AO_store(volatile AO_t *addr, AO_t new_val)
+  {
+    AO_t old_val;
+
+    do {
+      old_val = *(AO_t *)addr;
+    } while (AO_EXPECT_FALSE(!AO_compare_and_swap(addr,
+                                                        old_val, new_val)));
+  }
+# define AO_HAVE_store
+#endif
+
+#if defined(AO_HAVE_compare_and_swap_release) \
+    && !defined(AO_HAVE_store_release)
+  AO_INLINE void
+  AO_store_release(volatile AO_t *addr, AO_t new_val)
+  {
+    AO_t old_val;
+
+    do {
+      old_val = *(AO_t *)addr;
+    } while (AO_EXPECT_FALSE(!AO_compare_and_swap_release(addr, old_val,
+                                                                new_val)));
+  }
+# define AO_HAVE_store_release
+#endif
+
+#if defined(AO_HAVE_compare_and_swap_full) \
+    && !defined(AO_HAVE_store_full)
+  AO_INLINE void
+  AO_store_full(volatile AO_t *addr, AO_t new_val)
+  {
+    AO_t old_val;
+
+    do {
+      old_val = *(AO_t *)addr;
+    } while (AO_EXPECT_FALSE(!AO_compare_and_swap_full(addr, old_val,
+                                                             new_val)));
+  }
+# define AO_HAVE_store_full
+#endif
 /*
  * Copyright (c) 2003-2011 Hewlett-Packard Development Company, L.P.
  *
 # define AO_HAVE_double_store_release_write
 #endif
 
+#if defined(AO_HAVE_double_compare_and_swap_write) \
+    && !defined(AO_HAVE_double_store_write)
+  AO_INLINE void
+  AO_double_store_write(volatile AO_double_t *addr, AO_double_t new_val)
+  {
+    AO_double_t old_val;
+
+    do {
+      old_val = *(AO_double_t *)addr;
+    } while (AO_EXPECT_FALSE(!AO_double_compare_and_swap_write(addr, old_val,
+                                                              new_val)));
+  }
+# define AO_HAVE_double_store_write
+#endif
+
 #if defined(AO_HAVE_double_store_release) && defined(AO_HAVE_nop_full) \
     && !defined(AO_HAVE_double_store_full)
 # define AO_double_store_full(addr, val) \
                                  AO_nop_full())
 # define AO_HAVE_double_store_full
 #endif
+
+#if defined(AO_HAVE_double_compare_and_swap) && !defined(AO_HAVE_double_store)
+  AO_INLINE void
+  AO_double_store(volatile AO_double_t *addr, AO_double_t new_val)
+  {
+    AO_double_t old_val;
+
+    do {
+      old_val = *(AO_double_t *)addr;
+    } while (AO_EXPECT_FALSE(!AO_double_compare_and_swap(addr,
+                                                        old_val, new_val)));
+  }
+# define AO_HAVE_double_store
+#endif
+
+#if defined(AO_HAVE_double_compare_and_swap_release) \
+    && !defined(AO_HAVE_double_store_release)
+  AO_INLINE void
+  AO_double_store_release(volatile AO_double_t *addr, AO_double_t new_val)
+  {
+    AO_double_t old_val;
+
+    do {
+      old_val = *(AO_double_t *)addr;
+    } while (AO_EXPECT_FALSE(!AO_double_compare_and_swap_release(addr, old_val,
+                                                                new_val)));
+  }
+# define AO_HAVE_double_store_release
+#endif
+
+#if defined(AO_HAVE_double_compare_and_swap_full) \
+    && !defined(AO_HAVE_double_store_full)
+  AO_INLINE void
+  AO_double_store_full(volatile AO_double_t *addr, AO_double_t new_val)
+  {
+    AO_double_t old_val;
+
+    do {
+      old_val = *(AO_double_t *)addr;
+    } while (AO_EXPECT_FALSE(!AO_double_compare_and_swap_full(addr, old_val,
+                                                             new_val)));
+  }
+# define AO_HAVE_double_store_full
+#endif
index b8ab439cd4da0d287444f7e6f311d27e39f79f01..b5284ec446272d02cc56b86901ce6adfb0b0170e 100644 (file)
 # define AO_HAVE_XSIZE_store_release_write
 #endif
 
+#if defined(AO_HAVE_XSIZE_compare_and_swap_write) \
+    && !defined(AO_HAVE_XSIZE_store_write)
+  AO_INLINE void
+  AO_XSIZE_store_write(volatile XCTYPE *addr, XCTYPE new_val)
+  {
+    XCTYPE old_val;
+
+    do {
+      old_val = *(XCTYPE *)addr;
+    } while (AO_EXPECT_FALSE(!AO_XSIZE_compare_and_swap_write(addr, old_val,
+                                                              new_val)));
+  }
+# define AO_HAVE_XSIZE_store_write
+#endif
+
 #if defined(AO_HAVE_XSIZE_store_release) && defined(AO_HAVE_nop_full) \
     && !defined(AO_HAVE_XSIZE_store_full)
 # define AO_XSIZE_store_full(addr, val) \
                                  AO_nop_full())
 # define AO_HAVE_XSIZE_store_full
 #endif
+
+#if defined(AO_HAVE_XSIZE_compare_and_swap) && !defined(AO_HAVE_XSIZE_store)
+  AO_INLINE void
+  AO_XSIZE_store(volatile XCTYPE *addr, XCTYPE new_val)
+  {
+    XCTYPE old_val;
+
+    do {
+      old_val = *(XCTYPE *)addr;
+    } while (AO_EXPECT_FALSE(!AO_XSIZE_compare_and_swap(addr,
+                                                        old_val, new_val)));
+  }
+# define AO_HAVE_XSIZE_store
+#endif
+
+#if defined(AO_HAVE_XSIZE_compare_and_swap_release) \
+    && !defined(AO_HAVE_XSIZE_store_release)
+  AO_INLINE void
+  AO_XSIZE_store_release(volatile XCTYPE *addr, XCTYPE new_val)
+  {
+    XCTYPE old_val;
+
+    do {
+      old_val = *(XCTYPE *)addr;
+    } while (AO_EXPECT_FALSE(!AO_XSIZE_compare_and_swap_release(addr, old_val,
+                                                                new_val)));
+  }
+# define AO_HAVE_XSIZE_store_release
+#endif
+
+#if defined(AO_HAVE_XSIZE_compare_and_swap_full) \
+    && !defined(AO_HAVE_XSIZE_store_full)
+  AO_INLINE void
+  AO_XSIZE_store_full(volatile XCTYPE *addr, XCTYPE new_val)
+  {
+    XCTYPE old_val;
+
+    do {
+      old_val = *(XCTYPE *)addr;
+    } while (AO_EXPECT_FALSE(!AO_XSIZE_compare_and_swap_full(addr, old_val,
+                                                             new_val)));
+  }
+# define AO_HAVE_XSIZE_store_full
+#endif