Palacios Public Git Repository

To checkout Palacios execute

  git clone http://v3vee.org/palacios/palacios.web/palacios.git
This will give you the master branch. You probably want the devel branch or one of the release branches. To switch to the devel branch, simply execute
  cd palacios
  git checkout --track -b devel origin/devel
The other branches are similar.


Merge branch 'devel'
[palacios-OLD.git] / kitten / include / arch-x86_64 / rwlock.h
diff --git a/kitten/include/arch-x86_64/rwlock.h b/kitten/include/arch-x86_64/rwlock.h
new file mode 100644 (file)
index 0000000..60036f3
--- /dev/null
@@ -0,0 +1,86 @@
+/* include/arch-x86_64/rwlock.h
+ *
+ *     Helpers used by both rw spinlocks and rw semaphores.
+ *
+ *     Based in part on code from semaphore.h and
+ *     spinlock.h Copyright 1996 Linus Torvalds.
+ *
+ *     Copyright 1999 Red Hat, Inc.
+ *     Copyright 2001,2002 SuSE labs 
+ *
+ *     Written by Benjamin LaHaise.
+ *
+ *     This program is free software; you can redistribute it and/or
+ *     modify it under the terms of the GNU General Public License
+ *     as published by the Free Software Foundation; either version
+ *     2 of the License, or (at your option) any later version.
+ */
+#ifndef _ARCH_X86_64_RWLOCK_H
+#define _ARCH_X86_64_RWLOCK_H
+
+#include <lwk/stringify.h>
+
+#define RW_LOCK_BIAS            0x01000000
+#define RW_LOCK_BIAS_STR       "0x01000000"
+
+#define __build_read_lock_ptr(rw, helper)   \
+       asm volatile("lock ; subl $1,(%0)\n\t" \
+                    "js 2f\n" \
+                    "1:\n" \
+                   LOCK_SECTION_START("") \
+                    "2:\tcall " helper "\n\t" \
+                    "jmp 1b\n" \
+                   LOCK_SECTION_END \
+                    ::"a" (rw) : "memory")
+
+#define __build_read_lock_const(rw, helper)   \
+       asm volatile("lock ; subl $1,%0\n\t" \
+                    "js 2f\n" \
+                    "1:\n" \
+                   LOCK_SECTION_START("") \
+                    "2:\tpushq %%rax\n\t" \
+                    "leaq %0,%%rax\n\t" \
+                    "call " helper "\n\t" \
+                    "popq %%rax\n\t" \
+                    "jmp 1b\n" \
+                   LOCK_SECTION_END \
+                    :"=m" (*((volatile int *)rw))::"memory")
+
+#define __build_read_lock(rw, helper)  do { \
+                                               if (__builtin_constant_p(rw)) \
+                                                       __build_read_lock_const(rw, helper); \
+                                               else \
+                                                       __build_read_lock_ptr(rw, helper); \
+                                       } while (0)
+
+#define __build_write_lock_ptr(rw, helper) \
+       asm volatile("lock ; subl $" RW_LOCK_BIAS_STR ",(%0)\n\t" \
+                    "jnz 2f\n" \
+                    "1:\n" \
+                    LOCK_SECTION_START("") \
+                    "2:\tcall " helper "\n\t" \
+                    "jmp 1b\n" \
+                    LOCK_SECTION_END \
+                    ::"a" (rw) : "memory")
+
+#define __build_write_lock_const(rw, helper) \
+       asm volatile("lock ; subl $" RW_LOCK_BIAS_STR ",%0\n\t" \
+                    "jnz 2f\n" \
+                    "1:\n" \
+                   LOCK_SECTION_START("") \
+                    "2:\tpushq %%rax\n\t" \
+                    "leaq %0,%%rax\n\t" \
+                    "call " helper "\n\t" \
+                    "popq %%rax\n\t" \
+                    "jmp 1b\n" \
+                   LOCK_SECTION_END \
+                    :"=m" (*((volatile long *)rw))::"memory")
+
+#define __build_write_lock(rw, helper) do { \
+                                               if (__builtin_constant_p(rw)) \
+                                                       __build_write_lock_const(rw, helper); \
+                                               else \
+                                                       __build_write_lock_ptr(rw, helper); \
+                                       } while (0)
+
+#endif