summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGeorge Koehler <kernigh@gmail.com>2020-08-04 18:06:58 +0000
committerIvan Maidanski <ivmai@mail.ru>2021-06-11 21:08:26 +0300
commite2dd3b4d2f169b190818095dc6a7cf1400cdb769 (patch)
treed15712968e6c26b8dca1000f6dfda70e3d344689 /src
parent76f1cfe1cdf06d7d076781ea9d7f86f58e6cea9d (diff)
downloadlibatomic_ops-e2dd3b4d2f169b190818095dc6a7cf1400cdb769.tar.gz
Implement fetch-CAS for sparc (gcc)
* src/atomic_ops/sysdeps/gcc/sparc.h [!AO_NO_SPARC_V9] (AO_fetch_compare_and_swap_full): Implement; remove TODO.
Diffstat (limited to 'src')
-rw-r--r--src/atomic_ops/sysdeps/gcc/sparc.h16
1 files changed, 15 insertions, 1 deletions
diff --git a/src/atomic_ops/sysdeps/gcc/sparc.h b/src/atomic_ops/sysdeps/gcc/sparc.h
index 79eb763..9bd48d4 100644
--- a/src/atomic_ops/sysdeps/gcc/sparc.h
+++ b/src/atomic_ops/sysdeps/gcc/sparc.h
@@ -61,7 +61,21 @@ AO_compare_and_swap_full(volatile AO_t *addr, AO_t old, AO_t new_val) {
}
#define AO_HAVE_compare_and_swap_full
-/* TODO: implement AO_fetch_compare_and_swap. */
+AO_INLINE AO_t
+AO_fetch_compare_and_swap_full(volatile AO_t *addr, AO_t old, AO_t new_val) {
+ __asm__ __volatile__ ("membar #StoreLoad | #LoadLoad\n\t"
+# if defined(__arch64__)
+ "casx [%1],%2,%0\n\t"
+# else
+ "cas [%1],%2,%0\n\t" /* 32-bit version */
+# endif
+ "membar #StoreLoad | #StoreStore\n\t"
+ : "+r" (new_val)
+ : "r" (addr), "r" (old)
+ : "memory");
+ return new_val;
+}
+#define AO_HAVE_fetch_compare_and_swap_full
#endif /* !AO_NO_SPARC_V9 */
/* TODO: Extend this for SPARC v8 and v9 (V8 also has swap, V9 has CAS, */