]> xenbits.xensource.com Git - people/dwmw2/xen.git/commitdiff
atomic: add atomic_and operations
authorRoger Pau Monné <roger.pau@citrix.com>
Wed, 26 Feb 2020 09:51:31 +0000 (10:51 +0100)
committerJan Beulich <jbeulich@suse.com>
Wed, 26 Feb 2020 09:51:31 +0000 (10:51 +0100)
To x86 and Arm. This performs an atomic AND operation against an
atomic_t variable with the provided mask.

Requested-by: Jan Beulich <jbeulich@suse.com>
Signed-off-by: Roger Pau Monné <roger.pau@citrix.com>
Reviewed-by: Jan Beulich <jbeulich@suse.com>
Reviewed-by: Julien Grall <julien@xen.org>
xen/include/asm-arm/arm32/atomic.h
xen/include/asm-arm/arm64/atomic.h
xen/include/asm-x86/atomic.h

index c03eb684cd9e8a603104b30d52d8060492b90f89..2832a727920a2b43922d1744a75fb4995337821a 100644 (file)
@@ -96,6 +96,23 @@ static inline int atomic_sub_return(int i, atomic_t *v)
        return result;
 }
 
+static inline void atomic_and(int m, atomic_t *v)
+{
+       unsigned long tmp;
+       int result;
+
+       prefetchw(&v->counter);
+       __asm__ __volatile__("@ atomic_and\n"
+"1:    ldrex   %0, [%3]\n"
+"      and     %0, %0, %4\n"
+"      strex   %1, %0, [%3]\n"
+"      teq     %1, #0\n"
+"      bne     1b"
+       : "=&r" (result), "=&r" (tmp), "+Qo" (v->counter)
+       : "r" (&v->counter), "Ir" (m)
+       : "cc");
+}
+
 static inline int atomic_cmpxchg(atomic_t *ptr, int old, int new)
 {
        int oldval;
index bce38d4ca27acaed034483c055b1e25f65743286..2d425678660b90f2417317bc66c16691b5679c12 100644 (file)
@@ -91,6 +91,20 @@ static inline int atomic_sub_return(int i, atomic_t *v)
        return result;
 }
 
+static inline void atomic_and(int m, atomic_t *v)
+{
+       unsigned long tmp;
+       int result;
+
+       asm volatile("// atomic_and\n"
+"1:    ldxr    %w0, %2\n"
+"      and     %w0, %w0, %w3\n"
+"      stxr    %w1, %w0, %2\n"
+"      cbnz    %w1, 1b"
+       : "=&r" (result), "=&r" (tmp), "+Q" (v->counter)
+       : "Ir" (m));
+}
+
 static inline int atomic_cmpxchg(atomic_t *ptr, int old, int new)
 {
        unsigned long tmp;
index 682bcf91b1b0b1eb8c8c967e62859c1a8b9e4c2d..6b40f9c9f8724b1d2a2171866a6e51276d6af4bb 100644 (file)
@@ -224,6 +224,14 @@ static inline int atomic_add_unless(atomic_t *v, int a, int u)
     return c;
 }
 
+static inline void atomic_and(int m, atomic_t *v)
+{
+    asm volatile (
+        "lock andl %1, %0"
+        : "+m" (*(volatile int *)&v->counter)
+        : "ir" (m) );
+}
+
 #define atomic_xchg(v, new) (xchg(&((v)->counter), new))
 
 #endif /* __ARCH_X86_ATOMIC__ */