• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
16#include <linux/linkage.h>
17#include <asm/rwlock.h>
18#include <asm/alternative-asm.h>
19#include <asm/frame.h>
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 */
32	.section .sched.text, "ax"
33
34/*
35 * rw spinlock fallbacks
36 */
37#ifdef CONFIG_SMP
38ENTRY(__write_lock_failed)
39	CFI_STARTPROC simple
40	FRAME
412: 	LOCK_PREFIX
42	addl	$ RW_LOCK_BIAS,(%eax)
431:	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
52	ENDPROC(__write_lock_failed)
53
54ENTRY(__read_lock_failed)
55	CFI_STARTPROC
56	FRAME
572: 	LOCK_PREFIX
58	incl	(%eax)
591:	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
68	ENDPROC(__read_lock_failed)
69
70#endif
71
72#ifdef CONFIG_RWSEM_XCHGADD_ALGORITHM
73
74/* Fix up special calling conventions */
75ENTRY(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
90	ENDPROC(call_rwsem_down_read_failed)
91
92ENTRY(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
102	ENDPROC(call_rwsem_down_write_failed)
103
104ENTRY(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
1141:	ret
115	CFI_ENDPROC
116	ENDPROC(call_rwsem_wake)
117
118/* Fix up special calling conventions */
119ENTRY(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
134	ENDPROC(call_rwsem_downgrade_wake)
135
136#endif
137