provide PAGE_SIZE as a constant value of 8192 on or1k
[musl] / arch / arm / atomic.h
index 8dc31b2..302e6d8 100644 (file)
@@ -22,11 +22,43 @@ static inline int a_ctz_64(uint64_t x)
        return a_ctz_l(y);
 }
 
+#if ((__ARM_ARCH_6__ || __ARM_ARCH_6K__ || __ARM_ARCH_6ZK__) && !__thumb__) \
+ || __ARM_ARCH_7A__ || __ARM_ARCH_7R__ || __ARM_ARCH >= 7
+
+#if __ARM_ARCH_7A__ || __ARM_ARCH_7R__ ||  __ARM_ARCH >= 7
+#define MEM_BARRIER "dmb ish"
+#else
+#define MEM_BARRIER "mcr p15,0,r0,c7,c10,5"
+#endif
+
+static inline int __k_cas(int t, int s, volatile int *p)
+{
+       int ret;
+       __asm__(
+               "       " MEM_BARRIER "\n"
+               "1:     ldrex %0,%3\n"
+               "       subs %0,%0,%1\n"
+#ifdef __thumb__
+               "       itt eq\n"
+#endif
+               "       strexeq %0,%2,%3\n"
+               "       teqeq %0,#1\n"
+               "       beq 1b\n"
+               "       " MEM_BARRIER "\n"
+               : "=&r"(ret)
+               : "r"(t), "r"(s), "Q"(*p)
+               : "memory", "cc" );
+       return ret;
+}
+#else
+#define __k_cas ((int (*)(int, int, volatile int *))0xffff0fc0)
+#endif
+
 static inline int a_cas(volatile int *p, int t, int s)
 {
        int old;
        for (;;) {
-               if (!((int (*)(int, int, volatile int *))0xffff0fc0)(t, s, p))
+               if (!__k_cas(t, s, p))
                        return t;
                if ((old=*p) != t)
                        return old;
@@ -38,16 +70,11 @@ static inline void *a_cas_p(volatile void *p, void *t, void *s)
        return (void *)a_cas(p, (int)t, (int)s);
 }
 
-static inline long a_cas_l(volatile void *p, long t, long s)
-{
-       return a_cas(p, t, s);
-}
-
 static inline int a_swap(volatile int *x, int v)
 {
        int old;
        do old = *x;
-       while (a_cas(x, old, v) != old);
+       while (__k_cas(old, v, x));
        return old;
 }
 
@@ -55,7 +82,7 @@ static inline int a_fetch_add(volatile int *x, int v)
 {
        int old;
        do old = *x;
-       while (a_cas(x, old, old+v) != old);
+       while (__k_cas(old, old+v, x));
        return old;
 }
 
@@ -71,7 +98,7 @@ static inline void a_dec(volatile int *x)
 
 static inline void a_store(volatile int *p, int x)
 {
-       *p=x;
+       while (__k_cas(*p, x, p));
 }
 
 static inline void a_spin()
@@ -87,26 +114,33 @@ static inline void a_and(volatile int *p, int v)
 {
        int old;
        do old = *p;
-       while (a_cas(p, old, old&v) != old);
+       while (__k_cas(old, old&v, p));
 }
 
 static inline void a_or(volatile int *p, int v)
 {
        int old;
        do old = *p;
-       while (a_cas(p, old, old|v) != old);
+       while (__k_cas(old, old|v, p));
+}
+
+static inline void a_or_l(volatile void *p, long v)
+{
+       a_or(p, v);
 }
 
 static inline void a_and_64(volatile uint64_t *p, uint64_t v)
 {
-       a_and((int *)p, v);
-       a_and((int *)p+1, v>>32);
+       union { uint64_t v; uint32_t r[2]; } u = { v };
+       a_and((int *)p, u.r[0]);
+       a_and((int *)p+1, u.r[1]);
 }
 
 static inline void a_or_64(volatile uint64_t *p, uint64_t v)
 {
-       a_or((int *)p, v);
-       a_or((int *)p+1, v>>32);
+       union { uint64_t v; uint32_t r[2]; } u = { v };
+       a_or((int *)p, u.r[0]);
+       a_or((int *)p+1, u.r[1]);
 }
 
 #endif