Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/Unity-Technologies/libatomic_ops.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIvan Maidanski <ivmai@mail.ru>2013-05-26 17:08:27 +0400
committerIvan Maidanski <ivmai@mail.ru>2013-05-26 17:08:27 +0400
commit25e83ad7a05407142af78ef4e9155ba3ba07176b (patch)
tree3f11e4bc69d32d1af4cf03cdd39113239f117dd8
parent6e7a0f7f75b46a5980ca711a8fc674c64c9567dd (diff)
Add non-generalized double-CAS-full implementation for AArch64
* src/atomic_ops/sysdeps/gcc/aarch64.h (AO_double_compare_and_swap_full): New function.
-rw-r--r--src/atomic_ops/sysdeps/gcc/aarch64.h25
1 files changed, 24 insertions, 1 deletions
diff --git a/src/atomic_ops/sysdeps/gcc/aarch64.h b/src/atomic_ops/sysdeps/gcc/aarch64.h
index 6ae26f3..54e6d7f 100644
--- a/src/atomic_ops/sysdeps/gcc/aarch64.h
+++ b/src/atomic_ops/sysdeps/gcc/aarch64.h
@@ -171,6 +171,29 @@
return !result;
}
# define AO_HAVE_double_compare_and_swap_release
-#endif
+
+ AO_INLINE int
+ AO_double_compare_and_swap_full(volatile AO_double_t *addr,
+ AO_double_t old_val, AO_double_t new_val)
+ {
+ AO_double_t tmp;
+ int result = 1;
+
+ do {
+ __asm__ __volatile__("//AO_double_compare_and_swap_full\n"
+ " ldaxp %0, %1, %2\n"
+ : "=&r" (tmp.AO_val1), "=&r" (tmp.AO_val2)
+ : "Q" (*addr));
+ if (tmp.AO_val1 != old_val.AO_val1 || tmp.AO_val2 != old_val.AO_val2)
+ break;
+ __asm__ __volatile__(
+ " stlxp %w0, %2, %3, %1\n"
+ : "=&r" (result), "=Q" (*addr)
+ : "r" (new_val.AO_val1), "r" (new_val.AO_val2));
+ } while (AO_EXPECT_FALSE(result));
+ return !result;
+ }
+# define AO_HAVE_double_compare_and_swap_full
+#endif /* __GNUC__ == 4 */
#include "generic.h"