Add the rt linux 4.1.3-rt3 as base
[kvmfornfv.git] / kernel / arch / alpha / lib / dec_and_lock.c
diff --git a/kernel/arch/alpha/lib/dec_and_lock.c b/kernel/arch/alpha/lib/dec_and_lock.c
new file mode 100644 (file)
index 0000000..f9f5fe8
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+ * arch/alpha/lib/dec_and_lock.c
+ *
+ * ll/sc version of atomic_dec_and_lock()
+ * 
+ */
+
+#include <linux/spinlock.h>
+#include <linux/atomic.h>
+
+  asm (".text                                  \n\
+       .global _atomic_dec_and_lock            \n\
+       .ent _atomic_dec_and_lock               \n\
+       .align  4                               \n\
+_atomic_dec_and_lock:                          \n\
+       .prologue 0                             \n\
+1:     ldl_l   $1, 0($16)                      \n\
+       subl    $1, 1, $1                       \n\
+       beq     $1, 2f                          \n\
+       stl_c   $1, 0($16)                      \n\
+       beq     $1, 4f                          \n\
+       mb                                      \n\
+       clr     $0                              \n\
+       ret                                     \n\
+2:     br      $29, 3f                         \n\
+3:     ldgp    $29, 0($29)                     \n\
+       br      $atomic_dec_and_lock_1..ng      \n\
+       .subsection 2                           \n\
+4:     br      1b                              \n\
+       .previous                               \n\
+       .end _atomic_dec_and_lock");
+
+static int __used atomic_dec_and_lock_1(atomic_t *atomic, spinlock_t *lock)
+{
+       /* Slow path */
+       spin_lock(lock);
+       if (atomic_dec_and_test(atomic))
+               return 1;
+       spin_unlock(lock);
+       return 0;
+}