]> granicus.if.org Git - libatomic_ops/commitdiff
Implement double-wide load/store and CAS primitives for AArch64
authorIvan Maidanski <ivmai@mail.ru>
Sat, 9 Feb 2013 14:31:09 +0000 (18:31 +0400)
committerIvan Maidanski <ivmai@mail.ru>
Sat, 9 Feb 2013 14:33:21 +0000 (18:33 +0400)
* src/atomic_ops/sysdeps/gcc/aarch64.h: Include standard_ao_double_t.h
(before inclusion of generic.h).
* src/atomic_ops/sysdeps/gcc/generic.h (AO_double_load,
AO_double_load_acquire, AO_double_store, AO_double_store_release,
AO_double_compare_and_swap): Implement (only if
AO_HAVE_DOUBLE_PTR_STORAGE defined).

src/atomic_ops/sysdeps/gcc/aarch64.h
src/atomic_ops/sysdeps/gcc/generic.h

index 083b3cf08a69efb98ec8a208ea9c013d60917c53..8e622109f1ce49224d424cb7d8928b28fa16556e 100644 (file)
@@ -17,4 +17,6 @@
 
 #include "../test_and_set_t_is_ao_t.h"
 
+#include "../standard_ao_double_t.h"
+
 #include "generic.h"
index 46a40a89fa13dd99170d4e8815b2709b8365aa91..18a586dd9640977b6bf9326071657ab78700dfe9 100644 (file)
@@ -249,6 +249,53 @@ AO_fetch_compare_and_swap(volatile AO_t *addr, AO_t old_val, AO_t new_val)
 # define AO_HAVE_compare_and_swap
 #endif /* !AO_GENERALIZE_ASM_BOOL_CAS */
 
-/* TODO: Add AO_char/short/int_ primitives. */
-/* TODO: Include standard_ao_double_t.h in aarch64.h. */
-/* TODO: add double-wide primitives if AO_double_t present. */
+/* TODO: Add AO_char/short/int_ primitives (via template header). */
+
+#ifdef AO_HAVE_DOUBLE_PTR_STORAGE
+
+  AO_INLINE AO_double_t
+  AO_double_load(const volatile AO_double_t *addr)
+  {
+    AO_double_t result;
+
+    result.AO_whole = __atomic_load_n(&addr->AO_whole, __ATOMIC_RELAXED);
+    return result;
+  }
+# define AO_HAVE_double_load
+
+  AO_INLINE AO_double_t
+  AO_double_load_acquire(const volatile AO_double_t *addr)
+  {
+    AO_double_t result;
+
+    result.AO_whole = __atomic_load_n(&addr->AO_whole, __ATOMIC_ACQUIRE);
+    return result;
+  }
+# define AO_HAVE_double_load_acquire
+
+  AO_INLINE void
+  AO_double_store(volatile AO_double_t *addr, AO_double_t value)
+  {
+    __atomic_store_n(&addr->AO_whole, value.AO_whole, __ATOMIC_RELAXED);
+  }
+# define AO_HAVE_double_store
+
+  AO_INLINE void
+  AO_double_store_release(volatile AO_double_t *addr, AO_double_t value)
+  {
+    __atomic_store_n(&addr->AO_whole, value.AO_whole, __ATOMIC_RELEASE);
+  }
+# define AO_HAVE_double_store_release
+
+  AO_INLINE int
+  AO_double_compare_and_swap(volatile AO_double_t *addr,
+                             AO_double_t old_val, AO_double_t new_val)
+  {
+    return __sync_bool_compare_and_swap(&addr->AO_whole,
+                                        old_val.AO_whole, new_val.AO_whole
+                                        /* empty protection list */);
+  }
+# define AO_HAVE_double_compare_and_swap
+
+  /* TODO: Add double CAS _acquire/release/full primitives. */
+#endif /* AO_HAVE_DOUBLE_PTR_STORAGE */