svn commit: r281157 - head/sys/arm64/include
Andrew Turner
andrew at FreeBSD.org
Mon Apr 6 16:27:24 UTC 2015
Author: andrew
Date: Mon Apr 6 16:27:22 2015
New Revision: 281157
URL: https://svnweb.freebsd.org/changeset/base/281157
Log:
Split out the _acq and _rel functions. These were the same, but there is
no need for them to be this strong, we only need to provide one or the
other.
While here replace atomic_load_acq_* and atomic_store_rel_* with a single
instruction version, and fix the definition of atomic_clear_* to point to
the correct functions.
Sponsored by: The FreeBSD Foundation
Modified:
head/sys/arm64/include/atomic.h
Modified: head/sys/arm64/include/atomic.h
==============================================================================
--- head/sys/arm64/include/atomic.h Mon Apr 6 15:50:20 2015 (r281156)
+++ head/sys/arm64/include/atomic.h Mon Apr 6 16:27:22 2015 (r281157)
@@ -160,7 +160,6 @@ atomic_subtract_32(volatile uint32_t *p,
#define atomic_set_int atomic_set_32
#define atomic_subtract_int atomic_subtract_32
-
static __inline void
atomic_add_acq_32(volatile uint32_t *p, uint32_t val)
{
@@ -170,7 +169,7 @@ atomic_add_acq_32(volatile uint32_t *p,
__asm __volatile(
"1: ldaxr %w0, [%2] \n"
" add %w0, %w0, %w3 \n"
- " stlxr %w1, %w0, [%2] \n"
+ " stxr %w1, %w0, [%2] \n"
" cbnz %w1, 1b \n"
"2:"
: "=&r"(tmp), "=&r"(res), "+r" (p), "+r" (val) : : "cc", "memory"
@@ -186,7 +185,7 @@ atomic_clear_acq_32(volatile uint32_t *p
__asm __volatile(
"1: ldaxr %w0, [%2] \n"
" bic %w0, %w0, %w3 \n"
- " stlxr %w1, %w0, [%2] \n"
+ " stxr %w1, %w0, [%2] \n"
" cbnz %w1, 1b \n"
: "=&r"(tmp), "=&r"(res), "+r" (p), "+r" (val) : : "cc", "memory"
);
@@ -203,7 +202,7 @@ atomic_cmpset_acq_32(volatile uint32_t *
" ldaxr %w0, [%2] \n"
" cmp %w0, %w3 \n"
" b.ne 2f \n"
- " stlxr %w1, %w4, [%2] \n"
+ " stxr %w1, %w4, [%2] \n"
" cbnz %w1, 1b \n"
"2:"
: "=&r"(tmp), "=&r"(res), "+r" (p), "+r" (cmpval), "+r" (newval)
@@ -218,8 +217,9 @@ atomic_load_acq_32(volatile uint32_t *p)
{
uint32_t ret;
- ret = *p;
- dmb();
+ __asm __volatile(
+ "ldar %w0, [%1] \n"
+ : "=&r" (ret) : "r" (p) : "memory");
return (ret);
}
@@ -233,7 +233,7 @@ atomic_set_acq_32(volatile uint32_t *p,
__asm __volatile(
"1: ldaxr %w0, [%2] \n"
" orr %w0, %w0, %w3 \n"
- " stlxr %w1, %w0, [%2] \n"
+ " stxr %w1, %w0, [%2] \n"
" cbnz %w1, 1b \n"
: "=&r"(tmp), "=&r"(res), "+r" (p), "+r" (val) : : "cc", "memory"
);
@@ -248,6 +248,82 @@ atomic_subtract_acq_32(volatile uint32_t
__asm __volatile(
"1: ldaxr %w0, [%2] \n"
" sub %w0, %w0, %w3 \n"
+ " stxr %w1, %w0, [%2] \n"
+ " cbnz %w1, 1b \n"
+ : "=&r"(tmp), "=&r"(res), "+r" (p), "+r" (val) : : "cc", "memory"
+ );
+}
+
+#define atomic_add_acq_int atomic_add_acq_32
+#define atomic_clear_acq_int atomic_clear_acq_32
+#define atomic_cmpset_acq_int atomic_cmpset_acq_32
+#define atomic_load_acq_int atomic_load_acq_32
+#define atomic_set_acq_int atomic_set_acq_32
+#define atomic_subtract_acq_int atomic_subtract_acq_32
+
+/* The atomic functions currently are both acq and rel, we should fix this. */
+
+static __inline void
+atomic_add_rel_32(volatile uint32_t *p, uint32_t val)
+{
+ uint32_t tmp;
+ int res;
+
+ __asm __volatile(
+ "1: ldxr %w0, [%2] \n"
+ " add %w0, %w0, %w3 \n"
+ " stlxr %w1, %w0, [%2] \n"
+ " cbnz %w1, 1b \n"
+ "2:"
+ : "=&r"(tmp), "=&r"(res), "+r" (p), "+r" (val) : : "cc", "memory"
+ );
+}
+
+static __inline void
+atomic_clear_rel_32(volatile uint32_t *p, uint32_t val)
+{
+ uint32_t tmp;
+ int res;
+
+ __asm __volatile(
+ "1: ldxr %w0, [%2] \n"
+ " bic %w0, %w0, %w3 \n"
+ " stlxr %w1, %w0, [%2] \n"
+ " cbnz %w1, 1b \n"
+ : "=&r"(tmp), "=&r"(res), "+r" (p), "+r" (val) : : "cc", "memory"
+ );
+}
+
+static __inline int
+atomic_cmpset_rel_32(volatile uint32_t *p, uint32_t cmpval, uint32_t newval)
+{
+ uint32_t tmp;
+ int res;
+
+ __asm __volatile(
+ "1: mov %w1, #1 \n"
+ " ldxr %w0, [%2] \n"
+ " cmp %w0, %w3 \n"
+ " b.ne 2f \n"
+ " stlxr %w1, %w4, [%2] \n"
+ " cbnz %w1, 1b \n"
+ "2:"
+ : "=&r"(tmp), "=&r"(res), "+r" (p), "+r" (cmpval), "+r" (newval)
+ : : "cc", "memory"
+ );
+
+ return (!res);
+}
+
+static __inline void
+atomic_set_rel_32(volatile uint32_t *p, uint32_t val)
+{
+ uint32_t tmp;
+ int res;
+
+ __asm __volatile(
+ "1: ldxr %w0, [%2] \n"
+ " orr %w0, %w0, %w3 \n"
" stlxr %w1, %w0, [%2] \n"
" cbnz %w1, 1b \n"
: "=&r"(tmp), "=&r"(res), "+r" (p), "+r" (val) : : "cc", "memory"
@@ -258,23 +334,25 @@ static __inline void
atomic_store_rel_32(volatile uint32_t *p, uint32_t val)
{
- dmb();
- *p = val;
+ __asm __volatile(
+ "stlr %w0, [%1] \n"
+ : : "r" (val), "r" (p) : "memory");
}
-#define atomic_add_acq_int atomic_add_acq_32
-#define atomic_clear_acq_int atomic_add_acq_32
-#define atomic_cmpset_acq_int atomic_cmpset_acq_32
-#define atomic_load_acq_int atomic_load_acq_32
-#define atomic_set_acq_int atomic_set_acq_32
-#define atomic_subtract_acq_int atomic_subtract_acq_32
+static __inline void
+atomic_subtract_rel_32(volatile uint32_t *p, uint32_t val)
+{
+ uint32_t tmp;
+ int res;
-/* The atomic functions currently are both acq and rel, we should fix this. */
-#define atomic_add_rel_32 atomic_add_acq_32
-#define atomic_clear_rel_32 atomic_add_acq_32
-#define atomic_cmpset_rel_32 atomic_cmpset_acq_32
-#define atomic_set_rel_32 atomic_set_acq_32
-#define atomic_subtract_rel_32 atomic_subtract_acq_32
+ __asm __volatile(
+ "1: ldxr %w0, [%2] \n"
+ " sub %w0, %w0, %w3 \n"
+ " stlxr %w1, %w0, [%2] \n"
+ " cbnz %w1, 1b \n"
+ : "=&r"(tmp), "=&r"(res), "+r" (p), "+r" (val) : : "cc", "memory"
+ );
+}
#define atomic_add_rel_int atomic_add_rel_32
#define atomic_clear_rel_int atomic_add_rel_32
@@ -440,7 +518,7 @@ atomic_add_acq_64(volatile uint64_t *p,
__asm __volatile(
"1: ldaxr %0, [%2] \n"
" add %0, %0, %3 \n"
- " stlxr %w1, %0, [%2] \n"
+ " stxr %w1, %0, [%2] \n"
" cbnz %w1, 1b \n"
"2:"
: "=&r"(tmp), "=&r"(res), "+r" (p), "+r" (val) : : "cc", "memory"
@@ -456,7 +534,7 @@ atomic_clear_acq_64(volatile uint64_t *p
__asm __volatile(
"1: ldaxr %0, [%2] \n"
" bic %0, %0, %3 \n"
- " stlxr %w1, %0, [%2] \n"
+ " stxr %w1, %0, [%2] \n"
" cbnz %w1, 1b \n"
: "=&r"(tmp), "=&r"(res), "+r" (p), "+r" (val) : : "cc", "memory"
);
@@ -473,7 +551,7 @@ atomic_cmpset_acq_64(volatile uint64_t *
" ldaxr %0, [%2] \n"
" cmp %0, %3 \n"
" b.ne 2f \n"
- " stlxr %w1, %4, [%2] \n"
+ " stxr %w1, %4, [%2] \n"
" cbnz %w1, 1b \n"
"2:"
: "=&r" (tmp), "=&r" (res), "+r" (p), "+r" (cmpval), "+r" (newval)
@@ -488,8 +566,9 @@ atomic_load_acq_64(volatile uint64_t *p)
{
uint64_t ret;
- ret = *p;
- dmb();
+ __asm __volatile(
+ "ldar %0, [%1] \n"
+ : "=&r" (ret) : "r" (p) : "memory");
return (ret);
}
@@ -503,7 +582,7 @@ atomic_set_acq_64(volatile uint64_t *p,
__asm __volatile(
"1: ldaxr %0, [%2] \n"
" orr %0, %0, %3 \n"
- " stlxr %w1, %0, [%2] \n"
+ " stxr %w1, %0, [%2] \n"
" cbnz %w1, 1b \n"
: "=&r"(tmp), "=&r"(res), "+r" (p), "+r" (val) : : "cc", "memory"
);
@@ -518,20 +597,12 @@ atomic_subtract_acq_64(volatile uint64_t
__asm __volatile(
"1: ldaxr %0, [%2] \n"
" sub %0, %0, %3 \n"
- " stlxr %w1, %0, [%2] \n"
+ " stxr %w1, %0, [%2] \n"
" cbnz %w1, 1b \n"
: "=&r"(tmp), "=&r"(res), "+r" (p), "+r" (val) : : "cc", "memory"
);
}
-static __inline void
-atomic_store_rel_64(volatile uint64_t *p, uint64_t val)
-{
-
- dmb();
- *p = val;
-}
-
#define atomic_add_acq_long atomic_add_acq_64
#define atomic_clear_acq_long atomic_add_acq_64
#define atomic_cmpset_acq_long atomic_cmpset_acq_64
@@ -550,21 +621,106 @@ atomic_store_rel_64(volatile uint64_t *p
* TODO: The atomic functions currently are both acq and rel, we should fix
* this.
*/
-#define atomic_add_rel_64 atomic_add_acq_64
-#define atomic_clear_rel_64 atomic_add_acq_64
-#define atomic_cmpset_rel_64 atomic_cmpset_acq_64
-#define atomic_set_rel_64 atomic_set_acq_64
-#define atomic_subtract_rel_64 atomic_subtract_acq_64
+static __inline void
+atomic_add_rel_64(volatile uint64_t *p, uint64_t val)
+{
+ uint64_t tmp;
+ int res;
+
+ __asm __volatile(
+ "1: ldxr %0, [%2] \n"
+ " add %0, %0, %3 \n"
+ " stlxr %w1, %0, [%2] \n"
+ " cbnz %w1, 1b \n"
+ "2:"
+ : "=&r"(tmp), "=&r"(res), "+r" (p), "+r" (val) : : "cc", "memory"
+ );
+}
+
+static __inline void
+atomic_clear_rel_64(volatile uint64_t *p, uint64_t val)
+{
+ uint64_t tmp;
+ int res;
+
+ __asm __volatile(
+ "1: ldxr %0, [%2] \n"
+ " bic %0, %0, %3 \n"
+ " stlxr %w1, %0, [%2] \n"
+ " cbnz %w1, 1b \n"
+ : "=&r"(tmp), "=&r"(res), "+r" (p), "+r" (val) : : "cc", "memory"
+ );
+}
+
+static __inline int
+atomic_cmpset_rel_64(volatile uint64_t *p, uint64_t cmpval, uint64_t newval)
+{
+ uint64_t tmp;
+ int res;
+
+ __asm __volatile(
+ "1: mov %w1, #1 \n"
+ " ldxr %0, [%2] \n"
+ " cmp %0, %3 \n"
+ " b.ne 2f \n"
+ " stlxr %w1, %4, [%2] \n"
+ " cbnz %w1, 1b \n"
+ "2:"
+ : "=&r" (tmp), "=&r" (res), "+r" (p), "+r" (cmpval), "+r" (newval)
+ : : "cc", "memory"
+ );
+
+ return (!res);
+}
+
+static __inline void
+atomic_set_rel_64(volatile uint64_t *p, uint64_t val)
+{
+ uint64_t tmp;
+ int res;
+
+ __asm __volatile(
+ "1: ldxr %0, [%2] \n"
+ " orr %0, %0, %3 \n"
+ " stlxr %w1, %0, [%2] \n"
+ " cbnz %w1, 1b \n"
+ : "=&r"(tmp), "=&r"(res), "+r" (p), "+r" (val) : : "cc", "memory"
+ );
+}
+
+static __inline void
+atomic_store_rel_64(volatile uint64_t *p, uint64_t val)
+{
+
+ __asm __volatile(
+ "stlr %0, [%1] \n"
+ : : "r" (val), "r" (p) : "memory");
+}
+
+static __inline void
+atomic_subtract_rel_64(volatile uint64_t *p, uint64_t val)
+{
+ uint64_t tmp;
+ int res;
+
+ __asm __volatile(
+ "1: ldxr %0, [%2] \n"
+ " sub %0, %0, %3 \n"
+ " stlxr %w1, %0, [%2] \n"
+ " cbnz %w1, 1b \n"
+ : "=&r"(tmp), "=&r"(res), "+r" (p), "+r" (val) : : "cc", "memory"
+ );
+}
#define atomic_add_rel_long atomic_add_rel_64
-#define atomic_clear_rel_long atomic_add_rel_64
+#define atomic_clear_rel_long atomic_clear_rel_64
#define atomic_cmpset_rel_long atomic_cmpset_rel_64
#define atomic_set_rel_long atomic_set_rel_64
#define atomic_subtract_rel_long atomic_subtract_rel_64
#define atomic_store_rel_long atomic_store_rel_64
#define atomic_add_rel_ptr atomic_add_rel_64
-#define atomic_clear_rel_ptr atomic_add_rel_64
+#define atomic_clear_rel_ptr atomic_clear_rel_64
#define atomic_cmpset_rel_ptr atomic_cmpset_rel_64
#define atomic_set_rel_ptr atomic_set_rel_64
#define atomic_subtract_rel_ptr atomic_subtract_rel_64
More information about the svn-src-head
mailing list