Commit | Line | Data |
---|---|---|
ecaf45ee AK |
1 | /* |
2 | * i386 semaphore implementation. | |
3 | * | |
4 | * (C) Copyright 1999 Linus Torvalds | |
5 | * | |
6 | * Portions Copyright 1999 Red Hat, Inc. | |
7 | * | |
8 | * This program is free software; you can redistribute it and/or | |
9 | * modify it under the terms of the GNU General Public License | |
10 | * as published by the Free Software Foundation; either version | |
11 | * 2 of the License, or (at your option) any later version. | |
12 | * | |
13 | * rw semaphores implemented November 1999 by Benjamin LaHaise <bcrl@kvack.org> | |
14 | */ | |
15 | ||
ecaf45ee AK |
16 | #include <linux/linkage.h> |
17 | #include <asm/rwlock.h> | |
7e02cb94 AB |
18 | #include <asm/alternative-asm.h> |
19 | #include <asm/frame.h> | |
ecaf45ee AK |
20 | #include <asm/dwarf2.h> |
21 | ||
22 | /* | |
23 | * The semaphore operations have a special calling sequence that | |
24 | * allow us to do a simpler in-line version of them. These routines | |
25 | * need to convert that sequence back into the C sequence when | |
26 | * there is contention on the semaphore. | |
27 | * | |
28 | * %eax contains the semaphore pointer on entry. Save the C-clobbered | |
29 | * registers (%eax, %edx and %ecx) except %eax whish is either a return | |
30 | * value or just clobbered.. | |
31 | */ | |
c6c2d7a0 | 32 | .section .sched.text, "ax" |
ecaf45ee AK |
33 | |
34 | /* | |
35 | * rw spinlock fallbacks | |
36 | */ | |
37 | #ifdef CONFIG_SMP | |
38 | ENTRY(__write_lock_failed) | |
39 | CFI_STARTPROC simple | |
40 | FRAME | |
41 | 2: LOCK_PREFIX | |
42 | addl $ RW_LOCK_BIAS,(%eax) | |
43 | 1: rep; nop | |
44 | cmpl $ RW_LOCK_BIAS,(%eax) | |
45 | jne 1b | |
46 | LOCK_PREFIX | |
47 | subl $ RW_LOCK_BIAS,(%eax) | |
48 | jnz 2b | |
49 | ENDFRAME | |
50 | ret | |
51 | CFI_ENDPROC | |
6b8be6df | 52 | ENDPROC(__write_lock_failed) |
ecaf45ee AK |
53 | |
54 | ENTRY(__read_lock_failed) | |
55 | CFI_STARTPROC | |
56 | FRAME | |
57 | 2: LOCK_PREFIX | |
58 | incl (%eax) | |
59 | 1: rep; nop | |
60 | cmpl $1,(%eax) | |
61 | js 1b | |
62 | LOCK_PREFIX | |
63 | decl (%eax) | |
64 | js 2b | |
65 | ENDFRAME | |
66 | ret | |
67 | CFI_ENDPROC | |
6b8be6df | 68 | ENDPROC(__read_lock_failed) |
ecaf45ee AK |
69 | |
70 | #endif | |
add659bf | 71 | |
88271e9e IM |
72 | #ifdef CONFIG_RWSEM_XCHGADD_ALGORITHM |
73 | ||
add659bf AK |
74 | /* Fix up special calling conventions */ |
75 | ENTRY(call_rwsem_down_read_failed) | |
76 | CFI_STARTPROC | |
77 | push %ecx | |
78 | CFI_ADJUST_CFA_OFFSET 4 | |
79 | CFI_REL_OFFSET ecx,0 | |
80 | push %edx | |
81 | CFI_ADJUST_CFA_OFFSET 4 | |
82 | CFI_REL_OFFSET edx,0 | |
83 | call rwsem_down_read_failed | |
84 | pop %edx | |
85 | CFI_ADJUST_CFA_OFFSET -4 | |
86 | pop %ecx | |
87 | CFI_ADJUST_CFA_OFFSET -4 | |
88 | ret | |
89 | CFI_ENDPROC | |
6b8be6df | 90 | ENDPROC(call_rwsem_down_read_failed) |
add659bf AK |
91 | |
92 | ENTRY(call_rwsem_down_write_failed) | |
93 | CFI_STARTPROC | |
94 | push %ecx | |
95 | CFI_ADJUST_CFA_OFFSET 4 | |
96 | CFI_REL_OFFSET ecx,0 | |
97 | calll rwsem_down_write_failed | |
98 | pop %ecx | |
99 | CFI_ADJUST_CFA_OFFSET -4 | |
100 | ret | |
101 | CFI_ENDPROC | |
6b8be6df | 102 | ENDPROC(call_rwsem_down_write_failed) |
add659bf AK |
103 | |
104 | ENTRY(call_rwsem_wake) | |
105 | CFI_STARTPROC | |
106 | decw %dx /* do nothing if still outstanding active readers */ | |
107 | jnz 1f | |
108 | push %ecx | |
109 | CFI_ADJUST_CFA_OFFSET 4 | |
110 | CFI_REL_OFFSET ecx,0 | |
111 | call rwsem_wake | |
112 | pop %ecx | |
113 | CFI_ADJUST_CFA_OFFSET -4 | |
114 | 1: ret | |
115 | CFI_ENDPROC | |
6b8be6df | 116 | ENDPROC(call_rwsem_wake) |
add659bf AK |
117 | |
118 | /* Fix up special calling conventions */ | |
119 | ENTRY(call_rwsem_downgrade_wake) | |
120 | CFI_STARTPROC | |
121 | push %ecx | |
122 | CFI_ADJUST_CFA_OFFSET 4 | |
123 | CFI_REL_OFFSET ecx,0 | |
124 | push %edx | |
125 | CFI_ADJUST_CFA_OFFSET 4 | |
126 | CFI_REL_OFFSET edx,0 | |
127 | call rwsem_downgrade_wake | |
128 | pop %edx | |
129 | CFI_ADJUST_CFA_OFFSET -4 | |
130 | pop %ecx | |
131 | CFI_ADJUST_CFA_OFFSET -4 | |
132 | ret | |
133 | CFI_ENDPROC | |
6b8be6df | 134 | ENDPROC(call_rwsem_downgrade_wake) |
add659bf | 135 | |
88271e9e | 136 | #endif |