aboutsummaryrefslogtreecommitdiffstats
path: root/include/asm-x86_64/rwlock.h
diff options
context:
space:
mode:
authorAndi Kleen <ak@suse.de>2006-09-26 04:52:28 -0400
committerAndi Kleen <andi@basil.nowhere.org>2006-09-26 04:52:28 -0400
commit9a0b26e6bc4ae1979d9bcc6194e57a71b2b5cac6 (patch)
tree01601a502007b85d4fc88f79de7a93c257ef9d97 /include/asm-x86_64/rwlock.h
parentb4062b16094038334d9bbadac0397a3fc9e981b0 (diff)
[PATCH] Clean up read write lock assembly
- Move the slow path fallbacks to their own assembly files This makes them much easier to read and is needed for the next change. - Add CFI annotations for unwinding (XXX need review) - Remove constant case which can never happen with out of line spinlocks - Use patchable LOCK prefixes - Don't use lock sections anymore for inline code because they can't be expressed by the unwinder (this adds one taken jump to the lock fast path) Cc: jbeulich@novell.com Signed-off-by: Andi Kleen <ak@suse.de>
Diffstat (limited to 'include/asm-x86_64/rwlock.h')
-rw-r--r--include/asm-x86_64/rwlock.h68
1 files changed, 10 insertions, 58 deletions
diff --git a/include/asm-x86_64/rwlock.h b/include/asm-x86_64/rwlock.h
index dea0e9459264..28a080d23119 100644
--- a/include/asm-x86_64/rwlock.h
+++ b/include/asm-x86_64/rwlock.h
@@ -18,69 +18,21 @@
18#ifndef _ASM_X86_64_RWLOCK_H 18#ifndef _ASM_X86_64_RWLOCK_H
19#define _ASM_X86_64_RWLOCK_H 19#define _ASM_X86_64_RWLOCK_H
20 20
21#include <linux/stringify.h>
22
23#define RW_LOCK_BIAS 0x01000000 21#define RW_LOCK_BIAS 0x01000000
24#define RW_LOCK_BIAS_STR "0x01000000" 22#define RW_LOCK_BIAS_STR "0x01000000"
25 23
26#define __build_read_lock_ptr(rw, helper) \ 24#define __build_read_lock(rw) \
27 asm volatile(LOCK_PREFIX "subl $1,(%0)\n\t" \ 25 asm volatile(LOCK_PREFIX "subl $1,(%0)\n\t" \
28 "js 2f\n" \ 26 "jns 1f\n" \
29 "1:\n" \ 27 "call __read_lock_failed\n" \
30 LOCK_SECTION_START("") \
31 "2:\tcall " helper "\n\t" \
32 "jmp 1b\n" \
33 LOCK_SECTION_END \
34 ::"a" (rw) : "memory")
35
36#define __build_read_lock_const(rw, helper) \
37 asm volatile(LOCK_PREFIX "subl $1,%0\n\t" \
38 "js 2f\n" \
39 "1:\n" \ 28 "1:\n" \
40 LOCK_SECTION_START("") \ 29 ::"D" (rw), "i" (RW_LOCK_BIAS) : "memory")
41 "2:\tpushq %%rax\n\t" \
42 "leaq %0,%%rax\n\t" \
43 "call " helper "\n\t" \
44 "popq %%rax\n\t" \
45 "jmp 1b\n" \
46 LOCK_SECTION_END \
47 :"=m" (*((volatile int *)rw))::"memory")
48
49#define __build_read_lock(rw, helper) do { \
50 if (__builtin_constant_p(rw)) \
51 __build_read_lock_const(rw, helper); \
52 else \
53 __build_read_lock_ptr(rw, helper); \
54 } while (0)
55 30
56#define __build_write_lock_ptr(rw, helper) \ 31#define __build_write_lock(rw) \
57 asm volatile(LOCK_PREFIX "subl $" RW_LOCK_BIAS_STR ",(%0)\n\t" \ 32 asm volatile(LOCK_PREFIX "subl %1,(%0)\n\t" \
58 "jnz 2f\n" \ 33 "jz 1f\n" \
34 "\tcall __write_lock_failed\n\t" \
59 "1:\n" \ 35 "1:\n" \
60 LOCK_SECTION_START("") \ 36 ::"D" (rw), "i" (RW_LOCK_BIAS) : "memory")
61 "2:\tcall " helper "\n\t" \
62 "jmp 1b\n" \
63 LOCK_SECTION_END \
64 ::"a" (rw) : "memory")
65
66#define __build_write_lock_const(rw, helper) \
67 asm volatile(LOCK_PREFIX "subl $" RW_LOCK_BIAS_STR ",%0\n\t" \
68 "jnz 2f\n" \
69 "1:\n" \
70 LOCK_SECTION_START("") \
71 "2:\tpushq %%rax\n\t" \
72 "leaq %0,%%rax\n\t" \
73 "call " helper "\n\t" \
74 "popq %%rax\n\t" \
75 "jmp 1b\n" \
76 LOCK_SECTION_END \
77 :"=m" (*((volatile long *)rw))::"memory")
78
79#define __build_write_lock(rw, helper) do { \
80 if (__builtin_constant_p(rw)) \
81 __build_write_lock_const(rw, helper); \
82 else \
83 __build_write_lock_ptr(rw, helper); \
84 } while (0)
85 37
86#endif 38#endif