diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2008-04-18 11:25:29 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2008-04-18 11:25:29 -0400 |
commit | d7bb545d86825e635cab33a1dd81ca0ad7b92887 (patch) | |
tree | 34da4139ef06ceab6549aea3906639c7413978c8 | |
parent | 75e98b34155264d943aa53edce465e87f3ccbadf (diff) | |
parent | 2342e51ba2b52a7f5b78227e6faa4603ed3632a0 (diff) |
Merge branch 'semaphore' of git://git.kernel.org/pub/scm/linux/kernel/git/willy/misc
* 'semaphore' of git://git.kernel.org/pub/scm/linux/kernel/git/willy/misc:
Remove DEBUG_SEMAPHORE from Kconfig
Improve semaphore documentation
Simplify semaphore implementation
Add down_timeout and change ACPI to use it
Introduce down_killable()
Generic semaphore implementation
Add semaphore.h to kernel_lock.c
Fix quota.h includes
117 files changed, 393 insertions, 7759 deletions
diff --git a/arch/alpha/kernel/Makefile b/arch/alpha/kernel/Makefile index dccf05245d4d..ac706c1d7ada 100644 --- a/arch/alpha/kernel/Makefile +++ b/arch/alpha/kernel/Makefile | |||
@@ -7,7 +7,7 @@ EXTRA_AFLAGS := $(KBUILD_CFLAGS) | |||
7 | EXTRA_CFLAGS := -Werror -Wno-sign-compare | 7 | EXTRA_CFLAGS := -Werror -Wno-sign-compare |
8 | 8 | ||
9 | obj-y := entry.o traps.o process.o init_task.o osf_sys.o irq.o \ | 9 | obj-y := entry.o traps.o process.o init_task.o osf_sys.o irq.o \ |
10 | irq_alpha.o signal.o setup.o ptrace.o time.o semaphore.o \ | 10 | irq_alpha.o signal.o setup.o ptrace.o time.o \ |
11 | alpha_ksyms.o systbls.o err_common.o io.o | 11 | alpha_ksyms.o systbls.o err_common.o io.o |
12 | 12 | ||
13 | obj-$(CONFIG_VGA_HOSE) += console.o | 13 | obj-$(CONFIG_VGA_HOSE) += console.o |
diff --git a/arch/alpha/kernel/alpha_ksyms.c b/arch/alpha/kernel/alpha_ksyms.c index e9762a33b043..d96e742d4dc2 100644 --- a/arch/alpha/kernel/alpha_ksyms.c +++ b/arch/alpha/kernel/alpha_ksyms.c | |||
@@ -77,15 +77,6 @@ EXPORT_SYMBOL(__do_clear_user); | |||
77 | EXPORT_SYMBOL(__strncpy_from_user); | 77 | EXPORT_SYMBOL(__strncpy_from_user); |
78 | EXPORT_SYMBOL(__strnlen_user); | 78 | EXPORT_SYMBOL(__strnlen_user); |
79 | 79 | ||
80 | /* Semaphore helper functions. */ | ||
81 | EXPORT_SYMBOL(__down_failed); | ||
82 | EXPORT_SYMBOL(__down_failed_interruptible); | ||
83 | EXPORT_SYMBOL(__up_wakeup); | ||
84 | EXPORT_SYMBOL(down); | ||
85 | EXPORT_SYMBOL(down_interruptible); | ||
86 | EXPORT_SYMBOL(down_trylock); | ||
87 | EXPORT_SYMBOL(up); | ||
88 | |||
89 | /* | 80 | /* |
90 | * SMP-specific symbols. | 81 | * SMP-specific symbols. |
91 | */ | 82 | */ |
diff --git a/arch/alpha/kernel/semaphore.c b/arch/alpha/kernel/semaphore.c deleted file mode 100644 index 8d2982aa1b8d..000000000000 --- a/arch/alpha/kernel/semaphore.c +++ /dev/null | |||
@@ -1,224 +0,0 @@ | |||
1 | /* | ||
2 | * Alpha semaphore implementation. | ||
3 | * | ||
4 | * (C) Copyright 1996 Linus Torvalds | ||
5 | * (C) Copyright 1999, 2000 Richard Henderson | ||
6 | */ | ||
7 | |||
8 | #include <linux/errno.h> | ||
9 | #include <linux/sched.h> | ||
10 | #include <linux/init.h> | ||
11 | |||
12 | /* | ||
13 | * This is basically the PPC semaphore scheme ported to use | ||
14 | * the Alpha ll/sc sequences, so see the PPC code for | ||
15 | * credits. | ||
16 | */ | ||
17 | |||
18 | /* | ||
19 | * Atomically update sem->count. | ||
20 | * This does the equivalent of the following: | ||
21 | * | ||
22 | * old_count = sem->count; | ||
23 | * tmp = MAX(old_count, 0) + incr; | ||
24 | * sem->count = tmp; | ||
25 | * return old_count; | ||
26 | */ | ||
27 | static inline int __sem_update_count(struct semaphore *sem, int incr) | ||
28 | { | ||
29 | long old_count, tmp = 0; | ||
30 | |||
31 | __asm__ __volatile__( | ||
32 | "1: ldl_l %0,%2\n" | ||
33 | " cmovgt %0,%0,%1\n" | ||
34 | " addl %1,%3,%1\n" | ||
35 | " stl_c %1,%2\n" | ||
36 | " beq %1,2f\n" | ||
37 | " mb\n" | ||
38 | ".subsection 2\n" | ||
39 | "2: br 1b\n" | ||
40 | ".previous" | ||
41 | : "=&r" (old_count), "=&r" (tmp), "=m" (sem->count) | ||
42 | : "Ir" (incr), "1" (tmp), "m" (sem->count)); | ||
43 | |||
44 | return old_count; | ||
45 | } | ||
46 | |||
47 | /* | ||
48 | * Perform the "down" function. Return zero for semaphore acquired, | ||
49 | * return negative for signalled out of the function. | ||
50 | * | ||
51 | * If called from down, the return is ignored and the wait loop is | ||
52 | * not interruptible. This means that a task waiting on a semaphore | ||
53 | * using "down()" cannot be killed until someone does an "up()" on | ||
54 | * the semaphore. | ||
55 | * | ||
56 | * If called from down_interruptible, the return value gets checked | ||
57 | * upon return. If the return value is negative then the task continues | ||
58 | * with the negative value in the return register (it can be tested by | ||
59 | * the caller). | ||
60 | * | ||
61 | * Either form may be used in conjunction with "up()". | ||
62 | */ | ||
63 | |||
64 | void __sched | ||
65 | __down_failed(struct semaphore *sem) | ||
66 | { | ||
67 | struct task_struct *tsk = current; | ||
68 | DECLARE_WAITQUEUE(wait, tsk); | ||
69 | |||
70 | #ifdef CONFIG_DEBUG_SEMAPHORE | ||
71 | printk("%s(%d): down failed(%p)\n", | ||
72 | tsk->comm, task_pid_nr(tsk), sem); | ||
73 | #endif | ||
74 | |||
75 | tsk->state = TASK_UNINTERRUPTIBLE; | ||
76 | wmb(); | ||
77 | add_wait_queue_exclusive(&sem->wait, &wait); | ||
78 | |||
79 | /* | ||
80 | * Try to get the semaphore. If the count is > 0, then we've | ||
81 | * got the semaphore; we decrement count and exit the loop. | ||
82 | * If the count is 0 or negative, we set it to -1, indicating | ||
83 | * that we are asleep, and then sleep. | ||
84 | */ | ||
85 | while (__sem_update_count(sem, -1) <= 0) { | ||
86 | schedule(); | ||
87 | set_task_state(tsk, TASK_UNINTERRUPTIBLE); | ||
88 | } | ||
89 | remove_wait_queue(&sem->wait, &wait); | ||
90 | tsk->state = TASK_RUNNING; | ||
91 | |||
92 | /* | ||
93 | * If there are any more sleepers, wake one of them up so | ||
94 | * that it can either get the semaphore, or set count to -1 | ||
95 | * indicating that there are still processes sleeping. | ||
96 | */ | ||
97 | wake_up(&sem->wait); | ||
98 | |||
99 | #ifdef CONFIG_DEBUG_SEMAPHORE | ||
100 | printk("%s(%d): down acquired(%p)\n", | ||
101 | tsk->comm, task_pid_nr(tsk), sem); | ||
102 | #endif | ||
103 | } | ||
104 | |||
105 | int __sched | ||
106 | __down_failed_interruptible(struct semaphore *sem) | ||
107 | { | ||
108 | struct task_struct *tsk = current; | ||
109 | DECLARE_WAITQUEUE(wait, tsk); | ||
110 | long ret = 0; | ||
111 | |||
112 | #ifdef CONFIG_DEBUG_SEMAPHORE | ||
113 | printk("%s(%d): down failed(%p)\n", | ||
114 | tsk->comm, task_pid_nr(tsk), sem); | ||
115 | #endif | ||
116 | |||
117 | tsk->state = TASK_INTERRUPTIBLE; | ||
118 | wmb(); | ||
119 | add_wait_queue_exclusive(&sem->wait, &wait); | ||
120 | |||
121 | while (__sem_update_count(sem, -1) <= 0) { | ||
122 | if (signal_pending(current)) { | ||
123 | /* | ||
124 | * A signal is pending - give up trying. | ||
125 | * Set sem->count to 0 if it is negative, | ||
126 | * since we are no longer sleeping. | ||
127 | */ | ||
128 | __sem_update_count(sem, 0); | ||
129 | ret = -EINTR; | ||
130 | break; | ||
131 | } | ||
132 | schedule(); | ||
133 | set_task_state(tsk, TASK_INTERRUPTIBLE); | ||
134 | } | ||
135 | |||
136 | remove_wait_queue(&sem->wait, &wait); | ||
137 | tsk->state = TASK_RUNNING; | ||
138 | wake_up(&sem->wait); | ||
139 | |||
140 | #ifdef CONFIG_DEBUG_SEMAPHORE | ||
141 | printk("%s(%d): down %s(%p)\n", | ||
142 | current->comm, task_pid_nr(current), | ||
143 | (ret < 0 ? "interrupted" : "acquired"), sem); | ||
144 | #endif | ||
145 | return ret; | ||
146 | } | ||
147 | |||
148 | void | ||
149 | __up_wakeup(struct semaphore *sem) | ||
150 | { | ||
151 | /* | ||
152 | * Note that we incremented count in up() before we came here, | ||
153 | * but that was ineffective since the result was <= 0, and | ||
154 | * any negative value of count is equivalent to 0. | ||
155 | * This ends up setting count to 1, unless count is now > 0 | ||
156 | * (i.e. because some other cpu has called up() in the meantime), | ||
157 | * in which case we just increment count. | ||
158 | */ | ||
159 | __sem_update_count(sem, 1); | ||
160 | wake_up(&sem->wait); | ||
161 | } | ||
162 | |||
163 | void __sched | ||
164 | down(struct semaphore *sem) | ||
165 | { | ||
166 | #ifdef WAITQUEUE_DEBUG | ||
167 | CHECK_MAGIC(sem->__magic); | ||
168 | #endif | ||
169 | #ifdef CONFIG_DEBUG_SEMAPHORE | ||
170 | printk("%s(%d): down(%p) <count=%d> from %p\n", | ||
171 | current->comm, task_pid_nr(current), sem, | ||
172 | atomic_read(&sem->count), __builtin_return_address(0)); | ||
173 | #endif | ||
174 | __down(sem); | ||
175 | } | ||
176 | |||
177 | int __sched | ||
178 | down_interruptible(struct semaphore *sem) | ||
179 | { | ||
180 | #ifdef WAITQUEUE_DEBUG | ||
181 | CHECK_MAGIC(sem->__magic); | ||
182 | #endif | ||
183 | #ifdef CONFIG_DEBUG_SEMAPHORE | ||
184 | printk("%s(%d): down(%p) <count=%d> from %p\n", | ||
185 | current->comm, task_pid_nr(current), sem, | ||
186 | atomic_read(&sem->count), __builtin_return_address(0)); | ||
187 | #endif | ||
188 | return __down_interruptible(sem); | ||
189 | } | ||
190 | |||
191 | int | ||
192 | down_trylock(struct semaphore *sem) | ||
193 | { | ||
194 | int ret; | ||
195 | |||
196 | #ifdef WAITQUEUE_DEBUG | ||
197 | CHECK_MAGIC(sem->__magic); | ||
198 | #endif | ||
199 | |||
200 | ret = __down_trylock(sem); | ||
201 | |||
202 | #ifdef CONFIG_DEBUG_SEMAPHORE | ||
203 | printk("%s(%d): down_trylock %s from %p\n", | ||
204 | current->comm, task_pid_nr(current), | ||
205 | ret ? "failed" : "acquired", | ||
206 | __builtin_return_address(0)); | ||
207 | #endif | ||
208 | |||
209 | return ret; | ||
210 | } | ||
211 | |||
212 | void | ||
213 | up(struct semaphore *sem) | ||
214 | { | ||
215 | #ifdef WAITQUEUE_DEBUG | ||
216 | CHECK_MAGIC(sem->__magic); | ||
217 | #endif | ||
218 | #ifdef CONFIG_DEBUG_SEMAPHORE | ||
219 | printk("%s(%d): up(%p) <count=%d> from %p\n", | ||
220 | current->comm, task_pid_nr(current), sem, | ||
221 | atomic_read(&sem->count), __builtin_return_address(0)); | ||
222 | #endif | ||
223 | __up(sem); | ||
224 | } | ||
diff --git a/arch/arm/kernel/Makefile b/arch/arm/kernel/Makefile index 00d44c6fbfe9..6235f72a14f0 100644 --- a/arch/arm/kernel/Makefile +++ b/arch/arm/kernel/Makefile | |||
@@ -7,7 +7,7 @@ AFLAGS_head.o := -DTEXT_OFFSET=$(TEXT_OFFSET) | |||
7 | # Object file lists. | 7 | # Object file lists. |
8 | 8 | ||
9 | obj-y := compat.o entry-armv.o entry-common.o irq.o \ | 9 | obj-y := compat.o entry-armv.o entry-common.o irq.o \ |
10 | process.o ptrace.o semaphore.o setup.o signal.o \ | 10 | process.o ptrace.o setup.o signal.o \ |
11 | sys_arm.o stacktrace.o time.o traps.o | 11 | sys_arm.o stacktrace.o time.o traps.o |
12 | 12 | ||
13 | obj-$(CONFIG_ISA_DMA_API) += dma.o | 13 | obj-$(CONFIG_ISA_DMA_API) += dma.o |
diff --git a/arch/arm/kernel/semaphore.c b/arch/arm/kernel/semaphore.c deleted file mode 100644 index 981fe5c6ccbe..000000000000 --- a/arch/arm/kernel/semaphore.c +++ /dev/null | |||
@@ -1,221 +0,0 @@ | |||
1 | /* | ||
2 | * ARM semaphore implementation, taken from | ||
3 | * | ||
4 | * i386 semaphore implementation. | ||
5 | * | ||
6 | * (C) Copyright 1999 Linus Torvalds | ||
7 | * | ||
8 | * Modified for ARM by Russell King | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify | ||
11 | * it under the terms of the GNU General Public License version 2 as | ||
12 | * published by the Free Software Foundation. | ||
13 | */ | ||
14 | #include <linux/module.h> | ||
15 | #include <linux/sched.h> | ||
16 | #include <linux/errno.h> | ||
17 | #include <linux/init.h> | ||
18 | |||
19 | #include <asm/semaphore.h> | ||
20 | |||
21 | /* | ||
22 | * Semaphores are implemented using a two-way counter: | ||
23 | * The "count" variable is decremented for each process | ||
24 | * that tries to acquire the semaphore, while the "sleeping" | ||
25 | * variable is a count of such acquires. | ||
26 | * | ||
27 | * Notably, the inline "up()" and "down()" functions can | ||
28 | * efficiently test if they need to do any extra work (up | ||
29 | * needs to do something only if count was negative before | ||
30 | * the increment operation. | ||
31 | * | ||
32 | * "sleeping" and the contention routine ordering is | ||
33 | * protected by the semaphore spinlock. | ||
34 | * | ||
35 | * Note that these functions are only called when there is | ||
36 | * contention on the lock, and as such all this is the | ||
37 | * "non-critical" part of the whole semaphore business. The | ||
38 | * critical part is the inline stuff in <asm/semaphore.h> | ||
39 | * where we want to avoid any extra jumps and calls. | ||
40 | */ | ||
41 | |||
42 | /* | ||
43 | * Logic: | ||
44 | * - only on a boundary condition do we need to care. When we go | ||
45 | * from a negative count to a non-negative, we wake people up. | ||
46 | * - when we go from a non-negative count to a negative do we | ||
47 | * (a) synchronize with the "sleeper" count and (b) make sure | ||
48 | * that we're on the wakeup list before we synchronize so that | ||
49 | * we cannot lose wakeup events. | ||
50 | */ | ||
51 | |||
52 | void __up(struct semaphore *sem) | ||
53 | { | ||
54 | wake_up(&sem->wait); | ||
55 | } | ||
56 | |||
57 | static DEFINE_SPINLOCK(semaphore_lock); | ||
58 | |||
59 | void __sched __down(struct semaphore * sem) | ||
60 | { | ||
61 | struct task_struct *tsk = current; | ||
62 | DECLARE_WAITQUEUE(wait, tsk); | ||
63 | tsk->state = TASK_UNINTERRUPTIBLE; | ||
64 | add_wait_queue_exclusive(&sem->wait, &wait); | ||
65 | |||
66 | spin_lock_irq(&semaphore_lock); | ||
67 | sem->sleepers++; | ||
68 | for (;;) { | ||
69 | int sleepers = sem->sleepers; | ||
70 | |||
71 | /* | ||
72 | * Add "everybody else" into it. They aren't | ||
73 | * playing, because we own the spinlock. | ||
74 | */ | ||
75 | if (!atomic_add_negative(sleepers - 1, &sem->count)) { | ||
76 | sem->sleepers = 0; | ||
77 | break; | ||
78 | } | ||
79 | sem->sleepers = 1; /* us - see -1 above */ | ||
80 | spin_unlock_irq(&semaphore_lock); | ||
81 | |||
82 | schedule(); | ||
83 | tsk->state = TASK_UNINTERRUPTIBLE; | ||
84 | spin_lock_irq(&semaphore_lock); | ||
85 | } | ||
86 | spin_unlock_irq(&semaphore_lock); | ||
87 | remove_wait_queue(&sem->wait, &wait); | ||
88 | tsk->state = TASK_RUNNING; | ||
89 | wake_up(&sem->wait); | ||
90 | } | ||
91 | |||
92 | int __sched __down_interruptible(struct semaphore * sem) | ||
93 | { | ||
94 | int retval = 0; | ||
95 | struct task_struct *tsk = current; | ||
96 | DECLARE_WAITQUEUE(wait, tsk); | ||
97 | tsk->state = TASK_INTERRUPTIBLE; | ||
98 | add_wait_queue_exclusive(&sem->wait, &wait); | ||
99 | |||
100 | spin_lock_irq(&semaphore_lock); | ||
101 | sem->sleepers ++; | ||
102 | for (;;) { | ||
103 | int sleepers = sem->sleepers; | ||
104 | |||
105 | /* | ||
106 | * With signals pending, this turns into | ||
107 | * the trylock failure case - we won't be | ||
108 | * sleeping, and we* can't get the lock as | ||
109 | * it has contention. Just correct the count | ||
110 | * and exit. | ||
111 | */ | ||
112 | if (signal_pending(current)) { | ||
113 | retval = -EINTR; | ||
114 | sem->sleepers = 0; | ||
115 | atomic_add(sleepers, &sem->count); | ||
116 | break; | ||
117 | } | ||
118 | |||
119 | /* | ||
120 | * Add "everybody else" into it. They aren't | ||
121 | * playing, because we own the spinlock. The | ||
122 | * "-1" is because we're still hoping to get | ||
123 | * the lock. | ||
124 | */ | ||
125 | if (!atomic_add_negative(sleepers - 1, &sem->count)) { | ||
126 | sem->sleepers = 0; | ||
127 | break; | ||
128 | } | ||
129 | sem->sleepers = 1; /* us - see -1 above */ | ||
130 | spin_unlock_irq(&semaphore_lock); | ||
131 | |||
132 | schedule(); | ||
133 | tsk->state = TASK_INTERRUPTIBLE; | ||
134 | spin_lock_irq(&semaphore_lock); | ||
135 | } | ||
136 | spin_unlock_irq(&semaphore_lock); | ||
137 | tsk->state = TASK_RUNNING; | ||
138 | remove_wait_queue(&sem->wait, &wait); | ||
139 | wake_up(&sem->wait); | ||
140 | return retval; | ||
141 | } | ||
142 | |||
143 | /* | ||
144 | * Trylock failed - make sure we correct for | ||
145 | * having decremented the count. | ||
146 | * | ||
147 | * We could have done the trylock with a | ||
148 | * single "cmpxchg" without failure cases, | ||
149 | * but then it wouldn't work on a 386. | ||
150 | */ | ||
151 | int __down_trylock(struct semaphore * sem) | ||
152 | { | ||
153 | int sleepers; | ||
154 | unsigned long flags; | ||
155 | |||
156 | spin_lock_irqsave(&semaphore_lock, flags); | ||
157 | sleepers = sem->sleepers + 1; | ||
158 | sem->sleepers = 0; | ||
159 | |||
160 | /* | ||
161 | * Add "everybody else" and us into it. They aren't | ||
162 | * playing, because we own the spinlock. | ||
163 | */ | ||
164 | if (!atomic_add_negative(sleepers, &sem->count)) | ||
165 | wake_up(&sem->wait); | ||
166 | |||
167 | spin_unlock_irqrestore(&semaphore_lock, flags); | ||
168 | return 1; | ||
169 | } | ||
170 | |||
171 | /* | ||
172 | * The semaphore operations have a special calling sequence that | ||
173 | * allow us to do a simpler in-line version of them. These routines | ||
174 | * need to convert that sequence back into the C sequence when | ||
175 | * there is contention on the semaphore. | ||
176 | * | ||
177 | * ip contains the semaphore pointer on entry. Save the C-clobbered | ||
178 | * registers (r0 to r3 and lr), but not ip, as we use it as a return | ||
179 | * value in some cases.. | ||
180 | * To remain AAPCS compliant (64-bit stack align) we save r4 as well. | ||
181 | */ | ||
182 | asm(" .section .sched.text,\"ax\",%progbits \n\ | ||
183 | .align 5 \n\ | ||
184 | .globl __down_failed \n\ | ||
185 | __down_failed: \n\ | ||
186 | stmfd sp!, {r0 - r4, lr} \n\ | ||
187 | mov r0, ip \n\ | ||
188 | bl __down \n\ | ||
189 | ldmfd sp!, {r0 - r4, pc} \n\ | ||
190 | \n\ | ||
191 | .align 5 \n\ | ||
192 | .globl __down_interruptible_failed \n\ | ||
193 | __down_interruptible_failed: \n\ | ||
194 | stmfd sp!, {r0 - r4, lr} \n\ | ||
195 | mov r0, ip \n\ | ||
196 | bl __down_interruptible \n\ | ||
197 | mov ip, r0 \n\ | ||
198 | ldmfd sp!, {r0 - r4, pc} \n\ | ||
199 | \n\ | ||
200 | .align 5 \n\ | ||
201 | .globl __down_trylock_failed \n\ | ||
202 | __down_trylock_failed: \n\ | ||
203 | stmfd sp!, {r0 - r4, lr} \n\ | ||
204 | mov r0, ip \n\ | ||
205 | bl __down_trylock \n\ | ||
206 | mov ip, r0 \n\ | ||
207 | ldmfd sp!, {r0 - r4, pc} \n\ | ||
208 | \n\ | ||
209 | .align 5 \n\ | ||
210 | .globl __up_wakeup \n\ | ||
211 | __up_wakeup: \n\ | ||
212 | stmfd sp!, {r0 - r4, lr} \n\ | ||
213 | mov r0, ip \n\ | ||
214 | bl __up \n\ | ||
215 | ldmfd sp!, {r0 - r4, pc} \n\ | ||
216 | "); | ||
217 | |||
218 | EXPORT_SYMBOL(__down_failed); | ||
219 | EXPORT_SYMBOL(__down_interruptible_failed); | ||
220 | EXPORT_SYMBOL(__down_trylock_failed); | ||
221 | EXPORT_SYMBOL(__up_wakeup); | ||
diff --git a/arch/avr32/kernel/Makefile b/arch/avr32/kernel/Makefile index e4b6d122b033..18229d0d1861 100644 --- a/arch/avr32/kernel/Makefile +++ b/arch/avr32/kernel/Makefile | |||
@@ -6,7 +6,7 @@ extra-y := head.o vmlinux.lds | |||
6 | 6 | ||
7 | obj-$(CONFIG_SUBARCH_AVR32B) += entry-avr32b.o | 7 | obj-$(CONFIG_SUBARCH_AVR32B) += entry-avr32b.o |
8 | obj-y += syscall_table.o syscall-stubs.o irq.o | 8 | obj-y += syscall_table.o syscall-stubs.o irq.o |
9 | obj-y += setup.o traps.o semaphore.o ocd.o ptrace.o | 9 | obj-y += setup.o traps.o ocd.o ptrace.o |
10 | obj-y += signal.o sys_avr32.o process.o time.o | 10 | obj-y += signal.o sys_avr32.o process.o time.o |
11 | obj-y += init_task.o switch_to.o cpu.o | 11 | obj-y += init_task.o switch_to.o cpu.o |
12 | obj-$(CONFIG_MODULES) += module.o avr32_ksyms.o | 12 | obj-$(CONFIG_MODULES) += module.o avr32_ksyms.o |
diff --git a/arch/avr32/kernel/semaphore.c b/arch/avr32/kernel/semaphore.c deleted file mode 100644 index 1e2705a05016..000000000000 --- a/arch/avr32/kernel/semaphore.c +++ /dev/null | |||
@@ -1,148 +0,0 @@ | |||
1 | /* | ||
2 | * AVR32 sempahore implementation. | ||
3 | * | ||
4 | * Copyright (C) 2004-2006 Atmel Corporation | ||
5 | * | ||
6 | * Based on linux/arch/i386/kernel/semaphore.c | ||
7 | * Copyright (C) 1999 Linus Torvalds | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify | ||
10 | * it under the terms of the GNU General Public License version 2 as | ||
11 | * published by the Free Software Foundation. | ||
12 | */ | ||
13 | |||
14 | #include <linux/sched.h> | ||
15 | #include <linux/errno.h> | ||
16 | #include <linux/module.h> | ||
17 | |||
18 | #include <asm/semaphore.h> | ||
19 | #include <asm/atomic.h> | ||
20 | |||
21 | /* | ||
22 | * Semaphores are implemented using a two-way counter: | ||
23 | * The "count" variable is decremented for each process | ||
24 | * that tries to acquire the semaphore, while the "sleeping" | ||
25 | * variable is a count of such acquires. | ||
26 | * | ||
27 | * Notably, the inline "up()" and "down()" functions can | ||
28 | * efficiently test if they need to do any extra work (up | ||
29 | * needs to do something only if count was negative before | ||
30 | * the increment operation. | ||
31 | * | ||
32 | * "sleeping" and the contention routine ordering is protected | ||
33 | * by the spinlock in the semaphore's waitqueue head. | ||
34 | * | ||
35 | * Note that these functions are only called when there is | ||
36 | * contention on the lock, and as such all this is the | ||
37 | * "non-critical" part of the whole semaphore business. The | ||
38 | * critical part is the inline stuff in <asm/semaphore.h> | ||
39 | * where we want to avoid any extra jumps and calls. | ||
40 | */ | ||
41 | |||
42 | /* | ||
43 | * Logic: | ||
44 | * - only on a boundary condition do we need to care. When we go | ||
45 | * from a negative count to a non-negative, we wake people up. | ||
46 | * - when we go from a non-negative count to a negative do we | ||
47 | * (a) synchronize with the "sleeper" count and (b) make sure | ||
48 | * that we're on the wakeup list before we synchronize so that | ||
49 | * we cannot lose wakeup events. | ||
50 | */ | ||
51 | |||
52 | void __up(struct semaphore *sem) | ||
53 | { | ||
54 | wake_up(&sem->wait); | ||
55 | } | ||
56 | EXPORT_SYMBOL(__up); | ||
57 | |||
58 | void __sched __down(struct semaphore *sem) | ||
59 | { | ||
60 | struct task_struct *tsk = current; | ||
61 | DECLARE_WAITQUEUE(wait, tsk); | ||
62 | unsigned long flags; | ||
63 | |||
64 | tsk->state = TASK_UNINTERRUPTIBLE; | ||
65 | spin_lock_irqsave(&sem->wait.lock, flags); | ||
66 | add_wait_queue_exclusive_locked(&sem->wait, &wait); | ||
67 | |||
68 | sem->sleepers++; | ||
69 | for (;;) { | ||
70 | int sleepers = sem->sleepers; | ||
71 | |||
72 | /* | ||
73 | * Add "everybody else" into it. They aren't | ||
74 | * playing, because we own the spinlock in | ||
75 | * the wait_queue_head. | ||
76 | */ | ||
77 | if (atomic_add_return(sleepers - 1, &sem->count) >= 0) { | ||
78 | sem->sleepers = 0; | ||
79 | break; | ||
80 | } | ||
81 | sem->sleepers = 1; /* us - see -1 above */ | ||
82 | spin_unlock_irqrestore(&sem->wait.lock, flags); | ||
83 | |||
84 | schedule(); | ||
85 | |||
86 | spin_lock_irqsave(&sem->wait.lock, flags); | ||
87 | tsk->state = TASK_UNINTERRUPTIBLE; | ||
88 | } | ||
89 | remove_wait_queue_locked(&sem->wait, &wait); | ||
90 | wake_up_locked(&sem->wait); | ||
91 | spin_unlock_irqrestore(&sem->wait.lock, flags); | ||
92 | tsk->state = TASK_RUNNING; | ||
93 | } | ||
94 | EXPORT_SYMBOL(__down); | ||
95 | |||
96 | int __sched __down_interruptible(struct semaphore *sem) | ||
97 | { | ||
98 | int retval = 0; | ||
99 | struct task_struct *tsk = current; | ||
100 | DECLARE_WAITQUEUE(wait, tsk); | ||
101 | unsigned long flags; | ||
102 | |||
103 | tsk->state = TASK_INTERRUPTIBLE; | ||
104 | spin_lock_irqsave(&sem->wait.lock, flags); | ||
105 | add_wait_queue_exclusive_locked(&sem->wait, &wait); | ||
106 | |||
107 | sem->sleepers++; | ||
108 | for (;;) { | ||
109 | int sleepers = sem->sleepers; | ||
110 | |||
111 | /* | ||
112 | * With signals pending, this turns into the trylock | ||
113 | * failure case - we won't be sleeping, and we can't | ||
114 | * get the lock as it has contention. Just correct the | ||
115 | * count and exit. | ||
116 | */ | ||
117 | if (signal_pending(current)) { | ||
118 | retval = -EINTR; | ||
119 | sem->sleepers = 0; | ||
120 | atomic_add(sleepers, &sem->count); | ||
121 | break; | ||
122 | } | ||
123 | |||
124 | /* | ||
125 | * Add "everybody else" into it. They aren't | ||
126 | * playing, because we own the spinlock in | ||
127 | * the wait_queue_head. | ||
128 | */ | ||
129 | if (atomic_add_return(sleepers - 1, &sem->count) >= 0) { | ||
130 | sem->sleepers = 0; | ||
131 | break; | ||
132 | } | ||
133 | sem->sleepers = 1; /* us - see -1 above */ | ||
134 | spin_unlock_irqrestore(&sem->wait.lock, flags); | ||
135 | |||
136 | schedule(); | ||
137 | |||
138 | spin_lock_irqsave(&sem->wait.lock, flags); | ||
139 | tsk->state = TASK_INTERRUPTIBLE; | ||
140 | } | ||
141 | remove_wait_queue_locked(&sem->wait, &wait); | ||
142 | wake_up_locked(&sem->wait); | ||
143 | spin_unlock_irqrestore(&sem->wait.lock, flags); | ||
144 | |||
145 | tsk->state = TASK_RUNNING; | ||
146 | return retval; | ||
147 | } | ||
148 | EXPORT_SYMBOL(__down_interruptible); | ||
diff --git a/arch/blackfin/Kconfig b/arch/blackfin/Kconfig index 589c6aca4803..2dd1f300a5cf 100644 --- a/arch/blackfin/Kconfig +++ b/arch/blackfin/Kconfig | |||
@@ -31,10 +31,6 @@ config ZONE_DMA | |||
31 | bool | 31 | bool |
32 | default y | 32 | default y |
33 | 33 | ||
34 | config SEMAPHORE_SLEEPERS | ||
35 | bool | ||
36 | default y | ||
37 | |||
38 | config GENERIC_FIND_NEXT_BIT | 34 | config GENERIC_FIND_NEXT_BIT |
39 | bool | 35 | bool |
40 | default y | 36 | default y |
diff --git a/arch/blackfin/kernel/bfin_ksyms.c b/arch/blackfin/kernel/bfin_ksyms.c index 0bfbb269e350..053edff6c0d8 100644 --- a/arch/blackfin/kernel/bfin_ksyms.c +++ b/arch/blackfin/kernel/bfin_ksyms.c | |||
@@ -42,11 +42,6 @@ EXPORT_SYMBOL(ip_fast_csum); | |||
42 | 42 | ||
43 | EXPORT_SYMBOL(kernel_thread); | 43 | EXPORT_SYMBOL(kernel_thread); |
44 | 44 | ||
45 | EXPORT_SYMBOL(__up); | ||
46 | EXPORT_SYMBOL(__down); | ||
47 | EXPORT_SYMBOL(__down_trylock); | ||
48 | EXPORT_SYMBOL(__down_interruptible); | ||
49 | |||
50 | EXPORT_SYMBOL(is_in_rom); | 45 | EXPORT_SYMBOL(is_in_rom); |
51 | EXPORT_SYMBOL(bfin_return_from_exception); | 46 | EXPORT_SYMBOL(bfin_return_from_exception); |
52 | 47 | ||
diff --git a/arch/cris/kernel/Makefile b/arch/cris/kernel/Makefile index c8e8ea570989..ee7bcd4d20b2 100644 --- a/arch/cris/kernel/Makefile +++ b/arch/cris/kernel/Makefile | |||
@@ -5,8 +5,7 @@ | |||
5 | 5 | ||
6 | extra-y := vmlinux.lds | 6 | extra-y := vmlinux.lds |
7 | 7 | ||
8 | obj-y := process.o traps.o irq.o ptrace.o setup.o \ | 8 | obj-y := process.o traps.o irq.o ptrace.o setup.o time.o sys_cris.o |
9 | time.o sys_cris.o semaphore.o | ||
10 | 9 | ||
11 | obj-$(CONFIG_MODULES) += crisksyms.o | 10 | obj-$(CONFIG_MODULES) += crisksyms.o |
12 | obj-$(CONFIG_MODULES) += module.o | 11 | obj-$(CONFIG_MODULES) += module.o |
diff --git a/arch/cris/kernel/crisksyms.c b/arch/cris/kernel/crisksyms.c index 62f0e752915a..7ac000f6a888 100644 --- a/arch/cris/kernel/crisksyms.c +++ b/arch/cris/kernel/crisksyms.c | |||
@@ -9,7 +9,6 @@ | |||
9 | #include <linux/string.h> | 9 | #include <linux/string.h> |
10 | #include <linux/tty.h> | 10 | #include <linux/tty.h> |
11 | 11 | ||
12 | #include <asm/semaphore.h> | ||
13 | #include <asm/processor.h> | 12 | #include <asm/processor.h> |
14 | #include <asm/uaccess.h> | 13 | #include <asm/uaccess.h> |
15 | #include <asm/checksum.h> | 14 | #include <asm/checksum.h> |
@@ -49,12 +48,6 @@ EXPORT_SYMBOL(__negdi2); | |||
49 | EXPORT_SYMBOL(__ioremap); | 48 | EXPORT_SYMBOL(__ioremap); |
50 | EXPORT_SYMBOL(iounmap); | 49 | EXPORT_SYMBOL(iounmap); |
51 | 50 | ||
52 | /* Semaphore functions */ | ||
53 | EXPORT_SYMBOL(__up); | ||
54 | EXPORT_SYMBOL(__down); | ||
55 | EXPORT_SYMBOL(__down_interruptible); | ||
56 | EXPORT_SYMBOL(__down_trylock); | ||
57 | |||
58 | /* Userspace access functions */ | 51 | /* Userspace access functions */ |
59 | EXPORT_SYMBOL(__copy_user_zeroing); | 52 | EXPORT_SYMBOL(__copy_user_zeroing); |
60 | EXPORT_SYMBOL(__copy_user); | 53 | EXPORT_SYMBOL(__copy_user); |
diff --git a/arch/cris/kernel/semaphore.c b/arch/cris/kernel/semaphore.c deleted file mode 100644 index f137a439041f..000000000000 --- a/arch/cris/kernel/semaphore.c +++ /dev/null | |||
@@ -1,129 +0,0 @@ | |||
1 | /* | ||
2 | * Generic semaphore code. Buyer beware. Do your own | ||
3 | * specific changes in <asm/semaphore-helper.h> | ||
4 | */ | ||
5 | |||
6 | #include <linux/sched.h> | ||
7 | #include <asm/semaphore-helper.h> | ||
8 | |||
9 | /* | ||
10 | * Semaphores are implemented using a two-way counter: | ||
11 | * The "count" variable is decremented for each process | ||
12 | * that tries to sleep, while the "waking" variable is | ||
13 | * incremented when the "up()" code goes to wake up waiting | ||
14 | * processes. | ||
15 | * | ||
16 | * Notably, the inline "up()" and "down()" functions can | ||
17 | * efficiently test if they need to do any extra work (up | ||
18 | * needs to do something only if count was negative before | ||
19 | * the increment operation. | ||
20 | * | ||
21 | * waking_non_zero() (from asm/semaphore.h) must execute | ||
22 | * atomically. | ||
23 | * | ||
24 | * When __up() is called, the count was negative before | ||
25 | * incrementing it, and we need to wake up somebody. | ||
26 | * | ||
27 | * This routine adds one to the count of processes that need to | ||
28 | * wake up and exit. ALL waiting processes actually wake up but | ||
29 | * only the one that gets to the "waking" field first will gate | ||
30 | * through and acquire the semaphore. The others will go back | ||
31 | * to sleep. | ||
32 | * | ||
33 | * Note that these functions are only called when there is | ||
34 | * contention on the lock, and as such all this is the | ||
35 | * "non-critical" part of the whole semaphore business. The | ||
36 | * critical part is the inline stuff in <asm/semaphore.h> | ||
37 | * where we want to avoid any extra jumps and calls. | ||
38 | */ | ||
39 | void __up(struct semaphore *sem) | ||
40 | { | ||
41 | wake_one_more(sem); | ||
42 | wake_up(&sem->wait); | ||
43 | } | ||
44 | |||
45 | /* | ||
46 | * Perform the "down" function. Return zero for semaphore acquired, | ||
47 | * return negative for signalled out of the function. | ||
48 | * | ||
49 | * If called from __down, the return is ignored and the wait loop is | ||
50 | * not interruptible. This means that a task waiting on a semaphore | ||
51 | * using "down()" cannot be killed until someone does an "up()" on | ||
52 | * the semaphore. | ||
53 | * | ||
54 | * If called from __down_interruptible, the return value gets checked | ||
55 | * upon return. If the return value is negative then the task continues | ||
56 | * with the negative value in the return register (it can be tested by | ||
57 | * the caller). | ||
58 | * | ||
59 | * Either form may be used in conjunction with "up()". | ||
60 | * | ||
61 | */ | ||
62 | |||
63 | #define DOWN_VAR \ | ||
64 | struct task_struct *tsk = current; \ | ||
65 | wait_queue_t wait; \ | ||
66 | init_waitqueue_entry(&wait, tsk); | ||
67 | |||
68 | #define DOWN_HEAD(task_state) \ | ||
69 | \ | ||
70 | \ | ||
71 | tsk->state = (task_state); \ | ||
72 | add_wait_queue(&sem->wait, &wait); \ | ||
73 | \ | ||
74 | /* \ | ||
75 | * Ok, we're set up. sem->count is known to be less than zero \ | ||
76 | * so we must wait. \ | ||
77 | * \ | ||
78 | * We can let go the lock for purposes of waiting. \ | ||
79 | * We re-acquire it after awaking so as to protect \ | ||
80 | * all semaphore operations. \ | ||
81 | * \ | ||
82 | * If "up()" is called before we call waking_non_zero() then \ | ||
83 | * we will catch it right away. If it is called later then \ | ||
84 | * we will have to go through a wakeup cycle to catch it. \ | ||
85 | * \ | ||
86 | * Multiple waiters contend for the semaphore lock to see \ | ||
87 | * who gets to gate through and who has to wait some more. \ | ||
88 | */ \ | ||
89 | for (;;) { | ||
90 | |||
91 | #define DOWN_TAIL(task_state) \ | ||
92 | tsk->state = (task_state); \ | ||
93 | } \ | ||
94 | tsk->state = TASK_RUNNING; \ | ||
95 | remove_wait_queue(&sem->wait, &wait); | ||
96 | |||
97 | void __sched __down(struct semaphore * sem) | ||
98 | { | ||
99 | DOWN_VAR | ||
100 | DOWN_HEAD(TASK_UNINTERRUPTIBLE) | ||
101 | if (waking_non_zero(sem)) | ||
102 | break; | ||
103 | schedule(); | ||
104 | DOWN_TAIL(TASK_UNINTERRUPTIBLE) | ||
105 | } | ||
106 | |||
107 | int __sched __down_interruptible(struct semaphore * sem) | ||
108 | { | ||
109 | int ret = 0; | ||
110 | DOWN_VAR | ||
111 | DOWN_HEAD(TASK_INTERRUPTIBLE) | ||
112 | |||
113 | ret = waking_non_zero_interruptible(sem, tsk); | ||
114 | if (ret) | ||
115 | { | ||
116 | if (ret == 1) | ||
117 | /* ret != 0 only if we get interrupted -arca */ | ||
118 | ret = 0; | ||
119 | break; | ||
120 | } | ||
121 | schedule(); | ||
122 | DOWN_TAIL(TASK_INTERRUPTIBLE) | ||
123 | return ret; | ||
124 | } | ||
125 | |||
126 | int __down_trylock(struct semaphore * sem) | ||
127 | { | ||
128 | return waking_non_zero_trylock(sem); | ||
129 | } | ||
diff --git a/arch/frv/kernel/Makefile b/arch/frv/kernel/Makefile index e8f73ed28b52..c36f70b6699a 100644 --- a/arch/frv/kernel/Makefile +++ b/arch/frv/kernel/Makefile | |||
@@ -9,7 +9,7 @@ extra-y:= head.o init_task.o vmlinux.lds | |||
9 | 9 | ||
10 | obj-y := $(heads-y) entry.o entry-table.o break.o switch_to.o kernel_thread.o \ | 10 | obj-y := $(heads-y) entry.o entry-table.o break.o switch_to.o kernel_thread.o \ |
11 | kernel_execve.o process.o traps.o ptrace.o signal.o dma.o \ | 11 | kernel_execve.o process.o traps.o ptrace.o signal.o dma.o \ |
12 | sys_frv.o time.o semaphore.o setup.o frv_ksyms.o \ | 12 | sys_frv.o time.o setup.o frv_ksyms.o \ |
13 | debug-stub.o irq.o sleep.o uaccess.o | 13 | debug-stub.o irq.o sleep.o uaccess.o |
14 | 14 | ||
15 | obj-$(CONFIG_GDBSTUB) += gdb-stub.o gdb-io.o | 15 | obj-$(CONFIG_GDBSTUB) += gdb-stub.o gdb-io.o |
diff --git a/arch/frv/kernel/frv_ksyms.c b/arch/frv/kernel/frv_ksyms.c index f772704b3d28..0316b3c50eff 100644 --- a/arch/frv/kernel/frv_ksyms.c +++ b/arch/frv/kernel/frv_ksyms.c | |||
@@ -12,7 +12,6 @@ | |||
12 | #include <asm/pgalloc.h> | 12 | #include <asm/pgalloc.h> |
13 | #include <asm/irq.h> | 13 | #include <asm/irq.h> |
14 | #include <asm/io.h> | 14 | #include <asm/io.h> |
15 | #include <asm/semaphore.h> | ||
16 | #include <asm/checksum.h> | 15 | #include <asm/checksum.h> |
17 | #include <asm/hardirq.h> | 16 | #include <asm/hardirq.h> |
18 | #include <asm/cacheflush.h> | 17 | #include <asm/cacheflush.h> |
diff --git a/arch/frv/kernel/semaphore.c b/arch/frv/kernel/semaphore.c deleted file mode 100644 index 7ee3a147b471..000000000000 --- a/arch/frv/kernel/semaphore.c +++ /dev/null | |||
@@ -1,155 +0,0 @@ | |||
1 | /* semaphore.c: FR-V semaphores | ||
2 | * | ||
3 | * Copyright (C) 2003 Red Hat, Inc. All Rights Reserved. | ||
4 | * Written by David Howells (dhowells@redhat.com) | ||
5 | * - Derived from lib/rwsem-spinlock.c | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or | ||
8 | * modify it under the terms of the GNU General Public License | ||
9 | * as published by the Free Software Foundation; either version | ||
10 | * 2 of the License, or (at your option) any later version. | ||
11 | */ | ||
12 | |||
13 | #include <linux/sched.h> | ||
14 | #include <linux/module.h> | ||
15 | #include <asm/semaphore.h> | ||
16 | |||
17 | struct sem_waiter { | ||
18 | struct list_head list; | ||
19 | struct task_struct *task; | ||
20 | }; | ||
21 | |||
22 | #ifdef CONFIG_DEBUG_SEMAPHORE | ||
23 | void semtrace(struct semaphore *sem, const char *str) | ||
24 | { | ||
25 | if (sem->debug) | ||
26 | printk("[%d] %s({%d,%d})\n", | ||
27 | current->pid, | ||
28 | str, | ||
29 | sem->counter, | ||
30 | list_empty(&sem->wait_list) ? 0 : 1); | ||
31 | } | ||
32 | #else | ||
33 | #define semtrace(SEM,STR) do { } while(0) | ||
34 | #endif | ||
35 | |||
36 | /* | ||
37 | * wait for a token to be granted from a semaphore | ||
38 | * - entered with lock held and interrupts disabled | ||
39 | */ | ||
40 | void __down(struct semaphore *sem, unsigned long flags) | ||
41 | { | ||
42 | struct task_struct *tsk = current; | ||
43 | struct sem_waiter waiter; | ||
44 | |||
45 | semtrace(sem, "Entering __down"); | ||
46 | |||
47 | /* set up my own style of waitqueue */ | ||
48 | waiter.task = tsk; | ||
49 | get_task_struct(tsk); | ||
50 | |||
51 | list_add_tail(&waiter.list, &sem->wait_list); | ||
52 | |||
53 | /* we don't need to touch the semaphore struct anymore */ | ||
54 | spin_unlock_irqrestore(&sem->wait_lock, flags); | ||
55 | |||
56 | /* wait to be given the semaphore */ | ||
57 | set_task_state(tsk, TASK_UNINTERRUPTIBLE); | ||
58 | |||
59 | for (;;) { | ||
60 | if (list_empty(&waiter.list)) | ||
61 | break; | ||
62 | schedule(); | ||
63 | set_task_state(tsk, TASK_UNINTERRUPTIBLE); | ||
64 | } | ||
65 | |||
66 | tsk->state = TASK_RUNNING; | ||
67 | semtrace(sem, "Leaving __down"); | ||
68 | } | ||
69 | |||
70 | EXPORT_SYMBOL(__down); | ||
71 | |||
72 | /* | ||
73 | * interruptibly wait for a token to be granted from a semaphore | ||
74 | * - entered with lock held and interrupts disabled | ||
75 | */ | ||
76 | int __down_interruptible(struct semaphore *sem, unsigned long flags) | ||
77 | { | ||
78 | struct task_struct *tsk = current; | ||
79 | struct sem_waiter waiter; | ||
80 | int ret; | ||
81 | |||
82 | semtrace(sem,"Entering __down_interruptible"); | ||
83 | |||
84 | /* set up my own style of waitqueue */ | ||
85 | waiter.task = tsk; | ||
86 | get_task_struct(tsk); | ||
87 | |||
88 | list_add_tail(&waiter.list, &sem->wait_list); | ||
89 | |||
90 | /* we don't need to touch the semaphore struct anymore */ | ||
91 | set_task_state(tsk, TASK_INTERRUPTIBLE); | ||
92 | |||
93 | spin_unlock_irqrestore(&sem->wait_lock, flags); | ||
94 | |||
95 | /* wait to be given the semaphore */ | ||
96 | ret = 0; | ||
97 | for (;;) { | ||
98 | if (list_empty(&waiter.list)) | ||
99 | break; | ||
100 | if (unlikely(signal_pending(current))) | ||
101 | goto interrupted; | ||
102 | schedule(); | ||
103 | set_task_state(tsk, TASK_INTERRUPTIBLE); | ||
104 | } | ||
105 | |||
106 | out: | ||
107 | tsk->state = TASK_RUNNING; | ||
108 | semtrace(sem, "Leaving __down_interruptible"); | ||
109 | return ret; | ||
110 | |||
111 | interrupted: | ||
112 | spin_lock_irqsave(&sem->wait_lock, flags); | ||
113 | |||
114 | if (!list_empty(&waiter.list)) { | ||
115 | list_del(&waiter.list); | ||
116 | ret = -EINTR; | ||
117 | } | ||
118 | |||
119 | spin_unlock_irqrestore(&sem->wait_lock, flags); | ||
120 | if (ret == -EINTR) | ||
121 | put_task_struct(current); | ||
122 | goto out; | ||
123 | } | ||
124 | |||
125 | EXPORT_SYMBOL(__down_interruptible); | ||
126 | |||
127 | /* | ||
128 | * release a single token back to a semaphore | ||
129 | * - entered with lock held and interrupts disabled | ||
130 | */ | ||
131 | void __up(struct semaphore *sem) | ||
132 | { | ||
133 | struct task_struct *tsk; | ||
134 | struct sem_waiter *waiter; | ||
135 | |||
136 | semtrace(sem,"Entering __up"); | ||
137 | |||
138 | /* grant the token to the process at the front of the queue */ | ||
139 | waiter = list_entry(sem->wait_list.next, struct sem_waiter, list); | ||
140 | |||
141 | /* We must be careful not to touch 'waiter' after we set ->task = NULL. | ||
142 | * It is allocated on the waiter's stack and may become invalid at | ||
143 | * any time after that point (due to a wakeup from another source). | ||
144 | */ | ||
145 | list_del_init(&waiter->list); | ||
146 | tsk = waiter->task; | ||
147 | mb(); | ||
148 | waiter->task = NULL; | ||
149 | wake_up_process(tsk); | ||
150 | put_task_struct(tsk); | ||
151 | |||
152 | semtrace(sem,"Leaving __up"); | ||
153 | } | ||
154 | |||
155 | EXPORT_SYMBOL(__up); | ||
diff --git a/arch/h8300/kernel/Makefile b/arch/h8300/kernel/Makefile index 874f6aefee65..6c248c3c5c3b 100644 --- a/arch/h8300/kernel/Makefile +++ b/arch/h8300/kernel/Makefile | |||
@@ -5,7 +5,7 @@ | |||
5 | extra-y := vmlinux.lds | 5 | extra-y := vmlinux.lds |
6 | 6 | ||
7 | obj-y := process.o traps.o ptrace.o irq.o \ | 7 | obj-y := process.o traps.o ptrace.o irq.o \ |
8 | sys_h8300.o time.o semaphore.o signal.o \ | 8 | sys_h8300.o time.o signal.o \ |
9 | setup.o gpio.o init_task.o syscalls.o \ | 9 | setup.o gpio.o init_task.o syscalls.o \ |
10 | entry.o | 10 | entry.o |
11 | 11 | ||
diff --git a/arch/h8300/kernel/h8300_ksyms.c b/arch/h8300/kernel/h8300_ksyms.c index d1b15267ac81..6866bd9c7fb4 100644 --- a/arch/h8300/kernel/h8300_ksyms.c +++ b/arch/h8300/kernel/h8300_ksyms.c | |||
@@ -12,7 +12,6 @@ | |||
12 | #include <asm/pgalloc.h> | 12 | #include <asm/pgalloc.h> |
13 | #include <asm/irq.h> | 13 | #include <asm/irq.h> |
14 | #include <asm/io.h> | 14 | #include <asm/io.h> |
15 | #include <asm/semaphore.h> | ||
16 | #include <asm/checksum.h> | 15 | #include <asm/checksum.h> |
17 | #include <asm/current.h> | 16 | #include <asm/current.h> |
18 | #include <asm/gpio.h> | 17 | #include <asm/gpio.h> |
diff --git a/arch/h8300/kernel/semaphore.c b/arch/h8300/kernel/semaphore.c deleted file mode 100644 index d12cbbfe6ebd..000000000000 --- a/arch/h8300/kernel/semaphore.c +++ /dev/null | |||
@@ -1,132 +0,0 @@ | |||
1 | /* | ||
2 | * Generic semaphore code. Buyer beware. Do your own | ||
3 | * specific changes in <asm/semaphore-helper.h> | ||
4 | */ | ||
5 | |||
6 | #include <linux/sched.h> | ||
7 | #include <linux/init.h> | ||
8 | #include <asm/semaphore-helper.h> | ||
9 | |||
10 | #ifndef CONFIG_RMW_INSNS | ||
11 | spinlock_t semaphore_wake_lock; | ||
12 | #endif | ||
13 | |||
14 | /* | ||
15 | * Semaphores are implemented using a two-way counter: | ||
16 | * The "count" variable is decremented for each process | ||
17 | * that tries to sleep, while the "waking" variable is | ||
18 | * incremented when the "up()" code goes to wake up waiting | ||
19 | * processes. | ||
20 | * | ||
21 | * Notably, the inline "up()" and "down()" functions can | ||
22 | * efficiently test if they need to do any extra work (up | ||
23 | * needs to do something only if count was negative before | ||
24 | * the increment operation. | ||
25 | * | ||
26 | * waking_non_zero() (from asm/semaphore.h) must execute | ||
27 | * atomically. | ||
28 | * | ||
29 | * When __up() is called, the count was negative before | ||
30 | * incrementing it, and we need to wake up somebody. | ||
31 | * | ||
32 | * This routine adds one to the count of processes that need to | ||
33 | * wake up and exit. ALL waiting processes actually wake up but | ||
34 | * only the one that gets to the "waking" field first will gate | ||
35 | * through and acquire the semaphore. The others will go back | ||
36 | * to sleep. | ||
37 | * | ||
38 | * Note that these functions are only called when there is | ||
39 | * contention on the lock, and as such all this is the | ||
40 | * "non-critical" part of the whole semaphore business. The | ||
41 | * critical part is the inline stuff in <asm/semaphore.h> | ||
42 | * where we want to avoid any extra jumps and calls. | ||
43 | */ | ||
44 | void __up(struct semaphore *sem) | ||
45 | { | ||
46 | wake_one_more(sem); | ||
47 | wake_up(&sem->wait); | ||
48 | } | ||
49 | |||
50 | /* | ||
51 | * Perform the "down" function. Return zero for semaphore acquired, | ||
52 | * return negative for signalled out of the function. | ||
53 | * | ||
54 | * If called from __down, the return is ignored and the wait loop is | ||
55 | * not interruptible. This means that a task waiting on a semaphore | ||
56 | * using "down()" cannot be killed until someone does an "up()" on | ||
57 | * the semaphore. | ||
58 | * | ||
59 | * If called from __down_interruptible, the return value gets checked | ||
60 | * upon return. If the return value is negative then the task continues | ||
61 | * with the negative value in the return register (it can be tested by | ||
62 | * the caller). | ||
63 | * | ||
64 | * Either form may be used in conjunction with "up()". | ||
65 | * | ||
66 | */ | ||
67 | |||
68 | |||
69 | #define DOWN_HEAD(task_state) \ | ||
70 | \ | ||
71 | \ | ||
72 | current->state = (task_state); \ | ||
73 | add_wait_queue(&sem->wait, &wait); \ | ||
74 | \ | ||
75 | /* \ | ||
76 | * Ok, we're set up. sem->count is known to be less than zero \ | ||
77 | * so we must wait. \ | ||
78 | * \ | ||
79 | * We can let go the lock for purposes of waiting. \ | ||
80 | * We re-acquire it after awaking so as to protect \ | ||
81 | * all semaphore operations. \ | ||
82 | * \ | ||
83 | * If "up()" is called before we call waking_non_zero() then \ | ||
84 | * we will catch it right away. If it is called later then \ | ||
85 | * we will have to go through a wakeup cycle to catch it. \ | ||
86 | * \ | ||
87 | * Multiple waiters contend for the semaphore lock to see \ | ||
88 | * who gets to gate through and who has to wait some more. \ | ||
89 | */ \ | ||
90 | for (;;) { | ||
91 | |||
92 | #define DOWN_TAIL(task_state) \ | ||
93 | current->state = (task_state); \ | ||
94 | } \ | ||
95 | current->state = TASK_RUNNING; \ | ||
96 | remove_wait_queue(&sem->wait, &wait); | ||
97 | |||
98 | void __sched __down(struct semaphore * sem) | ||
99 | { | ||
100 | DECLARE_WAITQUEUE(wait, current); | ||
101 | |||
102 | DOWN_HEAD(TASK_UNINTERRUPTIBLE) | ||
103 | if (waking_non_zero(sem)) | ||
104 | break; | ||
105 | schedule(); | ||
106 | DOWN_TAIL(TASK_UNINTERRUPTIBLE) | ||
107 | } | ||
108 | |||
109 | int __sched __down_interruptible(struct semaphore * sem) | ||
110 | { | ||
111 | DECLARE_WAITQUEUE(wait, current); | ||
112 | int ret = 0; | ||
113 | |||
114 | DOWN_HEAD(TASK_INTERRUPTIBLE) | ||
115 | |||
116 | ret = waking_non_zero_interruptible(sem, current); | ||
117 | if (ret) | ||
118 | { | ||
119 | if (ret == 1) | ||
120 | /* ret != 0 only if we get interrupted -arca */ | ||
121 | ret = 0; | ||
122 | break; | ||
123 | } | ||
124 | schedule(); | ||
125 | DOWN_TAIL(TASK_INTERRUPTIBLE) | ||
126 | return ret; | ||
127 | } | ||
128 | |||
129 | int __down_trylock(struct semaphore * sem) | ||
130 | { | ||
131 | return waking_non_zero_trylock(sem); | ||
132 | } | ||
diff --git a/arch/ia64/kernel/Makefile b/arch/ia64/kernel/Makefile index 33e5a598672d..13fd10e8699e 100644 --- a/arch/ia64/kernel/Makefile +++ b/arch/ia64/kernel/Makefile | |||
@@ -6,7 +6,7 @@ extra-y := head.o init_task.o vmlinux.lds | |||
6 | 6 | ||
7 | obj-y := acpi.o entry.o efi.o efi_stub.o gate-data.o fsys.o ia64_ksyms.o irq.o irq_ia64.o \ | 7 | obj-y := acpi.o entry.o efi.o efi_stub.o gate-data.o fsys.o ia64_ksyms.o irq.o irq_ia64.o \ |
8 | irq_lsapic.o ivt.o machvec.o pal.o patch.o process.o perfmon.o ptrace.o sal.o \ | 8 | irq_lsapic.o ivt.o machvec.o pal.o patch.o process.o perfmon.o ptrace.o sal.o \ |
9 | salinfo.o semaphore.o setup.o signal.o sys_ia64.o time.o traps.o unaligned.o \ | 9 | salinfo.o setup.o signal.o sys_ia64.o time.o traps.o unaligned.o \ |
10 | unwind.o mca.o mca_asm.o topology.o | 10 | unwind.o mca.o mca_asm.o topology.o |
11 | 11 | ||
12 | obj-$(CONFIG_IA64_BRL_EMU) += brl_emu.o | 12 | obj-$(CONFIG_IA64_BRL_EMU) += brl_emu.o |
diff --git a/arch/ia64/kernel/ia64_ksyms.c b/arch/ia64/kernel/ia64_ksyms.c index 8e7193d55528..6da1f20d7372 100644 --- a/arch/ia64/kernel/ia64_ksyms.c +++ b/arch/ia64/kernel/ia64_ksyms.c | |||
@@ -19,12 +19,6 @@ EXPORT_SYMBOL_GPL(empty_zero_page); | |||
19 | EXPORT_SYMBOL(ip_fast_csum); /* hand-coded assembly */ | 19 | EXPORT_SYMBOL(ip_fast_csum); /* hand-coded assembly */ |
20 | EXPORT_SYMBOL(csum_ipv6_magic); | 20 | EXPORT_SYMBOL(csum_ipv6_magic); |
21 | 21 | ||
22 | #include <asm/semaphore.h> | ||
23 | EXPORT_SYMBOL(__down); | ||
24 | EXPORT_SYMBOL(__down_interruptible); | ||
25 | EXPORT_SYMBOL(__down_trylock); | ||
26 | EXPORT_SYMBOL(__up); | ||
27 | |||
28 | #include <asm/page.h> | 22 | #include <asm/page.h> |
29 | EXPORT_SYMBOL(clear_page); | 23 | EXPORT_SYMBOL(clear_page); |
30 | 24 | ||
diff --git a/arch/ia64/kernel/semaphore.c b/arch/ia64/kernel/semaphore.c deleted file mode 100644 index 2724ef3fbae2..000000000000 --- a/arch/ia64/kernel/semaphore.c +++ /dev/null | |||
@@ -1,165 +0,0 @@ | |||
1 | /* | ||
2 | * IA-64 semaphore implementation (derived from x86 version). | ||
3 | * | ||
4 | * Copyright (C) 1999-2000, 2002 Hewlett-Packard Co | ||
5 | * David Mosberger-Tang <davidm@hpl.hp.com> | ||
6 | */ | ||
7 | |||
8 | /* | ||
9 | * Semaphores are implemented using a two-way counter: The "count" | ||
10 | * variable is decremented for each process that tries to acquire the | ||
11 | * semaphore, while the "sleepers" variable is a count of such | ||
12 | * acquires. | ||
13 | * | ||
14 | * Notably, the inline "up()" and "down()" functions can efficiently | ||
15 | * test if they need to do any extra work (up needs to do something | ||
16 | * only if count was negative before the increment operation. | ||
17 | * | ||
18 | * "sleeping" and the contention routine ordering is protected | ||
19 | * by the spinlock in the semaphore's waitqueue head. | ||
20 | * | ||
21 | * Note that these functions are only called when there is contention | ||
22 | * on the lock, and as such all this is the "non-critical" part of the | ||
23 | * whole semaphore business. The critical part is the inline stuff in | ||
24 | * <asm/semaphore.h> where we want to avoid any extra jumps and calls. | ||
25 | */ | ||
26 | #include <linux/sched.h> | ||
27 | #include <linux/init.h> | ||
28 | |||
29 | #include <asm/errno.h> | ||
30 | #include <asm/semaphore.h> | ||
31 | |||
32 | /* | ||
33 | * Logic: | ||
34 | * - Only on a boundary condition do we need to care. When we go | ||
35 | * from a negative count to a non-negative, we wake people up. | ||
36 | * - When we go from a non-negative count to a negative do we | ||
37 | * (a) synchronize with the "sleepers" count and (b) make sure | ||
38 | * that we're on the wakeup list before we synchronize so that | ||
39 | * we cannot lose wakeup events. | ||
40 | */ | ||
41 | |||
42 | void | ||
43 | __up (struct semaphore *sem) | ||
44 | { | ||
45 | wake_up(&sem->wait); | ||
46 | } | ||
47 | |||
48 | void __sched __down (struct semaphore *sem) | ||
49 | { | ||
50 | struct task_struct *tsk = current; | ||
51 | DECLARE_WAITQUEUE(wait, tsk); | ||
52 | unsigned long flags; | ||
53 | |||
54 | tsk->state = TASK_UNINTERRUPTIBLE; | ||
55 | spin_lock_irqsave(&sem->wait.lock, flags); | ||
56 | add_wait_queue_exclusive_locked(&sem->wait, &wait); | ||
57 | |||
58 | sem->sleepers++; | ||
59 | for (;;) { | ||
60 | int sleepers = sem->sleepers; | ||
61 | |||
62 | /* | ||
63 | * Add "everybody else" into it. They aren't | ||
64 | * playing, because we own the spinlock in | ||
65 | * the wait_queue_head. | ||
66 | */ | ||
67 | if (!atomic_add_negative(sleepers - 1, &sem->count)) { | ||
68 | sem->sleepers = 0; | ||
69 | break; | ||
70 | } | ||
71 | sem->sleepers = 1; /* us - see -1 above */ | ||
72 | spin_unlock_irqrestore(&sem->wait.lock, flags); | ||
73 | |||
74 | schedule(); | ||
75 | |||
76 | spin_lock_irqsave(&sem->wait.lock, flags); | ||
77 | tsk->state = TASK_UNINTERRUPTIBLE; | ||
78 | } | ||
79 | remove_wait_queue_locked(&sem->wait, &wait); | ||
80 | wake_up_locked(&sem->wait); | ||
81 | spin_unlock_irqrestore(&sem->wait.lock, flags); | ||
82 | tsk->state = TASK_RUNNING; | ||
83 | } | ||
84 | |||
85 | int __sched __down_interruptible (struct semaphore * sem) | ||
86 | { | ||
87 | int retval = 0; | ||
88 | struct task_struct *tsk = current; | ||
89 | DECLARE_WAITQUEUE(wait, tsk); | ||
90 | unsigned long flags; | ||
91 | |||
92 | tsk->state = TASK_INTERRUPTIBLE; | ||
93 | spin_lock_irqsave(&sem->wait.lock, flags); | ||
94 | add_wait_queue_exclusive_locked(&sem->wait, &wait); | ||
95 | |||
96 | sem->sleepers ++; | ||
97 | for (;;) { | ||
98 | int sleepers = sem->sleepers; | ||
99 | |||
100 | /* | ||
101 | * With signals pending, this turns into | ||
102 | * the trylock failure case - we won't be | ||
103 | * sleeping, and we* can't get the lock as | ||
104 | * it has contention. Just correct the count | ||
105 | * and exit. | ||
106 | */ | ||
107 | if (signal_pending(current)) { | ||
108 | retval = -EINTR; | ||
109 | sem->sleepers = 0; | ||
110 | atomic_add(sleepers, &sem->count); | ||
111 | break; | ||
112 | } | ||
113 | |||
114 | /* | ||
115 | * Add "everybody else" into it. They aren't | ||
116 | * playing, because we own the spinlock in | ||
117 | * wait_queue_head. The "-1" is because we're | ||
118 | * still hoping to get the semaphore. | ||
119 | */ | ||
120 | if (!atomic_add_negative(sleepers - 1, &sem->count)) { | ||
121 | sem->sleepers = 0; | ||
122 | break; | ||
123 | } | ||
124 | sem->sleepers = 1; /* us - see -1 above */ | ||
125 | spin_unlock_irqrestore(&sem->wait.lock, flags); | ||
126 | |||
127 | schedule(); | ||
128 | |||
129 | spin_lock_irqsave(&sem->wait.lock, flags); | ||
130 | tsk->state = TASK_INTERRUPTIBLE; | ||
131 | } | ||
132 | remove_wait_queue_locked(&sem->wait, &wait); | ||
133 | wake_up_locked(&sem->wait); | ||
134 | spin_unlock_irqrestore(&sem->wait.lock, flags); | ||
135 | |||
136 | tsk->state = TASK_RUNNING; | ||
137 | return retval; | ||
138 | } | ||
139 | |||
140 | /* | ||
141 | * Trylock failed - make sure we correct for having decremented the | ||
142 | * count. | ||
143 | */ | ||
144 | int | ||
145 | __down_trylock (struct semaphore *sem) | ||
146 | { | ||
147 | unsigned long flags; | ||
148 | int sleepers; | ||
149 | |||
150 | spin_lock_irqsave(&sem->wait.lock, flags); | ||
151 | sleepers = sem->sleepers + 1; | ||
152 | sem->sleepers = 0; | ||
153 | |||
154 | /* | ||
155 | * Add "everybody else" and us into it. They aren't | ||
156 | * playing, because we own the spinlock in the | ||
157 | * wait_queue_head. | ||
158 | */ | ||
159 | if (!atomic_add_negative(sleepers, &sem->count)) { | ||
160 | wake_up_locked(&sem->wait); | ||
161 | } | ||
162 | |||
163 | spin_unlock_irqrestore(&sem->wait.lock, flags); | ||
164 | return 1; | ||
165 | } | ||
diff --git a/arch/m32r/kernel/Makefile b/arch/m32r/kernel/Makefile index e97e26e87c9e..09200d4886e3 100644 --- a/arch/m32r/kernel/Makefile +++ b/arch/m32r/kernel/Makefile | |||
@@ -5,7 +5,7 @@ | |||
5 | extra-y := head.o init_task.o vmlinux.lds | 5 | extra-y := head.o init_task.o vmlinux.lds |
6 | 6 | ||
7 | obj-y := process.o entry.o traps.o align.o irq.o setup.o time.o \ | 7 | obj-y := process.o entry.o traps.o align.o irq.o setup.o time.o \ |
8 | m32r_ksyms.o sys_m32r.o semaphore.o signal.o ptrace.o | 8 | m32r_ksyms.o sys_m32r.o signal.o ptrace.o |
9 | 9 | ||
10 | obj-$(CONFIG_SMP) += smp.o smpboot.o | 10 | obj-$(CONFIG_SMP) += smp.o smpboot.o |
11 | obj-$(CONFIG_MODULES) += module.o | 11 | obj-$(CONFIG_MODULES) += module.o |
diff --git a/arch/m32r/kernel/m32r_ksyms.c b/arch/m32r/kernel/m32r_ksyms.c index 41a4c95e06d6..e6709fe950ba 100644 --- a/arch/m32r/kernel/m32r_ksyms.c +++ b/arch/m32r/kernel/m32r_ksyms.c | |||
@@ -7,7 +7,6 @@ | |||
7 | #include <linux/interrupt.h> | 7 | #include <linux/interrupt.h> |
8 | #include <linux/string.h> | 8 | #include <linux/string.h> |
9 | 9 | ||
10 | #include <asm/semaphore.h> | ||
11 | #include <asm/processor.h> | 10 | #include <asm/processor.h> |
12 | #include <asm/uaccess.h> | 11 | #include <asm/uaccess.h> |
13 | #include <asm/checksum.h> | 12 | #include <asm/checksum.h> |
@@ -22,10 +21,6 @@ EXPORT_SYMBOL(dump_fpu); | |||
22 | EXPORT_SYMBOL(__ioremap); | 21 | EXPORT_SYMBOL(__ioremap); |
23 | EXPORT_SYMBOL(iounmap); | 22 | EXPORT_SYMBOL(iounmap); |
24 | EXPORT_SYMBOL(kernel_thread); | 23 | EXPORT_SYMBOL(kernel_thread); |
25 | EXPORT_SYMBOL(__down); | ||
26 | EXPORT_SYMBOL(__down_interruptible); | ||
27 | EXPORT_SYMBOL(__up); | ||
28 | EXPORT_SYMBOL(__down_trylock); | ||
29 | 24 | ||
30 | /* Networking helper routines. */ | 25 | /* Networking helper routines. */ |
31 | /* Delay loops */ | 26 | /* Delay loops */ |
diff --git a/arch/m32r/kernel/semaphore.c b/arch/m32r/kernel/semaphore.c deleted file mode 100644 index 940c2d37cfd1..000000000000 --- a/arch/m32r/kernel/semaphore.c +++ /dev/null | |||
@@ -1,185 +0,0 @@ | |||
1 | /* | ||
2 | * linux/arch/m32r/semaphore.c | ||
3 | * orig : i386 2.6.4 | ||
4 | * | ||
5 | * M32R semaphore implementation. | ||
6 | * | ||
7 | * Copyright (c) 2002 - 2004 Hitoshi Yamamoto | ||
8 | */ | ||
9 | |||
10 | /* | ||
11 | * i386 semaphore implementation. | ||
12 | * | ||
13 | * (C) Copyright 1999 Linus Torvalds | ||
14 | * | ||
15 | * Portions Copyright 1999 Red Hat, Inc. | ||
16 | * | ||
17 | * This program is free software; you can redistribute it and/or | ||
18 | * modify it under the terms of the GNU General Public License | ||
19 | * as published by the Free Software Foundation; either version | ||
20 | * 2 of the License, or (at your option) any later version. | ||
21 | * | ||
22 | * rw semaphores implemented November 1999 by Benjamin LaHaise <bcrl@kvack.org> | ||
23 | */ | ||
24 | #include <linux/sched.h> | ||
25 | #include <linux/err.h> | ||
26 | #include <linux/init.h> | ||
27 | #include <asm/semaphore.h> | ||
28 | |||
29 | /* | ||
30 | * Semaphores are implemented using a two-way counter: | ||
31 | * The "count" variable is decremented for each process | ||
32 | * that tries to acquire the semaphore, while the "sleeping" | ||
33 | * variable is a count of such acquires. | ||
34 | * | ||
35 | * Notably, the inline "up()" and "down()" functions can | ||
36 | * efficiently test if they need to do any extra work (up | ||
37 | * needs to do something only if count was negative before | ||
38 | * the increment operation. | ||
39 | * | ||
40 | * "sleeping" and the contention routine ordering is protected | ||
41 | * by the spinlock in the semaphore's waitqueue head. | ||
42 | * | ||
43 | * Note that these functions are only called when there is | ||
44 | * contention on the lock, and as such all this is the | ||
45 | * "non-critical" part of the whole semaphore business. The | ||
46 | * critical part is the inline stuff in <asm/semaphore.h> | ||
47 | * where we want to avoid any extra jumps and calls. | ||
48 | */ | ||
49 | |||
50 | /* | ||
51 | * Logic: | ||
52 | * - only on a boundary condition do we need to care. When we go | ||
53 | * from a negative count to a non-negative, we wake people up. | ||
54 | * - when we go from a non-negative count to a negative do we | ||
55 | * (a) synchronize with the "sleeper" count and (b) make sure | ||
56 | * that we're on the wakeup list before we synchronize so that | ||
57 | * we cannot lose wakeup events. | ||
58 | */ | ||
59 | |||
60 | asmlinkage void __up(struct semaphore *sem) | ||
61 | { | ||
62 | wake_up(&sem->wait); | ||
63 | } | ||
64 | |||
65 | asmlinkage void __sched __down(struct semaphore * sem) | ||
66 | { | ||
67 | struct task_struct *tsk = current; | ||
68 | DECLARE_WAITQUEUE(wait, tsk); | ||
69 | unsigned long flags; | ||
70 | |||
71 | tsk->state = TASK_UNINTERRUPTIBLE; | ||
72 | spin_lock_irqsave(&sem->wait.lock, flags); | ||
73 | add_wait_queue_exclusive_locked(&sem->wait, &wait); | ||
74 | |||
75 | sem->sleepers++; | ||
76 | for (;;) { | ||
77 | int sleepers = sem->sleepers; | ||
78 | |||
79 | /* | ||
80 | * Add "everybody else" into it. They aren't | ||
81 | * playing, because we own the spinlock in | ||
82 | * the wait_queue_head. | ||
83 | */ | ||
84 | if (!atomic_add_negative(sleepers - 1, &sem->count)) { | ||
85 | sem->sleepers = 0; | ||
86 | break; | ||
87 | } | ||
88 | sem->sleepers = 1; /* us - see -1 above */ | ||
89 | spin_unlock_irqrestore(&sem->wait.lock, flags); | ||
90 | |||
91 | schedule(); | ||
92 | |||
93 | spin_lock_irqsave(&sem->wait.lock, flags); | ||
94 | tsk->state = TASK_UNINTERRUPTIBLE; | ||
95 | } | ||
96 | remove_wait_queue_locked(&sem->wait, &wait); | ||
97 | wake_up_locked(&sem->wait); | ||
98 | spin_unlock_irqrestore(&sem->wait.lock, flags); | ||
99 | tsk->state = TASK_RUNNING; | ||
100 | } | ||
101 | |||
102 | asmlinkage int __sched __down_interruptible(struct semaphore * sem) | ||
103 | { | ||
104 | int retval = 0; | ||
105 | struct task_struct *tsk = current; | ||
106 | DECLARE_WAITQUEUE(wait, tsk); | ||
107 | unsigned long flags; | ||
108 | |||
109 | tsk->state = TASK_INTERRUPTIBLE; | ||
110 | spin_lock_irqsave(&sem->wait.lock, flags); | ||
111 | add_wait_queue_exclusive_locked(&sem->wait, &wait); | ||
112 | |||
113 | sem->sleepers++; | ||
114 | for (;;) { | ||
115 | int sleepers = sem->sleepers; | ||
116 | |||
117 | /* | ||
118 | * With signals pending, this turns into | ||
119 | * the trylock failure case - we won't be | ||
120 | * sleeping, and we* can't get the lock as | ||
121 | * it has contention. Just correct the count | ||
122 | * and exit. | ||
123 | */ | ||
124 | if (signal_pending(current)) { | ||
125 | retval = -EINTR; | ||
126 | sem->sleepers = 0; | ||
127 | atomic_add(sleepers, &sem->count); | ||
128 | break; | ||
129 | } | ||
130 | |||
131 | /* | ||
132 | * Add "everybody else" into it. They aren't | ||
133 | * playing, because we own the spinlock in | ||
134 | * wait_queue_head. The "-1" is because we're | ||
135 | * still hoping to get the semaphore. | ||
136 | */ | ||
137 | if (!atomic_add_negative(sleepers - 1, &sem->count)) { | ||
138 | sem->sleepers = 0; | ||
139 | break; | ||
140 | } | ||
141 | sem->sleepers = 1; /* us - see -1 above */ | ||
142 | spin_unlock_irqrestore(&sem->wait.lock, flags); | ||
143 | |||
144 | schedule(); | ||
145 | |||
146 | spin_lock_irqsave(&sem->wait.lock, flags); | ||
147 | tsk->state = TASK_INTERRUPTIBLE; | ||
148 | } | ||
149 | remove_wait_queue_locked(&sem->wait, &wait); | ||
150 | wake_up_locked(&sem->wait); | ||
151 | spin_unlock_irqrestore(&sem->wait.lock, flags); | ||
152 | |||
153 | tsk->state = TASK_RUNNING; | ||
154 | return retval; | ||
155 | } | ||
156 | |||
157 | /* | ||
158 | * Trylock failed - make sure we correct for | ||
159 | * having decremented the count. | ||
160 | * | ||
161 | * We could have done the trylock with a | ||
162 | * single "cmpxchg" without failure cases, | ||
163 | * but then it wouldn't work on a 386. | ||
164 | */ | ||
165 | asmlinkage int __down_trylock(struct semaphore * sem) | ||
166 | { | ||
167 | int sleepers; | ||
168 | unsigned long flags; | ||
169 | |||
170 | spin_lock_irqsave(&sem->wait.lock, flags); | ||
171 | sleepers = sem->sleepers + 1; | ||
172 | sem->sleepers = 0; | ||
173 | |||
174 | /* | ||
175 | * Add "everybody else" and us into it. They aren't | ||
176 | * playing, because we own the spinlock in the | ||
177 | * wait_queue_head. | ||
178 | */ | ||
179 | if (!atomic_add_negative(sleepers, &sem->count)) { | ||
180 | wake_up_locked(&sem->wait); | ||
181 | } | ||
182 | |||
183 | spin_unlock_irqrestore(&sem->wait.lock, flags); | ||
184 | return 1; | ||
185 | } | ||
diff --git a/arch/m68k/kernel/Makefile b/arch/m68k/kernel/Makefile index a806208c7fb5..7a62a718143b 100644 --- a/arch/m68k/kernel/Makefile +++ b/arch/m68k/kernel/Makefile | |||
@@ -10,7 +10,7 @@ endif | |||
10 | extra-y += vmlinux.lds | 10 | extra-y += vmlinux.lds |
11 | 11 | ||
12 | obj-y := entry.o process.o traps.o ints.o signal.o ptrace.o module.o \ | 12 | obj-y := entry.o process.o traps.o ints.o signal.o ptrace.o module.o \ |
13 | sys_m68k.o time.o semaphore.o setup.o m68k_ksyms.o devres.o | 13 | sys_m68k.o time.o setup.o m68k_ksyms.o devres.o |
14 | 14 | ||
15 | devres-y = ../../../kernel/irq/devres.o | 15 | devres-y = ../../../kernel/irq/devres.o |
16 | 16 | ||
diff --git a/arch/m68k/kernel/m68k_ksyms.c b/arch/m68k/kernel/m68k_ksyms.c index 6fc69c74fe2e..d900e77e5363 100644 --- a/arch/m68k/kernel/m68k_ksyms.c +++ b/arch/m68k/kernel/m68k_ksyms.c | |||
@@ -1,5 +1,4 @@ | |||
1 | #include <linux/module.h> | 1 | #include <linux/module.h> |
2 | #include <asm/semaphore.h> | ||
3 | 2 | ||
4 | asmlinkage long long __ashldi3 (long long, int); | 3 | asmlinkage long long __ashldi3 (long long, int); |
5 | asmlinkage long long __ashrdi3 (long long, int); | 4 | asmlinkage long long __ashrdi3 (long long, int); |
@@ -15,8 +14,3 @@ EXPORT_SYMBOL(__ashrdi3); | |||
15 | EXPORT_SYMBOL(__lshrdi3); | 14 | EXPORT_SYMBOL(__lshrdi3); |
16 | EXPORT_SYMBOL(__muldi3); | 15 | EXPORT_SYMBOL(__muldi3); |
17 | 16 | ||
18 | EXPORT_SYMBOL(__down_failed); | ||
19 | EXPORT_SYMBOL(__down_failed_interruptible); | ||
20 | EXPORT_SYMBOL(__down_failed_trylock); | ||
21 | EXPORT_SYMBOL(__up_wakeup); | ||
22 | |||
diff --git a/arch/m68k/kernel/semaphore.c b/arch/m68k/kernel/semaphore.c deleted file mode 100644 index d12cbbfe6ebd..000000000000 --- a/arch/m68k/kernel/semaphore.c +++ /dev/null | |||
@@ -1,132 +0,0 @@ | |||
1 | /* | ||
2 | * Generic semaphore code. Buyer beware. Do your own | ||
3 | * specific changes in <asm/semaphore-helper.h> | ||
4 | */ | ||
5 | |||
6 | #include <linux/sched.h> | ||
7 | #include <linux/init.h> | ||
8 | #include <asm/semaphore-helper.h> | ||
9 | |||
10 | #ifndef CONFIG_RMW_INSNS | ||
11 | spinlock_t semaphore_wake_lock; | ||
12 | #endif | ||
13 | |||
14 | /* | ||
15 | * Semaphores are implemented using a two-way counter: | ||
16 | * The "count" variable is decremented for each process | ||
17 | * that tries to sleep, while the "waking" variable is | ||
18 | * incremented when the "up()" code goes to wake up waiting | ||
19 | * processes. | ||
20 | * | ||
21 | * Notably, the inline "up()" and "down()" functions can | ||
22 | * efficiently test if they need to do any extra work (up | ||
23 | * needs to do something only if count was negative before | ||
24 | * the increment operation. | ||
25 | * | ||
26 | * waking_non_zero() (from asm/semaphore.h) must execute | ||
27 | * atomically. | ||
28 | * | ||
29 | * When __up() is called, the count was negative before | ||
30 | * incrementing it, and we need to wake up somebody. | ||
31 | * | ||
32 | * This routine adds one to the count of processes that need to | ||
33 | * wake up and exit. ALL waiting processes actually wake up but | ||
34 | * only the one that gets to the "waking" field first will gate | ||
35 | * through and acquire the semaphore. The others will go back | ||
36 | * to sleep. | ||
37 | * | ||
38 | * Note that these functions are only called when there is | ||
39 | * contention on the lock, and as such all this is the | ||
40 | * "non-critical" part of the whole semaphore business. The | ||
41 | * critical part is the inline stuff in <asm/semaphore.h> | ||
42 | * where we want to avoid any extra jumps and calls. | ||
43 | */ | ||
44 | void __up(struct semaphore *sem) | ||
45 | { | ||
46 | wake_one_more(sem); | ||
47 | wake_up(&sem->wait); | ||
48 | } | ||
49 | |||
50 | /* | ||
51 | * Perform the "down" function. Return zero for semaphore acquired, | ||
52 | * return negative for signalled out of the function. | ||
53 | * | ||
54 | * If called from __down, the return is ignored and the wait loop is | ||
55 | * not interruptible. This means that a task waiting on a semaphore | ||
56 | * using "down()" cannot be killed until someone does an "up()" on | ||
57 | * the semaphore. | ||
58 | * | ||
59 | * If called from __down_interruptible, the return value gets checked | ||
60 | * upon return. If the return value is negative then the task continues | ||
61 | * with the negative value in the return register (it can be tested by | ||
62 | * the caller). | ||
63 | * | ||
64 | * Either form may be used in conjunction with "up()". | ||
65 | * | ||
66 | */ | ||
67 | |||
68 | |||
69 | #define DOWN_HEAD(task_state) \ | ||
70 | \ | ||
71 | \ | ||
72 | current->state = (task_state); \ | ||
73 | add_wait_queue(&sem->wait, &wait); \ | ||
74 | \ | ||
75 | /* \ | ||
76 | * Ok, we're set up. sem->count is known to be less than zero \ | ||
77 | * so we must wait. \ | ||
78 | * \ | ||
79 | * We can let go the lock for purposes of waiting. \ | ||
80 | * We re-acquire it after awaking so as to protect \ | ||
81 | * all semaphore operations. \ | ||
82 | * \ | ||
83 | * If "up()" is called before we call waking_non_zero() then \ | ||
84 | * we will catch it right away. If it is called later then \ | ||
85 | * we will have to go through a wakeup cycle to catch it. \ | ||
86 | * \ | ||
87 | * Multiple waiters contend for the semaphore lock to see \ | ||
88 | * who gets to gate through and who has to wait some more. \ | ||
89 | */ \ | ||
90 | for (;;) { | ||
91 | |||
92 | #define DOWN_TAIL(task_state) \ | ||
93 | current->state = (task_state); \ | ||
94 | } \ | ||
95 | current->state = TASK_RUNNING; \ | ||
96 | remove_wait_queue(&sem->wait, &wait); | ||
97 | |||
98 | void __sched __down(struct semaphore * sem) | ||
99 | { | ||
100 | DECLARE_WAITQUEUE(wait, current); | ||
101 | |||
102 | DOWN_HEAD(TASK_UNINTERRUPTIBLE) | ||
103 | if (waking_non_zero(sem)) | ||
104 | break; | ||
105 | schedule(); | ||
106 | DOWN_TAIL(TASK_UNINTERRUPTIBLE) | ||
107 | } | ||
108 | |||
109 | int __sched __down_interruptible(struct semaphore * sem) | ||
110 | { | ||
111 | DECLARE_WAITQUEUE(wait, current); | ||
112 | int ret = 0; | ||
113 | |||
114 | DOWN_HEAD(TASK_INTERRUPTIBLE) | ||
115 | |||
116 | ret = waking_non_zero_interruptible(sem, current); | ||
117 | if (ret) | ||
118 | { | ||
119 | if (ret == 1) | ||
120 | /* ret != 0 only if we get interrupted -arca */ | ||
121 | ret = 0; | ||
122 | break; | ||
123 | } | ||
124 | schedule(); | ||
125 | DOWN_TAIL(TASK_INTERRUPTIBLE) | ||
126 | return ret; | ||
127 | } | ||
128 | |||
129 | int __down_trylock(struct semaphore * sem) | ||
130 | { | ||
131 | return waking_non_zero_trylock(sem); | ||
132 | } | ||
diff --git a/arch/m68k/lib/Makefile b/arch/m68k/lib/Makefile index 6bbf19f96007..a18af095cd7c 100644 --- a/arch/m68k/lib/Makefile +++ b/arch/m68k/lib/Makefile | |||
@@ -5,4 +5,4 @@ | |||
5 | EXTRA_AFLAGS := -traditional | 5 | EXTRA_AFLAGS := -traditional |
6 | 6 | ||
7 | lib-y := ashldi3.o ashrdi3.o lshrdi3.o muldi3.o \ | 7 | lib-y := ashldi3.o ashrdi3.o lshrdi3.o muldi3.o \ |
8 | checksum.o string.o semaphore.o uaccess.o | 8 | checksum.o string.o uaccess.o |
diff --git a/arch/m68k/lib/semaphore.S b/arch/m68k/lib/semaphore.S deleted file mode 100644 index 0215624c1602..000000000000 --- a/arch/m68k/lib/semaphore.S +++ /dev/null | |||
@@ -1,53 +0,0 @@ | |||
1 | /* | ||
2 | * linux/arch/m68k/lib/semaphore.S | ||
3 | * | ||
4 | * Copyright (C) 1996 Linus Torvalds | ||
5 | * | ||
6 | * m68k version by Andreas Schwab | ||
7 | */ | ||
8 | |||
9 | #include <linux/linkage.h> | ||
10 | #include <asm/semaphore.h> | ||
11 | |||
12 | /* | ||
13 | * The semaphore operations have a special calling sequence that | ||
14 | * allow us to do a simpler in-line version of them. These routines | ||
15 | * need to convert that sequence back into the C sequence when | ||
16 | * there is contention on the semaphore. | ||
17 | */ | ||
18 | ENTRY(__down_failed) | ||
19 | moveml %a0/%d0/%d1,-(%sp) | ||
20 | movel %a1,-(%sp) | ||
21 | jbsr __down | ||
22 | movel (%sp)+,%a1 | ||
23 | moveml (%sp)+,%a0/%d0/%d1 | ||
24 | rts | ||
25 | |||
26 | ENTRY(__down_failed_interruptible) | ||
27 | movel %a0,-(%sp) | ||
28 | movel %d1,-(%sp) | ||
29 | movel %a1,-(%sp) | ||
30 | jbsr __down_interruptible | ||
31 | movel (%sp)+,%a1 | ||
32 | movel (%sp)+,%d1 | ||
33 | movel (%sp)+,%a0 | ||
34 | rts | ||
35 | |||
36 | ENTRY(__down_failed_trylock) | ||
37 | movel %a0,-(%sp) | ||
38 | movel %d1,-(%sp) | ||
39 | movel %a1,-(%sp) | ||
40 | jbsr __down_trylock | ||
41 | movel (%sp)+,%a1 | ||
42 | movel (%sp)+,%d1 | ||
43 | movel (%sp)+,%a0 | ||
44 | rts | ||
45 | |||
46 | ENTRY(__up_wakeup) | ||
47 | moveml %a0/%d0/%d1,-(%sp) | ||
48 | movel %a1,-(%sp) | ||
49 | jbsr __up | ||
50 | movel (%sp)+,%a1 | ||
51 | moveml (%sp)+,%a0/%d0/%d1 | ||
52 | rts | ||
53 | |||
diff --git a/arch/m68knommu/kernel/Makefile b/arch/m68knommu/kernel/Makefile index 1524b39ad63f..f0eab3dedb5a 100644 --- a/arch/m68knommu/kernel/Makefile +++ b/arch/m68knommu/kernel/Makefile | |||
@@ -5,7 +5,7 @@ | |||
5 | extra-y := vmlinux.lds | 5 | extra-y := vmlinux.lds |
6 | 6 | ||
7 | obj-y += dma.o entry.o init_task.o irq.o m68k_ksyms.o process.o ptrace.o \ | 7 | obj-y += dma.o entry.o init_task.o irq.o m68k_ksyms.o process.o ptrace.o \ |
8 | semaphore.o setup.o signal.o syscalltable.o sys_m68k.o time.o traps.o | 8 | setup.o signal.o syscalltable.o sys_m68k.o time.o traps.o |
9 | 9 | ||
10 | obj-$(CONFIG_MODULES) += module.o | 10 | obj-$(CONFIG_MODULES) += module.o |
11 | obj-$(CONFIG_COMEMPCI) += comempci.o | 11 | obj-$(CONFIG_COMEMPCI) += comempci.o |
diff --git a/arch/m68knommu/kernel/m68k_ksyms.c b/arch/m68knommu/kernel/m68k_ksyms.c index 53fad1490282..39fe0a7aec32 100644 --- a/arch/m68knommu/kernel/m68k_ksyms.c +++ b/arch/m68knommu/kernel/m68k_ksyms.c | |||
@@ -13,7 +13,6 @@ | |||
13 | #include <asm/pgalloc.h> | 13 | #include <asm/pgalloc.h> |
14 | #include <asm/irq.h> | 14 | #include <asm/irq.h> |
15 | #include <asm/io.h> | 15 | #include <asm/io.h> |
16 | #include <asm/semaphore.h> | ||
17 | #include <asm/checksum.h> | 16 | #include <asm/checksum.h> |
18 | #include <asm/current.h> | 17 | #include <asm/current.h> |
19 | 18 | ||
@@ -39,11 +38,6 @@ EXPORT_SYMBOL(csum_partial_copy_nocheck); | |||
39 | EXPORT_SYMBOL(memcpy); | 38 | EXPORT_SYMBOL(memcpy); |
40 | EXPORT_SYMBOL(memset); | 39 | EXPORT_SYMBOL(memset); |
41 | 40 | ||
42 | EXPORT_SYMBOL(__down_failed); | ||
43 | EXPORT_SYMBOL(__down_failed_interruptible); | ||
44 | EXPORT_SYMBOL(__down_failed_trylock); | ||
45 | EXPORT_SYMBOL(__up_wakeup); | ||
46 | |||
47 | /* | 41 | /* |
48 | * libgcc functions - functions that are used internally by the | 42 | * libgcc functions - functions that are used internally by the |
49 | * compiler... (prototypes are not correct though, but that | 43 | * compiler... (prototypes are not correct though, but that |
diff --git a/arch/m68knommu/kernel/semaphore.c b/arch/m68knommu/kernel/semaphore.c deleted file mode 100644 index bce2bc7d87c6..000000000000 --- a/arch/m68knommu/kernel/semaphore.c +++ /dev/null | |||
@@ -1,133 +0,0 @@ | |||
1 | /* | ||
2 | * Generic semaphore code. Buyer beware. Do your own | ||
3 | * specific changes in <asm/semaphore-helper.h> | ||
4 | */ | ||
5 | |||
6 | #include <linux/sched.h> | ||
7 | #include <linux/err.h> | ||
8 | #include <linux/init.h> | ||
9 | #include <asm/semaphore-helper.h> | ||
10 | |||
11 | #ifndef CONFIG_RMW_INSNS | ||
12 | spinlock_t semaphore_wake_lock; | ||
13 | #endif | ||
14 | |||
15 | /* | ||
16 | * Semaphores are implemented using a two-way counter: | ||
17 | * The "count" variable is decremented for each process | ||
18 | * that tries to sleep, while the "waking" variable is | ||
19 | * incremented when the "up()" code goes to wake up waiting | ||
20 | * processes. | ||
21 | * | ||
22 | * Notably, the inline "up()" and "down()" functions can | ||
23 | * efficiently test if they need to do any extra work (up | ||
24 | * needs to do something only if count was negative before | ||
25 | * the increment operation. | ||
26 | * | ||
27 | * waking_non_zero() (from asm/semaphore.h) must execute | ||
28 | * atomically. | ||
29 | * | ||
30 | * When __up() is called, the count was negative before | ||
31 | * incrementing it, and we need to wake up somebody. | ||
32 | * | ||
33 | * This routine adds one to the count of processes that need to | ||
34 | * wake up and exit. ALL waiting processes actually wake up but | ||
35 | * only the one that gets to the "waking" field first will gate | ||
36 | * through and acquire the semaphore. The others will go back | ||
37 | * to sleep. | ||
38 | * | ||
39 | * Note that these functions are only called when there is | ||
40 | * contention on the lock, and as such all this is the | ||
41 | * "non-critical" part of the whole semaphore business. The | ||
42 | * critical part is the inline stuff in <asm/semaphore.h> | ||
43 | * where we want to avoid any extra jumps and calls. | ||
44 | */ | ||
45 | void __up(struct semaphore *sem) | ||
46 | { | ||
47 | wake_one_more(sem); | ||
48 | wake_up(&sem->wait); | ||
49 | } | ||
50 | |||
51 | /* | ||
52 | * Perform the "down" function. Return zero for semaphore acquired, | ||
53 | * return negative for signalled out of the function. | ||
54 | * | ||
55 | * If called from __down, the return is ignored and the wait loop is | ||
56 | * not interruptible. This means that a task waiting on a semaphore | ||
57 | * using "down()" cannot be killed until someone does an "up()" on | ||
58 | * the semaphore. | ||
59 | * | ||
60 | * If called from __down_interruptible, the return value gets checked | ||
61 | * upon return. If the return value is negative then the task continues | ||
62 | * with the negative value in the return register (it can be tested by | ||
63 | * the caller). | ||
64 | * | ||
65 | * Either form may be used in conjunction with "up()". | ||
66 | * | ||
67 | */ | ||
68 | |||
69 | |||
70 | #define DOWN_HEAD(task_state) \ | ||
71 | \ | ||
72 | \ | ||
73 | current->state = (task_state); \ | ||
74 | add_wait_queue(&sem->wait, &wait); \ | ||
75 | \ | ||
76 | /* \ | ||
77 | * Ok, we're set up. sem->count is known to be less than zero \ | ||
78 | * so we must wait. \ | ||
79 | * \ | ||
80 | * We can let go the lock for purposes of waiting. \ | ||
81 | * We re-acquire it after awaking so as to protect \ | ||
82 | * all semaphore operations. \ | ||
83 | * \ | ||
84 | * If "up()" is called before we call waking_non_zero() then \ | ||
85 | * we will catch it right away. If it is called later then \ | ||
86 | * we will have to go through a wakeup cycle to catch it. \ | ||
87 | * \ | ||
88 | * Multiple waiters contend for the semaphore lock to see \ | ||
89 | * who gets to gate through and who has to wait some more. \ | ||
90 | */ \ | ||
91 | for (;;) { | ||
92 | |||
93 | #define DOWN_TAIL(task_state) \ | ||
94 | current->state = (task_state); \ | ||
95 | } \ | ||
96 | current->state = TASK_RUNNING; \ | ||
97 | remove_wait_queue(&sem->wait, &wait); | ||
98 | |||
99 | void __sched __down(struct semaphore * sem) | ||
100 | { | ||
101 | DECLARE_WAITQUEUE(wait, current); | ||
102 | |||
103 | DOWN_HEAD(TASK_UNINTERRUPTIBLE) | ||
104 | if (waking_non_zero(sem)) | ||
105 | break; | ||
106 | schedule(); | ||
107 | DOWN_TAIL(TASK_UNINTERRUPTIBLE) | ||
108 | } | ||
109 | |||
110 | int __sched __down_interruptible(struct semaphore * sem) | ||
111 | { | ||
112 | DECLARE_WAITQUEUE(wait, current); | ||
113 | int ret = 0; | ||
114 | |||
115 | DOWN_HEAD(TASK_INTERRUPTIBLE) | ||
116 | |||
117 | ret = waking_non_zero_interruptible(sem, current); | ||
118 | if (ret) | ||
119 | { | ||
120 | if (ret == 1) | ||
121 | /* ret != 0 only if we get interrupted -arca */ | ||
122 | ret = 0; | ||
123 | break; | ||
124 | } | ||
125 | schedule(); | ||
126 | DOWN_TAIL(TASK_INTERRUPTIBLE) | ||
127 | return ret; | ||
128 | } | ||
129 | |||
130 | int __down_trylock(struct semaphore * sem) | ||
131 | { | ||
132 | return waking_non_zero_trylock(sem); | ||
133 | } | ||
diff --git a/arch/m68knommu/lib/Makefile b/arch/m68knommu/lib/Makefile index e051a7913987..d94d709665aa 100644 --- a/arch/m68knommu/lib/Makefile +++ b/arch/m68knommu/lib/Makefile | |||
@@ -4,4 +4,4 @@ | |||
4 | 4 | ||
5 | lib-y := ashldi3.o ashrdi3.o lshrdi3.o \ | 5 | lib-y := ashldi3.o ashrdi3.o lshrdi3.o \ |
6 | muldi3.o mulsi3.o divsi3.o udivsi3.o modsi3.o umodsi3.o \ | 6 | muldi3.o mulsi3.o divsi3.o udivsi3.o modsi3.o umodsi3.o \ |
7 | checksum.o semaphore.o memcpy.o memset.o delay.o | 7 | checksum.o memcpy.o memset.o delay.o |
diff --git a/arch/m68knommu/lib/semaphore.S b/arch/m68knommu/lib/semaphore.S deleted file mode 100644 index 87c746034376..000000000000 --- a/arch/m68knommu/lib/semaphore.S +++ /dev/null | |||
@@ -1,66 +0,0 @@ | |||
1 | /* | ||
2 | * linux/arch/m68k/lib/semaphore.S | ||
3 | * | ||
4 | * Copyright (C) 1996 Linus Torvalds | ||
5 | * | ||
6 | * m68k version by Andreas Schwab | ||
7 | * | ||
8 | * MAR/1999 -- modified to support ColdFire (gerg@snapgear.com) | ||
9 | */ | ||
10 | |||
11 | #include <linux/linkage.h> | ||
12 | #include <asm/semaphore.h> | ||
13 | |||
14 | /* | ||
15 | * "down_failed" is called with the eventual return address | ||
16 | * in %a0, and the address of the semaphore in %a1. We need | ||
17 | * to increment the number of waiters on the semaphore, | ||
18 | * call "__down()", and then eventually return to try again. | ||
19 | */ | ||
20 | ENTRY(__down_failed) | ||
21 | #ifdef CONFIG_COLDFIRE | ||
22 | subl #12,%sp | ||
23 | moveml %a0/%d0/%d1,(%sp) | ||
24 | #else | ||
25 | moveml %a0/%d0/%d1,-(%sp) | ||
26 | #endif | ||
27 | movel %a1,-(%sp) | ||
28 | jbsr __down | ||
29 | movel (%sp)+,%a1 | ||
30 | movel (%sp)+,%d0 | ||
31 | movel (%sp)+,%d1 | ||
32 | rts | ||
33 | |||
34 | ENTRY(__down_failed_interruptible) | ||
35 | movel %a0,-(%sp) | ||
36 | movel %d1,-(%sp) | ||
37 | movel %a1,-(%sp) | ||
38 | jbsr __down_interruptible | ||
39 | movel (%sp)+,%a1 | ||
40 | movel (%sp)+,%d1 | ||
41 | rts | ||
42 | |||
43 | ENTRY(__up_wakeup) | ||
44 | #ifdef CONFIG_COLDFIRE | ||
45 | subl #12,%sp | ||
46 | moveml %a0/%d0/%d1,(%sp) | ||
47 | #else | ||
48 | moveml %a0/%d0/%d1,-(%sp) | ||
49 | #endif | ||
50 | movel %a1,-(%sp) | ||
51 | jbsr __up | ||
52 | movel (%sp)+,%a1 | ||
53 | movel (%sp)+,%d0 | ||
54 | movel (%sp)+,%d1 | ||
55 | rts | ||
56 | |||
57 | ENTRY(__down_failed_trylock) | ||
58 | movel %a0,-(%sp) | ||
59 | movel %d1,-(%sp) | ||
60 | movel %a1,-(%sp) | ||
61 | jbsr __down_trylock | ||
62 | movel (%sp)+,%a1 | ||
63 | movel (%sp)+,%d1 | ||
64 | movel (%sp)+,%a0 | ||
65 | rts | ||
66 | |||
diff --git a/arch/mips/kernel/Makefile b/arch/mips/kernel/Makefile index 9e78e1a4ca17..6fcdb6fda2e2 100644 --- a/arch/mips/kernel/Makefile +++ b/arch/mips/kernel/Makefile | |||
@@ -5,7 +5,7 @@ | |||
5 | extra-y := head.o init_task.o vmlinux.lds | 5 | extra-y := head.o init_task.o vmlinux.lds |
6 | 6 | ||
7 | obj-y += cpu-probe.o branch.o entry.o genex.o irq.o process.o \ | 7 | obj-y += cpu-probe.o branch.o entry.o genex.o irq.o process.o \ |
8 | ptrace.o reset.o semaphore.o setup.o signal.o syscall.o \ | 8 | ptrace.o reset.o setup.o signal.o syscall.o \ |
9 | time.o topology.o traps.o unaligned.o | 9 | time.o topology.o traps.o unaligned.o |
10 | 10 | ||
11 | obj-$(CONFIG_CEVT_BCM1480) += cevt-bcm1480.o | 11 | obj-$(CONFIG_CEVT_BCM1480) += cevt-bcm1480.o |
diff --git a/arch/mips/kernel/semaphore.c b/arch/mips/kernel/semaphore.c deleted file mode 100644 index 1265358cdca1..000000000000 --- a/arch/mips/kernel/semaphore.c +++ /dev/null | |||
@@ -1,168 +0,0 @@ | |||
1 | /* | ||
2 | * MIPS-specific semaphore code. | ||
3 | * | ||
4 | * Copyright (C) 1999 Cort Dougan <cort@cs.nmt.edu> | ||
5 | * Copyright (C) 2004 Ralf Baechle <ralf@linux-mips.org> | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or | ||
8 | * modify it under the terms of the GNU General Public License | ||
9 | * as published by the Free Software Foundation; either version | ||
10 | * 2 of the License, or (at your option) any later version. | ||
11 | * | ||
12 | * April 2001 - Reworked by Paul Mackerras <paulus@samba.org> | ||
13 | * to eliminate the SMP races in the old version between the updates | ||
14 | * of `count' and `waking'. Now we use negative `count' values to | ||
15 | * indicate that some process(es) are waiting for the semaphore. | ||
16 | */ | ||
17 | |||
18 | #include <linux/module.h> | ||
19 | #include <linux/sched.h> | ||
20 | #include <linux/init.h> | ||
21 | #include <asm/atomic.h> | ||
22 | #include <asm/cpu-features.h> | ||
23 | #include <asm/errno.h> | ||
24 | #include <asm/semaphore.h> | ||
25 | #include <asm/war.h> | ||
26 | /* | ||
27 | * Atomically update sem->count. | ||
28 | * This does the equivalent of the following: | ||
29 | * | ||
30 | * old_count = sem->count; | ||
31 | * tmp = MAX(old_count, 0) + incr; | ||
32 | * sem->count = tmp; | ||
33 | * return old_count; | ||
34 | * | ||
35 | * On machines without lld/scd we need a spinlock to make the manipulation of | ||
36 | * sem->count and sem->waking atomic. Scalability isn't an issue because | ||
37 | * this lock is used on UP only so it's just an empty variable. | ||
38 | */ | ||
39 | static inline int __sem_update_count(struct semaphore *sem, int incr) | ||
40 | { | ||
41 | int old_count, tmp; | ||
42 | |||
43 | if (cpu_has_llsc && R10000_LLSC_WAR) { | ||
44 | __asm__ __volatile__( | ||
45 | " .set mips3 \n" | ||
46 | "1: ll %0, %2 # __sem_update_count \n" | ||
47 | " sra %1, %0, 31 \n" | ||
48 | " not %1 \n" | ||
49 | " and %1, %0, %1 \n" | ||
50 | " addu %1, %1, %3 \n" | ||
51 | " sc %1, %2 \n" | ||
52 | " beqzl %1, 1b \n" | ||
53 | " .set mips0 \n" | ||
54 | : "=&r" (old_count), "=&r" (tmp), "=m" (sem->count) | ||
55 | : "r" (incr), "m" (sem->count)); | ||
56 | } else if (cpu_has_llsc) { | ||
57 | __asm__ __volatile__( | ||
58 | " .set mips3 \n" | ||
59 | "1: ll %0, %2 # __sem_update_count \n" | ||
60 | " sra %1, %0, 31 \n" | ||
61 | " not %1 \n" | ||
62 | " and %1, %0, %1 \n" | ||
63 | " addu %1, %1, %3 \n" | ||
64 | " sc %1, %2 \n" | ||
65 | " beqz %1, 1b \n" | ||
66 | " .set mips0 \n" | ||
67 | : "=&r" (old_count), "=&r" (tmp), "=m" (sem->count) | ||
68 | : "r" (incr), "m" (sem->count)); | ||
69 | } else { | ||
70 | static DEFINE_SPINLOCK(semaphore_lock); | ||
71 | unsigned long flags; | ||
72 | |||
73 | spin_lock_irqsave(&semaphore_lock, flags); | ||
74 | old_count = atomic_read(&sem->count); | ||
75 | tmp = max_t(int, old_count, 0) + incr; | ||
76 | atomic_set(&sem->count, tmp); | ||
77 | spin_unlock_irqrestore(&semaphore_lock, flags); | ||
78 | } | ||
79 | |||
80 | return old_count; | ||
81 | } | ||
82 | |||
83 | void __up(struct semaphore *sem) | ||
84 | { | ||
85 | /* | ||
86 | * Note that we incremented count in up() before we came here, | ||
87 | * but that was ineffective since the result was <= 0, and | ||
88 | * any negative value of count is equivalent to 0. | ||
89 | * This ends up setting count to 1, unless count is now > 0 | ||
90 | * (i.e. because some other cpu has called up() in the meantime), | ||
91 | * in which case we just increment count. | ||
92 | */ | ||
93 | __sem_update_count(sem, 1); | ||
94 | wake_up(&sem->wait); | ||
95 | } | ||
96 | |||
97 | EXPORT_SYMBOL(__up); | ||
98 | |||
99 | /* | ||
100 | * Note that when we come in to __down or __down_interruptible, | ||
101 | * we have already decremented count, but that decrement was | ||
102 | * ineffective since the result was < 0, and any negative value | ||
103 | * of count is equivalent to 0. | ||
104 | * Thus it is only when we decrement count from some value > 0 | ||
105 | * that we have actually got the semaphore. | ||
106 | */ | ||
107 | void __sched __down(struct semaphore *sem) | ||
108 | { | ||
109 | struct task_struct *tsk = current; | ||
110 | DECLARE_WAITQUEUE(wait, tsk); | ||
111 | |||
112 | __set_task_state(tsk, TASK_UNINTERRUPTIBLE); | ||
113 | add_wait_queue_exclusive(&sem->wait, &wait); | ||
114 | |||
115 | /* | ||
116 | * Try to get the semaphore. If the count is > 0, then we've | ||
117 | * got the semaphore; we decrement count and exit the loop. | ||
118 | * If the count is 0 or negative, we set it to -1, indicating | ||
119 | * that we are asleep, and then sleep. | ||
120 | */ | ||
121 | while (__sem_update_count(sem, -1) <= 0) { | ||
122 | schedule(); | ||
123 | set_task_state(tsk, TASK_UNINTERRUPTIBLE); | ||
124 | } | ||
125 | remove_wait_queue(&sem->wait, &wait); | ||
126 | __set_task_state(tsk, TASK_RUNNING); | ||
127 | |||
128 | /* | ||
129 | * If there are any more sleepers, wake one of them up so | ||
130 | * that it can either get the semaphore, or set count to -1 | ||
131 | * indicating that there are still processes sleeping. | ||
132 | */ | ||
133 | wake_up(&sem->wait); | ||
134 | } | ||
135 | |||
136 | EXPORT_SYMBOL(__down); | ||
137 | |||
138 | int __sched __down_interruptible(struct semaphore * sem) | ||
139 | { | ||
140 | int retval = 0; | ||
141 | struct task_struct *tsk = current; | ||
142 | DECLARE_WAITQUEUE(wait, tsk); | ||
143 | |||
144 | __set_task_state(tsk, TASK_INTERRUPTIBLE); | ||
145 | add_wait_queue_exclusive(&sem->wait, &wait); | ||
146 | |||
147 | while (__sem_update_count(sem, -1) <= 0) { | ||
148 | if (signal_pending(current)) { | ||
149 | /* | ||
150 | * A signal is pending - give up trying. | ||
151 | * Set sem->count to 0 if it is negative, | ||
152 | * since we are no longer sleeping. | ||
153 | */ | ||
154 | __sem_update_count(sem, 0); | ||
155 | retval = -EINTR; | ||
156 | break; | ||
157 | } | ||
158 | schedule(); | ||
159 | set_task_state(tsk, TASK_INTERRUPTIBLE); | ||
160 | } | ||
161 | remove_wait_queue(&sem->wait, &wait); | ||
162 | __set_task_state(tsk, TASK_RUNNING); | ||
163 | |||
164 | wake_up(&sem->wait); | ||
165 | return retval; | ||
166 | } | ||
167 | |||
168 | EXPORT_SYMBOL(__down_interruptible); | ||
diff --git a/arch/mn10300/kernel/Makefile b/arch/mn10300/kernel/Makefile index ef07c956170a..23f2ab67574c 100644 --- a/arch/mn10300/kernel/Makefile +++ b/arch/mn10300/kernel/Makefile | |||
@@ -3,7 +3,7 @@ | |||
3 | # | 3 | # |
4 | extra-y := head.o init_task.o vmlinux.lds | 4 | extra-y := head.o init_task.o vmlinux.lds |
5 | 5 | ||
6 | obj-y := process.o semaphore.o signal.o entry.o fpu.o traps.o irq.o \ | 6 | obj-y := process.o signal.o entry.o fpu.o traps.o irq.o \ |
7 | ptrace.o setup.o time.o sys_mn10300.o io.o kthread.o \ | 7 | ptrace.o setup.o time.o sys_mn10300.o io.o kthread.o \ |
8 | switch_to.o mn10300_ksyms.o kernel_execve.o | 8 | switch_to.o mn10300_ksyms.o kernel_execve.o |
9 | 9 | ||
diff --git a/arch/mn10300/kernel/semaphore.c b/arch/mn10300/kernel/semaphore.c deleted file mode 100644 index 9153c4039fd2..000000000000 --- a/arch/mn10300/kernel/semaphore.c +++ /dev/null | |||
@@ -1,149 +0,0 @@ | |||
1 | /* MN10300 Semaphore implementation | ||
2 | * | ||
3 | * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved. | ||
4 | * Written by David Howells (dhowells@redhat.com) | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or | ||
7 | * modify it under the terms of the GNU General Public Licence | ||
8 | * as published by the Free Software Foundation; either version | ||
9 | * 2 of the Licence, or (at your option) any later version. | ||
10 | */ | ||
11 | #include <linux/sched.h> | ||
12 | #include <linux/module.h> | ||
13 | #include <asm/semaphore.h> | ||
14 | |||
15 | struct sem_waiter { | ||
16 | struct list_head list; | ||
17 | struct task_struct *task; | ||
18 | }; | ||
19 | |||
20 | #if SEMAPHORE_DEBUG | ||
21 | void semtrace(struct semaphore *sem, const char *str) | ||
22 | { | ||
23 | if (sem->debug) | ||
24 | printk(KERN_DEBUG "[%d] %s({%d,%d})\n", | ||
25 | current->pid, | ||
26 | str, | ||
27 | atomic_read(&sem->count), | ||
28 | list_empty(&sem->wait_list) ? 0 : 1); | ||
29 | } | ||
30 | #else | ||
31 | #define semtrace(SEM, STR) do { } while (0) | ||
32 | #endif | ||
33 | |||
34 | /* | ||
35 | * wait for a token to be granted from a semaphore | ||
36 | * - entered with lock held and interrupts disabled | ||
37 | */ | ||
38 | void __down(struct semaphore *sem, unsigned long flags) | ||
39 | { | ||
40 | struct task_struct *tsk = current; | ||
41 | struct sem_waiter waiter; | ||
42 | |||
43 | semtrace(sem, "Entering __down"); | ||
44 | |||
45 | /* set up my own style of waitqueue */ | ||
46 | waiter.task = tsk; | ||
47 | get_task_struct(tsk); | ||
48 | |||
49 | list_add_tail(&waiter.list, &sem->wait_list); | ||
50 | |||
51 | /* we don't need to touch the semaphore struct anymore */ | ||
52 | spin_unlock_irqrestore(&sem->wait_lock, flags); | ||
53 | |||
54 | /* wait to be given the semaphore */ | ||
55 | set_task_state(tsk, TASK_UNINTERRUPTIBLE); | ||
56 | |||
57 | for (;;) { | ||
58 | if (!waiter.task) | ||
59 | break; | ||
60 | schedule(); | ||
61 | set_task_state(tsk, TASK_UNINTERRUPTIBLE); | ||
62 | } | ||
63 | |||
64 | tsk->state = TASK_RUNNING; | ||
65 | semtrace(sem, "Leaving __down"); | ||
66 | } | ||
67 | EXPORT_SYMBOL(__down); | ||
68 | |||
69 | /* | ||
70 | * interruptibly wait for a token to be granted from a semaphore | ||
71 | * - entered with lock held and interrupts disabled | ||
72 | */ | ||
73 | int __down_interruptible(struct semaphore *sem, unsigned long flags) | ||
74 | { | ||
75 | struct task_struct *tsk = current; | ||
76 | struct sem_waiter waiter; | ||
77 | int ret; | ||
78 | |||
79 | semtrace(sem, "Entering __down_interruptible"); | ||
80 | |||
81 | /* set up my own style of waitqueue */ | ||
82 | waiter.task = tsk; | ||
83 | get_task_struct(tsk); | ||
84 | |||
85 | list_add_tail(&waiter.list, &sem->wait_list); | ||
86 | |||
87 | /* we don't need to touch the semaphore struct anymore */ | ||
88 | set_task_state(tsk, TASK_INTERRUPTIBLE); | ||
89 | |||
90 | spin_unlock_irqrestore(&sem->wait_lock, flags); | ||
91 | |||
92 | /* wait to be given the semaphore */ | ||
93 | ret = 0; | ||
94 | for (;;) { | ||
95 | if (!waiter.task) | ||
96 | break; | ||
97 | if (unlikely(signal_pending(current))) | ||
98 | goto interrupted; | ||
99 | schedule(); | ||
100 | set_task_state(tsk, TASK_INTERRUPTIBLE); | ||
101 | } | ||
102 | |||
103 | out: | ||
104 | tsk->state = TASK_RUNNING; | ||
105 | semtrace(sem, "Leaving __down_interruptible"); | ||
106 | return ret; | ||
107 | |||
108 | interrupted: | ||
109 | spin_lock_irqsave(&sem->wait_lock, flags); | ||
110 | list_del(&waiter.list); | ||
111 | spin_unlock_irqrestore(&sem->wait_lock, flags); | ||
112 | |||
113 | ret = 0; | ||
114 | if (!waiter.task) { | ||
115 | put_task_struct(current); | ||
116 | ret = -EINTR; | ||
117 | } | ||
118 | goto out; | ||
119 | } | ||
120 | EXPORT_SYMBOL(__down_interruptible); | ||
121 | |||
122 | /* | ||
123 | * release a single token back to a semaphore | ||
124 | * - entered with lock held and interrupts disabled | ||
125 | */ | ||
126 | void __up(struct semaphore *sem) | ||
127 | { | ||
128 | struct task_struct *tsk; | ||
129 | struct sem_waiter *waiter; | ||
130 | |||
131 | semtrace(sem, "Entering __up"); | ||
132 | |||
133 | /* grant the token to the process at the front of the queue */ | ||
134 | waiter = list_entry(sem->wait_list.next, struct sem_waiter, list); | ||
135 | |||
136 | /* We must be careful not to touch 'waiter' after we set ->task = NULL. | ||
137 | * It is an allocated on the waiter's stack and may become invalid at | ||
138 | * any time after that point (due to a wakeup from another source). | ||
139 | */ | ||
140 | list_del_init(&waiter->list); | ||
141 | tsk = waiter->task; | ||
142 | smp_mb(); | ||
143 | waiter->task = NULL; | ||
144 | wake_up_process(tsk); | ||
145 | put_task_struct(tsk); | ||
146 | |||
147 | semtrace(sem, "Leaving __up"); | ||
148 | } | ||
149 | EXPORT_SYMBOL(__up); | ||
diff --git a/arch/parisc/kernel/Makefile b/arch/parisc/kernel/Makefile index 27827bc3717e..1f6585a56f97 100644 --- a/arch/parisc/kernel/Makefile +++ b/arch/parisc/kernel/Makefile | |||
@@ -9,7 +9,7 @@ AFLAGS_pacache.o := -traditional | |||
9 | 9 | ||
10 | obj-y := cache.o pacache.o setup.o traps.o time.o irq.o \ | 10 | obj-y := cache.o pacache.o setup.o traps.o time.o irq.o \ |
11 | pa7300lc.o syscall.o entry.o sys_parisc.o firmware.o \ | 11 | pa7300lc.o syscall.o entry.o sys_parisc.o firmware.o \ |
12 | ptrace.o hardware.o inventory.o drivers.o semaphore.o \ | 12 | ptrace.o hardware.o inventory.o drivers.o \ |
13 | signal.o hpmc.o real2.o parisc_ksyms.o unaligned.o \ | 13 | signal.o hpmc.o real2.o parisc_ksyms.o unaligned.o \ |
14 | process.o processor.o pdc_cons.o pdc_chassis.o unwind.o \ | 14 | process.o processor.o pdc_cons.o pdc_chassis.o unwind.o \ |
15 | topology.o | 15 | topology.o |
diff --git a/arch/parisc/kernel/parisc_ksyms.c b/arch/parisc/kernel/parisc_ksyms.c index 7aca704e96f0..5b7fc4aa044d 100644 --- a/arch/parisc/kernel/parisc_ksyms.c +++ b/arch/parisc/kernel/parisc_ksyms.c | |||
@@ -69,11 +69,6 @@ EXPORT_SYMBOL(memcpy_toio); | |||
69 | EXPORT_SYMBOL(memcpy_fromio); | 69 | EXPORT_SYMBOL(memcpy_fromio); |
70 | EXPORT_SYMBOL(memset_io); | 70 | EXPORT_SYMBOL(memset_io); |
71 | 71 | ||
72 | #include <asm/semaphore.h> | ||
73 | EXPORT_SYMBOL(__up); | ||
74 | EXPORT_SYMBOL(__down_interruptible); | ||
75 | EXPORT_SYMBOL(__down); | ||
76 | |||
77 | extern void $$divI(void); | 72 | extern void $$divI(void); |
78 | extern void $$divU(void); | 73 | extern void $$divU(void); |
79 | extern void $$remI(void); | 74 | extern void $$remI(void); |
diff --git a/arch/parisc/kernel/semaphore.c b/arch/parisc/kernel/semaphore.c deleted file mode 100644 index ee806bcc3726..000000000000 --- a/arch/parisc/kernel/semaphore.c +++ /dev/null | |||
@@ -1,102 +0,0 @@ | |||
1 | /* | ||
2 | * Semaphore implementation Copyright (c) 2001 Matthew Wilcox, Hewlett-Packard | ||
3 | */ | ||
4 | |||
5 | #include <linux/sched.h> | ||
6 | #include <linux/spinlock.h> | ||
7 | #include <linux/errno.h> | ||
8 | #include <linux/init.h> | ||
9 | |||
10 | /* | ||
11 | * Semaphores are complex as we wish to avoid using two variables. | ||
12 | * `count' has multiple roles, depending on its value. If it is positive | ||
13 | * or zero, there are no waiters. The functions here will never be | ||
14 | * called; see <asm/semaphore.h> | ||
15 | * | ||
16 | * When count is -1 it indicates there is at least one task waiting | ||
17 | * for the semaphore. | ||
18 | * | ||
19 | * When count is less than that, there are '- count - 1' wakeups | ||
20 | * pending. ie if it has value -3, there are 2 wakeups pending. | ||
21 | * | ||
22 | * Note that these functions are only called when there is contention | ||
23 | * on the lock, and as such all this is the "non-critical" part of the | ||
24 | * whole semaphore business. The critical part is the inline stuff in | ||
25 | * <asm/semaphore.h> where we want to avoid any extra jumps and calls. | ||
26 | */ | ||
27 | void __up(struct semaphore *sem) | ||
28 | { | ||
29 | sem->count--; | ||
30 | wake_up(&sem->wait); | ||
31 | } | ||
32 | |||
33 | #define wakers(count) (-1 - count) | ||
34 | |||
35 | #define DOWN_HEAD \ | ||
36 | int ret = 0; \ | ||
37 | DECLARE_WAITQUEUE(wait, current); \ | ||
38 | \ | ||
39 | /* Note that someone is waiting */ \ | ||
40 | if (sem->count == 0) \ | ||
41 | sem->count = -1; \ | ||
42 | \ | ||
43 | /* protected by the sentry still -- use unlocked version */ \ | ||
44 | wait.flags = WQ_FLAG_EXCLUSIVE; \ | ||
45 | __add_wait_queue_tail(&sem->wait, &wait); \ | ||
46 | lost_race: \ | ||
47 | spin_unlock_irq(&sem->sentry); \ | ||
48 | |||
49 | #define DOWN_TAIL \ | ||
50 | spin_lock_irq(&sem->sentry); \ | ||
51 | if (wakers(sem->count) == 0 && ret == 0) \ | ||
52 | goto lost_race; /* Someone stole our wakeup */ \ | ||
53 | __remove_wait_queue(&sem->wait, &wait); \ | ||
54 | current->state = TASK_RUNNING; \ | ||
55 | if (!waitqueue_active(&sem->wait) && (sem->count < 0)) \ | ||
56 | sem->count = wakers(sem->count); | ||
57 | |||
58 | #define UPDATE_COUNT \ | ||
59 | sem->count += (sem->count < 0) ? 1 : - 1; | ||
60 | |||
61 | |||
62 | void __sched __down(struct semaphore * sem) | ||
63 | { | ||
64 | DOWN_HEAD | ||
65 | |||
66 | for(;;) { | ||
67 | set_task_state(current, TASK_UNINTERRUPTIBLE); | ||
68 | /* we can _read_ this without the sentry */ | ||
69 | if (sem->count != -1) | ||
70 | break; | ||
71 | schedule(); | ||
72 | } | ||
73 | |||
74 | DOWN_TAIL | ||
75 | UPDATE_COUNT | ||
76 | } | ||
77 | |||
78 | int __sched __down_interruptible(struct semaphore * sem) | ||
79 | { | ||
80 | DOWN_HEAD | ||
81 | |||
82 | for(;;) { | ||
83 | set_task_state(current, TASK_INTERRUPTIBLE); | ||
84 | /* we can _read_ this without the sentry */ | ||
85 | if (sem->count != -1) | ||
86 | break; | ||
87 | |||
88 | if (signal_pending(current)) { | ||
89 | ret = -EINTR; | ||
90 | break; | ||
91 | } | ||
92 | schedule(); | ||
93 | } | ||
94 | |||
95 | DOWN_TAIL | ||
96 | |||
97 | if (!ret) { | ||
98 | UPDATE_COUNT | ||
99 | } | ||
100 | |||
101 | return ret; | ||
102 | } | ||
diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile index c1baf9d5903f..b9dbfff9afe9 100644 --- a/arch/powerpc/kernel/Makefile +++ b/arch/powerpc/kernel/Makefile | |||
@@ -12,7 +12,7 @@ CFLAGS_prom_init.o += -fPIC | |||
12 | CFLAGS_btext.o += -fPIC | 12 | CFLAGS_btext.o += -fPIC |
13 | endif | 13 | endif |
14 | 14 | ||
15 | obj-y := semaphore.o cputable.o ptrace.o syscalls.o \ | 15 | obj-y := cputable.o ptrace.o syscalls.o \ |
16 | irq.o align.o signal_32.o pmc.o vdso.o \ | 16 | irq.o align.o signal_32.o pmc.o vdso.o \ |
17 | init_task.o process.o systbl.o idle.o \ | 17 | init_task.o process.o systbl.o idle.o \ |
18 | signal.o | 18 | signal.o |
diff --git a/arch/powerpc/kernel/ppc_ksyms.c b/arch/powerpc/kernel/ppc_ksyms.c index 9c98424277a8..65d14e6ddc3c 100644 --- a/arch/powerpc/kernel/ppc_ksyms.c +++ b/arch/powerpc/kernel/ppc_ksyms.c | |||
@@ -15,7 +15,6 @@ | |||
15 | #include <linux/bitops.h> | 15 | #include <linux/bitops.h> |
16 | 16 | ||
17 | #include <asm/page.h> | 17 | #include <asm/page.h> |
18 | #include <asm/semaphore.h> | ||
19 | #include <asm/processor.h> | 18 | #include <asm/processor.h> |
20 | #include <asm/cacheflush.h> | 19 | #include <asm/cacheflush.h> |
21 | #include <asm/uaccess.h> | 20 | #include <asm/uaccess.h> |
diff --git a/arch/powerpc/kernel/semaphore.c b/arch/powerpc/kernel/semaphore.c deleted file mode 100644 index 2f8c3c951394..000000000000 --- a/arch/powerpc/kernel/semaphore.c +++ /dev/null | |||
@@ -1,135 +0,0 @@ | |||
1 | /* | ||
2 | * PowerPC-specific semaphore code. | ||
3 | * | ||
4 | * Copyright (C) 1999 Cort Dougan <cort@cs.nmt.edu> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or | ||
7 | * modify it under the terms of the GNU General Public License | ||
8 | * as published by the Free Software Foundation; either version | ||
9 | * 2 of the License, or (at your option) any later version. | ||
10 | * | ||
11 | * April 2001 - Reworked by Paul Mackerras <paulus@samba.org> | ||
12 | * to eliminate the SMP races in the old version between the updates | ||
13 | * of `count' and `waking'. Now we use negative `count' values to | ||
14 | * indicate that some process(es) are waiting for the semaphore. | ||
15 | */ | ||
16 | |||
17 | #include <linux/sched.h> | ||
18 | #include <linux/init.h> | ||
19 | #include <linux/module.h> | ||
20 | |||
21 | #include <asm/atomic.h> | ||
22 | #include <asm/semaphore.h> | ||
23 | #include <asm/errno.h> | ||
24 | |||
25 | /* | ||
26 | * Atomically update sem->count. | ||
27 | * This does the equivalent of the following: | ||
28 | * | ||
29 | * old_count = sem->count; | ||
30 | * tmp = MAX(old_count, 0) + incr; | ||
31 | * sem->count = tmp; | ||
32 | * return old_count; | ||
33 | */ | ||
34 | static inline int __sem_update_count(struct semaphore *sem, int incr) | ||
35 | { | ||
36 | int old_count, tmp; | ||
37 | |||
38 | __asm__ __volatile__("\n" | ||
39 | "1: lwarx %0,0,%3\n" | ||
40 | " srawi %1,%0,31\n" | ||
41 | " andc %1,%0,%1\n" | ||
42 | " add %1,%1,%4\n" | ||
43 | PPC405_ERR77(0,%3) | ||
44 | " stwcx. %1,0,%3\n" | ||
45 | " bne 1b" | ||
46 | : "=&r" (old_count), "=&r" (tmp), "=m" (sem->count) | ||
47 | : "r" (&sem->count), "r" (incr), "m" (sem->count) | ||
48 | : "cc"); | ||
49 | |||
50 | return old_count; | ||
51 | } | ||
52 | |||
53 | void __up(struct semaphore *sem) | ||
54 | { | ||
55 | /* | ||
56 | * Note that we incremented count in up() before we came here, | ||
57 | * but that was ineffective since the result was <= 0, and | ||
58 | * any negative value of count is equivalent to 0. | ||
59 | * This ends up setting count to 1, unless count is now > 0 | ||
60 | * (i.e. because some other cpu has called up() in the meantime), | ||
61 | * in which case we just increment count. | ||
62 | */ | ||
63 | __sem_update_count(sem, 1); | ||
64 | wake_up(&sem->wait); | ||
65 | } | ||
66 | EXPORT_SYMBOL(__up); | ||
67 | |||
68 | /* | ||
69 | * Note that when we come in to __down or __down_interruptible, | ||
70 | * we have already decremented count, but that decrement was | ||
71 | * ineffective since the result was < 0, and any negative value | ||
72 | * of count is equivalent to 0. | ||
73 | * Thus it is only when we decrement count from some value > 0 | ||
74 | * that we have actually got the semaphore. | ||
75 | */ | ||
76 | void __sched __down(struct semaphore *sem) | ||
77 | { | ||
78 | struct task_struct *tsk = current; | ||
79 | DECLARE_WAITQUEUE(wait, tsk); | ||
80 | |||
81 | __set_task_state(tsk, TASK_UNINTERRUPTIBLE); | ||
82 | add_wait_queue_exclusive(&sem->wait, &wait); | ||
83 | |||
84 | /* | ||
85 | * Try to get the semaphore. If the count is > 0, then we've | ||
86 | * got the semaphore; we decrement count and exit the loop. | ||
87 | * If the count is 0 or negative, we set it to -1, indicating | ||
88 | * that we are asleep, and then sleep. | ||
89 | */ | ||
90 | while (__sem_update_count(sem, -1) <= 0) { | ||
91 | schedule(); | ||
92 | set_task_state(tsk, TASK_UNINTERRUPTIBLE); | ||
93 | } | ||
94 | remove_wait_queue(&sem->wait, &wait); | ||
95 | __set_task_state(tsk, TASK_RUNNING); | ||
96 | |||
97 | /* | ||
98 | * If there are any more sleepers, wake one of them up so | ||
99 | * that it can either get the semaphore, or set count to -1 | ||
100 | * indicating that there are still processes sleeping. | ||
101 | */ | ||
102 | wake_up(&sem->wait); | ||
103 | } | ||
104 | EXPORT_SYMBOL(__down); | ||
105 | |||
106 | int __sched __down_interruptible(struct semaphore * sem) | ||
107 | { | ||
108 | int retval = 0; | ||
109 | struct task_struct *tsk = current; | ||
110 | DECLARE_WAITQUEUE(wait, tsk); | ||
111 | |||
112 | __set_task_state(tsk, TASK_INTERRUPTIBLE); | ||
113 | add_wait_queue_exclusive(&sem->wait, &wait); | ||
114 | |||
115 | while (__sem_update_count(sem, -1) <= 0) { | ||
116 | if (signal_pending(current)) { | ||
117 | /* | ||
118 | * A signal is pending - give up trying. | ||
119 | * Set sem->count to 0 if it is negative, | ||
120 | * since we are no longer sleeping. | ||
121 | */ | ||
122 | __sem_update_count(sem, 0); | ||
123 | retval = -EINTR; | ||
124 | break; | ||
125 | } | ||
126 | schedule(); | ||
127 | set_task_state(tsk, TASK_INTERRUPTIBLE); | ||
128 | } | ||
129 | remove_wait_queue(&sem->wait, &wait); | ||
130 | __set_task_state(tsk, TASK_RUNNING); | ||
131 | |||
132 | wake_up(&sem->wait); | ||
133 | return retval; | ||
134 | } | ||
135 | EXPORT_SYMBOL(__down_interruptible); | ||
diff --git a/arch/ppc/kernel/semaphore.c b/arch/ppc/kernel/semaphore.c deleted file mode 100644 index 2fe429b27c14..000000000000 --- a/arch/ppc/kernel/semaphore.c +++ /dev/null | |||
@@ -1,131 +0,0 @@ | |||
1 | /* | ||
2 | * PowerPC-specific semaphore code. | ||
3 | * | ||
4 | * Copyright (C) 1999 Cort Dougan <cort@cs.nmt.edu> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or | ||
7 | * modify it under the terms of the GNU General Public License | ||
8 | * as published by the Free Software Foundation; either version | ||
9 | * 2 of the License, or (at your option) any later version. | ||
10 | * | ||
11 | * April 2001 - Reworked by Paul Mackerras <paulus@samba.org> | ||
12 | * to eliminate the SMP races in the old version between the updates | ||
13 | * of `count' and `waking'. Now we use negative `count' values to | ||
14 | * indicate that some process(es) are waiting for the semaphore. | ||
15 | */ | ||
16 | |||
17 | #include <linux/sched.h> | ||
18 | #include <linux/init.h> | ||
19 | #include <asm/atomic.h> | ||
20 | #include <asm/semaphore.h> | ||
21 | #include <asm/errno.h> | ||
22 | |||
23 | /* | ||
24 | * Atomically update sem->count. | ||
25 | * This does the equivalent of the following: | ||
26 | * | ||
27 | * old_count = sem->count; | ||
28 | * tmp = MAX(old_count, 0) + incr; | ||
29 | * sem->count = tmp; | ||
30 | * return old_count; | ||
31 | */ | ||
32 | static inline int __sem_update_count(struct semaphore *sem, int incr) | ||
33 | { | ||
34 | int old_count, tmp; | ||
35 | |||
36 | __asm__ __volatile__("\n" | ||
37 | "1: lwarx %0,0,%3\n" | ||
38 | " srawi %1,%0,31\n" | ||
39 | " andc %1,%0,%1\n" | ||
40 | " add %1,%1,%4\n" | ||
41 | PPC405_ERR77(0,%3) | ||
42 | " stwcx. %1,0,%3\n" | ||
43 | " bne 1b" | ||
44 | : "=&r" (old_count), "=&r" (tmp), "=m" (sem->count) | ||
45 | : "r" (&sem->count), "r" (incr), "m" (sem->count) | ||
46 | : "cc"); | ||
47 | |||
48 | return old_count; | ||
49 | } | ||
50 | |||
51 | void __up(struct semaphore *sem) | ||
52 | { | ||
53 | /* | ||
54 | * Note that we incremented count in up() before we came here, | ||
55 | * but that was ineffective since the result was <= 0, and | ||
56 | * any negative value of count is equivalent to 0. | ||
57 | * This ends up setting count to 1, unless count is now > 0 | ||
58 | * (i.e. because some other cpu has called up() in the meantime), | ||
59 | * in which case we just increment count. | ||
60 | */ | ||
61 | __sem_update_count(sem, 1); | ||
62 | wake_up(&sem->wait); | ||
63 | } | ||
64 | |||
65 | /* | ||
66 | * Note that when we come in to __down or __down_interruptible, | ||
67 | * we have already decremented count, but that decrement was | ||
68 | * ineffective since the result was < 0, and any negative value | ||
69 | * of count is equivalent to 0. | ||
70 | * Thus it is only when we decrement count from some value > 0 | ||
71 | * that we have actually got the semaphore. | ||
72 | */ | ||
73 | void __sched __down(struct semaphore *sem) | ||
74 | { | ||
75 | struct task_struct *tsk = current; | ||
76 | DECLARE_WAITQUEUE(wait, tsk); | ||
77 | |||
78 | tsk->state = TASK_UNINTERRUPTIBLE; | ||
79 | add_wait_queue_exclusive(&sem->wait, &wait); | ||
80 | smp_wmb(); | ||
81 | |||
82 | /* | ||
83 | * Try to get the semaphore. If the count is > 0, then we've | ||
84 | * got the semaphore; we decrement count and exit the loop. | ||
85 | * If the count is 0 or negative, we set it to -1, indicating | ||
86 | * that we are asleep, and then sleep. | ||
87 | */ | ||
88 | while (__sem_update_count(sem, -1) <= 0) { | ||
89 | schedule(); | ||
90 | tsk->state = TASK_UNINTERRUPTIBLE; | ||
91 | } | ||
92 | remove_wait_queue(&sem->wait, &wait); | ||
93 | tsk->state = TASK_RUNNING; | ||
94 | |||
95 | /* | ||
96 | * If there are any more sleepers, wake one of them up so | ||
97 | * that it can either get the semaphore, or set count to -1 | ||
98 | * indicating that there are still processes sleeping. | ||
99 | */ | ||
100 | wake_up(&sem->wait); | ||
101 | } | ||
102 | |||
103 | int __sched __down_interruptible(struct semaphore * sem) | ||
104 | { | ||
105 | int retval = 0; | ||
106 | struct task_struct *tsk = current; | ||
107 | DECLARE_WAITQUEUE(wait, tsk); | ||
108 | |||
109 | tsk->state = TASK_INTERRUPTIBLE; | ||
110 | add_wait_queue_exclusive(&sem->wait, &wait); | ||
111 | smp_wmb(); | ||
112 | |||
113 | while (__sem_update_count(sem, -1) <= 0) { | ||
114 | if (signal_pending(current)) { | ||
115 | /* | ||
116 | * A signal is pending - give up trying. | ||
117 | * Set sem->count to 0 if it is negative, | ||
118 | * since we are no longer sleeping. | ||
119 | */ | ||
120 | __sem_update_count(sem, 0); | ||
121 | retval = -EINTR; | ||
122 | break; | ||
123 | } | ||
124 | schedule(); | ||
125 | tsk->state = TASK_INTERRUPTIBLE; | ||
126 | } | ||
127 | tsk->state = TASK_RUNNING; | ||
128 | remove_wait_queue(&sem->wait, &wait); | ||
129 | wake_up(&sem->wait); | ||
130 | return retval; | ||
131 | } | ||
diff --git a/arch/s390/kernel/Makefile b/arch/s390/kernel/Makefile index ef2b2470c25c..77051cd27925 100644 --- a/arch/s390/kernel/Makefile +++ b/arch/s390/kernel/Makefile | |||
@@ -11,7 +11,7 @@ CFLAGS_smp.o := -Wno-nonnull | |||
11 | 11 | ||
12 | obj-y := bitmap.o traps.o time.o process.o base.o early.o \ | 12 | obj-y := bitmap.o traps.o time.o process.o base.o early.o \ |
13 | setup.o sys_s390.o ptrace.o signal.o cpcmd.o ebcdic.o \ | 13 | setup.o sys_s390.o ptrace.o signal.o cpcmd.o ebcdic.o \ |
14 | semaphore.o s390_ext.o debug.o irq.o ipl.o dis.o diag.o | 14 | s390_ext.o debug.o irq.o ipl.o dis.o diag.o |
15 | 15 | ||
16 | obj-y += $(if $(CONFIG_64BIT),entry64.o,entry.o) | 16 | obj-y += $(if $(CONFIG_64BIT),entry64.o,entry.o) |
17 | obj-y += $(if $(CONFIG_64BIT),reipl64.o,reipl.o) | 17 | obj-y += $(if $(CONFIG_64BIT),reipl64.o,reipl.o) |
diff --git a/arch/s390/kernel/s390_ksyms.c b/arch/s390/kernel/s390_ksyms.c index 7234c737f825..48238a114ce9 100644 --- a/arch/s390/kernel/s390_ksyms.c +++ b/arch/s390/kernel/s390_ksyms.c | |||
@@ -27,13 +27,6 @@ EXPORT_SYMBOL(_zb_findmap); | |||
27 | EXPORT_SYMBOL(_sb_findmap); | 27 | EXPORT_SYMBOL(_sb_findmap); |
28 | 28 | ||
29 | /* | 29 | /* |
30 | * semaphore ops | ||
31 | */ | ||
32 | EXPORT_SYMBOL(__up); | ||
33 | EXPORT_SYMBOL(__down); | ||
34 | EXPORT_SYMBOL(__down_interruptible); | ||
35 | |||
36 | /* | ||
37 | * binfmt_elf loader | 30 | * binfmt_elf loader |
38 | */ | 31 | */ |
39 | extern int dump_fpu (struct pt_regs * regs, s390_fp_regs *fpregs); | 32 | extern int dump_fpu (struct pt_regs * regs, s390_fp_regs *fpregs); |
diff --git a/arch/s390/kernel/semaphore.c b/arch/s390/kernel/semaphore.c deleted file mode 100644 index 191303f6c1d8..000000000000 --- a/arch/s390/kernel/semaphore.c +++ /dev/null | |||
@@ -1,108 +0,0 @@ | |||
1 | /* | ||
2 | * linux/arch/s390/kernel/semaphore.c | ||
3 | * | ||
4 | * S390 version | ||
5 | * Copyright (C) 1998-2000 IBM Corporation | ||
6 | * Author(s): Martin Schwidefsky | ||
7 | * | ||
8 | * Derived from "linux/arch/i386/kernel/semaphore.c | ||
9 | * Copyright (C) 1999, Linus Torvalds | ||
10 | * | ||
11 | */ | ||
12 | #include <linux/sched.h> | ||
13 | #include <linux/errno.h> | ||
14 | #include <linux/init.h> | ||
15 | |||
16 | #include <asm/semaphore.h> | ||
17 | |||
18 | /* | ||
19 | * Atomically update sem->count. Equivalent to: | ||
20 | * old_val = sem->count.counter; | ||
21 | * new_val = ((old_val >= 0) ? old_val : 0) + incr; | ||
22 | * sem->count.counter = new_val; | ||
23 | * return old_val; | ||
24 | */ | ||
25 | static inline int __sem_update_count(struct semaphore *sem, int incr) | ||
26 | { | ||
27 | int old_val, new_val; | ||
28 | |||
29 | asm volatile( | ||
30 | " l %0,0(%3)\n" | ||
31 | "0: ltr %1,%0\n" | ||
32 | " jhe 1f\n" | ||
33 | " lhi %1,0\n" | ||
34 | "1: ar %1,%4\n" | ||
35 | " cs %0,%1,0(%3)\n" | ||
36 | " jl 0b\n" | ||
37 | : "=&d" (old_val), "=&d" (new_val), "=m" (sem->count) | ||
38 | : "a" (&sem->count), "d" (incr), "m" (sem->count) | ||
39 | : "cc"); | ||
40 | return old_val; | ||
41 | } | ||
42 | |||
43 | /* | ||
44 | * The inline function up() incremented count but the result | ||
45 | * was <= 0. This indicates that some process is waiting on | ||
46 | * the semaphore. The semaphore is free and we'll wake the | ||
47 | * first sleeping process, so we set count to 1 unless some | ||
48 | * other cpu has called up in the meantime in which case | ||
49 | * we just increment count by 1. | ||
50 | */ | ||
51 | void __up(struct semaphore *sem) | ||
52 | { | ||
53 | __sem_update_count(sem, 1); | ||
54 | wake_up(&sem->wait); | ||
55 | } | ||
56 | |||
57 | /* | ||
58 | * The inline function down() decremented count and the result | ||
59 | * was < 0. The wait loop will atomically test and update the | ||
60 | * semaphore counter following the rules: | ||
61 | * count > 0: decrement count, wake up queue and exit. | ||
62 | * count <= 0: set count to -1, go to sleep. | ||
63 | */ | ||
64 | void __sched __down(struct semaphore * sem) | ||
65 | { | ||
66 | struct task_struct *tsk = current; | ||
67 | DECLARE_WAITQUEUE(wait, tsk); | ||
68 | |||
69 | __set_task_state(tsk, TASK_UNINTERRUPTIBLE); | ||
70 | add_wait_queue_exclusive(&sem->wait, &wait); | ||
71 | while (__sem_update_count(sem, -1) <= 0) { | ||
72 | schedule(); | ||
73 | set_task_state(tsk, TASK_UNINTERRUPTIBLE); | ||
74 | } | ||
75 | remove_wait_queue(&sem->wait, &wait); | ||
76 | __set_task_state(tsk, TASK_RUNNING); | ||
77 | wake_up(&sem->wait); | ||
78 | } | ||
79 | |||
80 | /* | ||
81 | * Same as __down() with an additional test for signals. | ||
82 | * If a signal is pending the count is updated as follows: | ||
83 | * count > 0: wake up queue and exit. | ||
84 | * count <= 0: set count to 0, wake up queue and exit. | ||
85 | */ | ||
86 | int __sched __down_interruptible(struct semaphore * sem) | ||
87 | { | ||
88 | int retval = 0; | ||
89 | struct task_struct *tsk = current; | ||
90 | DECLARE_WAITQUEUE(wait, tsk); | ||
91 | |||
92 | __set_task_state(tsk, TASK_INTERRUPTIBLE); | ||
93 | add_wait_queue_exclusive(&sem->wait, &wait); | ||
94 | while (__sem_update_count(sem, -1) <= 0) { | ||
95 | if (signal_pending(current)) { | ||
96 | __sem_update_count(sem, 0); | ||
97 | retval = -EINTR; | ||
98 | break; | ||
99 | } | ||
100 | schedule(); | ||
101 | set_task_state(tsk, TASK_INTERRUPTIBLE); | ||
102 | } | ||
103 | remove_wait_queue(&sem->wait, &wait); | ||
104 | __set_task_state(tsk, TASK_RUNNING); | ||
105 | wake_up(&sem->wait); | ||
106 | return retval; | ||
107 | } | ||
108 | |||
diff --git a/arch/sh/kernel/Makefile_32 b/arch/sh/kernel/Makefile_32 index 62bf373266f7..4bbdce36b92b 100644 --- a/arch/sh/kernel/Makefile_32 +++ b/arch/sh/kernel/Makefile_32 | |||
@@ -5,7 +5,7 @@ | |||
5 | extra-y := head_32.o init_task.o vmlinux.lds | 5 | extra-y := head_32.o init_task.o vmlinux.lds |
6 | 6 | ||
7 | obj-y := debugtraps.o io.o io_generic.o irq.o machvec.o process_32.o \ | 7 | obj-y := debugtraps.o io.o io_generic.o irq.o machvec.o process_32.o \ |
8 | ptrace_32.o semaphore.o setup.o signal_32.o sys_sh.o sys_sh32.o \ | 8 | ptrace_32.o setup.o signal_32.o sys_sh.o sys_sh32.o \ |
9 | syscalls_32.o time_32.o topology.o traps.o traps_32.o | 9 | syscalls_32.o time_32.o topology.o traps.o traps_32.o |
10 | 10 | ||
11 | obj-y += cpu/ timers/ | 11 | obj-y += cpu/ timers/ |
diff --git a/arch/sh/kernel/Makefile_64 b/arch/sh/kernel/Makefile_64 index e01283d49cbf..6edf53b93d94 100644 --- a/arch/sh/kernel/Makefile_64 +++ b/arch/sh/kernel/Makefile_64 | |||
@@ -1,7 +1,7 @@ | |||
1 | extra-y := head_64.o init_task.o vmlinux.lds | 1 | extra-y := head_64.o init_task.o vmlinux.lds |
2 | 2 | ||
3 | obj-y := debugtraps.o io.o io_generic.o irq.o machvec.o process_64.o \ | 3 | obj-y := debugtraps.o io.o io_generic.o irq.o machvec.o process_64.o \ |
4 | ptrace_64.o semaphore.o setup.o signal_64.o sys_sh.o sys_sh64.o \ | 4 | ptrace_64.o setup.o signal_64.o sys_sh.o sys_sh64.o \ |
5 | syscalls_64.o time_64.o topology.o traps.o traps_64.o | 5 | syscalls_64.o time_64.o topology.o traps.o traps_64.o |
6 | 6 | ||
7 | obj-y += cpu/ timers/ | 7 | obj-y += cpu/ timers/ |
diff --git a/arch/sh/kernel/semaphore.c b/arch/sh/kernel/semaphore.c deleted file mode 100644 index 184119eeae56..000000000000 --- a/arch/sh/kernel/semaphore.c +++ /dev/null | |||
@@ -1,139 +0,0 @@ | |||
1 | /* | ||
2 | * Just taken from alpha implementation. | ||
3 | * This can't work well, perhaps. | ||
4 | */ | ||
5 | /* | ||
6 | * Generic semaphore code. Buyer beware. Do your own | ||
7 | * specific changes in <asm/semaphore-helper.h> | ||
8 | */ | ||
9 | |||
10 | #include <linux/errno.h> | ||
11 | #include <linux/sched.h> | ||
12 | #include <linux/wait.h> | ||
13 | #include <linux/init.h> | ||
14 | #include <asm/semaphore.h> | ||
15 | #include <asm/semaphore-helper.h> | ||
16 | |||
17 | DEFINE_SPINLOCK(semaphore_wake_lock); | ||
18 | |||
19 | /* | ||
20 | * Semaphores are implemented using a two-way counter: | ||
21 | * The "count" variable is decremented for each process | ||
22 | * that tries to sleep, while the "waking" variable is | ||
23 | * incremented when the "up()" code goes to wake up waiting | ||
24 | * processes. | ||
25 | * | ||
26 | * Notably, the inline "up()" and "down()" functions can | ||
27 | * efficiently test if they need to do any extra work (up | ||
28 | * needs to do something only if count was negative before | ||
29 | * the increment operation. | ||
30 | * | ||
31 | * waking_non_zero() (from asm/semaphore.h) must execute | ||
32 | * atomically. | ||
33 | * | ||
34 | * When __up() is called, the count was negative before | ||
35 | * incrementing it, and we need to wake up somebody. | ||
36 | * | ||
37 | * This routine adds one to the count of processes that need to | ||
38 | * wake up and exit. ALL waiting processes actually wake up but | ||
39 | * only the one that gets to the "waking" field first will gate | ||
40 | * through and acquire the semaphore. The others will go back | ||
41 | * to sleep. | ||
42 | * | ||
43 | * Note that these functions are only called when there is | ||
44 | * contention on the lock, and as such all this is the | ||
45 | * "non-critical" part of the whole semaphore business. The | ||
46 | * critical part is the inline stuff in <asm/semaphore.h> | ||
47 | * where we want to avoid any extra jumps and calls. | ||
48 | */ | ||
49 | void __up(struct semaphore *sem) | ||
50 | { | ||
51 | wake_one_more(sem); | ||
52 | wake_up(&sem->wait); | ||
53 | } | ||
54 | |||
55 | /* | ||
56 | * Perform the "down" function. Return zero for semaphore acquired, | ||
57 | * return negative for signalled out of the function. | ||
58 | * | ||
59 | * If called from __down, the return is ignored and the wait loop is | ||
60 | * not interruptible. This means that a task waiting on a semaphore | ||
61 | * using "down()" cannot be killed until someone does an "up()" on | ||
62 | * the semaphore. | ||
63 | * | ||
64 | * If called from __down_interruptible, the return value gets checked | ||
65 | * upon return. If the return value is negative then the task continues | ||
66 | * with the negative value in the return register (it can be tested by | ||
67 | * the caller). | ||
68 | * | ||
69 | * Either form may be used in conjunction with "up()". | ||
70 | * | ||
71 | */ | ||
72 | |||
73 | #define DOWN_VAR \ | ||
74 | struct task_struct *tsk = current; \ | ||
75 | wait_queue_t wait; \ | ||
76 | init_waitqueue_entry(&wait, tsk); | ||
77 | |||
78 | #define DOWN_HEAD(task_state) \ | ||
79 | \ | ||
80 | \ | ||
81 | tsk->state = (task_state); \ | ||
82 | add_wait_queue(&sem->wait, &wait); \ | ||
83 | \ | ||
84 | /* \ | ||
85 | * Ok, we're set up. sem->count is known to be less than zero \ | ||
86 | * so we must wait. \ | ||
87 | * \ | ||
88 | * We can let go the lock for purposes of waiting. \ | ||
89 | * We re-acquire it after awaking so as to protect \ | ||
90 | * all semaphore operations. \ | ||
91 | * \ | ||
92 | * If "up()" is called before we call waking_non_zero() then \ | ||
93 | * we will catch it right away. If it is called later then \ | ||
94 | * we will have to go through a wakeup cycle to catch it. \ | ||
95 | * \ | ||
96 | * Multiple waiters contend for the semaphore lock to see \ | ||
97 | * who gets to gate through and who has to wait some more. \ | ||
98 | */ \ | ||
99 | for (;;) { | ||
100 | |||
101 | #define DOWN_TAIL(task_state) \ | ||
102 | tsk->state = (task_state); \ | ||
103 | } \ | ||
104 | tsk->state = TASK_RUNNING; \ | ||
105 | remove_wait_queue(&sem->wait, &wait); | ||
106 | |||
107 | void __sched __down(struct semaphore * sem) | ||
108 | { | ||
109 | DOWN_VAR | ||
110 | DOWN_HEAD(TASK_UNINTERRUPTIBLE) | ||
111 | if (waking_non_zero(sem)) | ||
112 | break; | ||
113 | schedule(); | ||
114 | DOWN_TAIL(TASK_UNINTERRUPTIBLE) | ||
115 | } | ||
116 | |||
117 | int __sched __down_interruptible(struct semaphore * sem) | ||
118 | { | ||
119 | int ret = 0; | ||
120 | DOWN_VAR | ||
121 | DOWN_HEAD(TASK_INTERRUPTIBLE) | ||
122 | |||
123 | ret = waking_non_zero_interruptible(sem, tsk); | ||
124 | if (ret) | ||
125 | { | ||
126 | if (ret == 1) | ||
127 | /* ret != 0 only if we get interrupted -arca */ | ||
128 | ret = 0; | ||
129 | break; | ||
130 | } | ||
131 | schedule(); | ||
132 | DOWN_TAIL(TASK_INTERRUPTIBLE) | ||
133 | return ret; | ||
134 | } | ||
135 | |||
136 | int __down_trylock(struct semaphore * sem) | ||
137 | { | ||
138 | return waking_non_zero_trylock(sem); | ||
139 | } | ||
diff --git a/arch/sh/kernel/sh_ksyms_32.c b/arch/sh/kernel/sh_ksyms_32.c index 45bb333fd9ec..6d405462cee8 100644 --- a/arch/sh/kernel/sh_ksyms_32.c +++ b/arch/sh/kernel/sh_ksyms_32.c | |||
@@ -9,7 +9,6 @@ | |||
9 | #include <linux/pci.h> | 9 | #include <linux/pci.h> |
10 | #include <linux/irq.h> | 10 | #include <linux/irq.h> |
11 | #include <asm/sections.h> | 11 | #include <asm/sections.h> |
12 | #include <asm/semaphore.h> | ||
13 | #include <asm/processor.h> | 12 | #include <asm/processor.h> |
14 | #include <asm/uaccess.h> | 13 | #include <asm/uaccess.h> |
15 | #include <asm/checksum.h> | 14 | #include <asm/checksum.h> |
@@ -48,12 +47,6 @@ EXPORT_SYMBOL(__copy_user); | |||
48 | EXPORT_SYMBOL(get_vm_area); | 47 | EXPORT_SYMBOL(get_vm_area); |
49 | #endif | 48 | #endif |
50 | 49 | ||
51 | /* semaphore exports */ | ||
52 | EXPORT_SYMBOL(__up); | ||
53 | EXPORT_SYMBOL(__down); | ||
54 | EXPORT_SYMBOL(__down_interruptible); | ||
55 | EXPORT_SYMBOL(__down_trylock); | ||
56 | |||
57 | EXPORT_SYMBOL(__udelay); | 50 | EXPORT_SYMBOL(__udelay); |
58 | EXPORT_SYMBOL(__ndelay); | 51 | EXPORT_SYMBOL(__ndelay); |
59 | EXPORT_SYMBOL(__const_udelay); | 52 | EXPORT_SYMBOL(__const_udelay); |
diff --git a/arch/sh/kernel/sh_ksyms_64.c b/arch/sh/kernel/sh_ksyms_64.c index b6410ce4bd1d..a310c9707f03 100644 --- a/arch/sh/kernel/sh_ksyms_64.c +++ b/arch/sh/kernel/sh_ksyms_64.c | |||
@@ -16,7 +16,6 @@ | |||
16 | #include <linux/in6.h> | 16 | #include <linux/in6.h> |
17 | #include <linux/interrupt.h> | 17 | #include <linux/interrupt.h> |
18 | #include <linux/screen_info.h> | 18 | #include <linux/screen_info.h> |
19 | #include <asm/semaphore.h> | ||
20 | #include <asm/processor.h> | 19 | #include <asm/processor.h> |
21 | #include <asm/uaccess.h> | 20 | #include <asm/uaccess.h> |
22 | #include <asm/checksum.h> | 21 | #include <asm/checksum.h> |
@@ -37,9 +36,6 @@ EXPORT_SYMBOL(csum_partial_copy_nocheck); | |||
37 | EXPORT_SYMBOL(screen_info); | 36 | EXPORT_SYMBOL(screen_info); |
38 | #endif | 37 | #endif |
39 | 38 | ||
40 | EXPORT_SYMBOL(__down); | ||
41 | EXPORT_SYMBOL(__down_trylock); | ||
42 | EXPORT_SYMBOL(__up); | ||
43 | EXPORT_SYMBOL(__put_user_asm_l); | 39 | EXPORT_SYMBOL(__put_user_asm_l); |
44 | EXPORT_SYMBOL(__get_user_asm_l); | 40 | EXPORT_SYMBOL(__get_user_asm_l); |
45 | EXPORT_SYMBOL(copy_page); | 41 | EXPORT_SYMBOL(copy_page); |
diff --git a/arch/sparc/kernel/Makefile b/arch/sparc/kernel/Makefile index bf1b15d3f6f5..2712bb166f6f 100644 --- a/arch/sparc/kernel/Makefile +++ b/arch/sparc/kernel/Makefile | |||
@@ -12,7 +12,7 @@ obj-y := entry.o wof.o wuf.o etrap.o rtrap.o traps.o $(IRQ_OBJS) \ | |||
12 | sys_sparc.o sunos_asm.o systbls.o \ | 12 | sys_sparc.o sunos_asm.o systbls.o \ |
13 | time.o windows.o cpu.o devices.o sclow.o \ | 13 | time.o windows.o cpu.o devices.o sclow.o \ |
14 | tadpole.o tick14.o ptrace.o sys_solaris.o \ | 14 | tadpole.o tick14.o ptrace.o sys_solaris.o \ |
15 | unaligned.o una_asm.o muldiv.o semaphore.o \ | 15 | unaligned.o una_asm.o muldiv.o \ |
16 | prom.o of_device.o devres.o | 16 | prom.o of_device.o devres.o |
17 | 17 | ||
18 | devres-y = ../../../kernel/irq/devres.o | 18 | devres-y = ../../../kernel/irq/devres.o |
diff --git a/arch/sparc/kernel/semaphore.c b/arch/sparc/kernel/semaphore.c deleted file mode 100644 index 0c37c1a7cd7e..000000000000 --- a/arch/sparc/kernel/semaphore.c +++ /dev/null | |||
@@ -1,155 +0,0 @@ | |||
1 | /* $Id: semaphore.c,v 1.7 2001/04/18 21:06:05 davem Exp $ */ | ||
2 | |||
3 | /* sparc32 semaphore implementation, based on i386 version */ | ||
4 | |||
5 | #include <linux/sched.h> | ||
6 | #include <linux/errno.h> | ||
7 | #include <linux/init.h> | ||
8 | |||
9 | #include <asm/semaphore.h> | ||
10 | |||
11 | /* | ||
12 | * Semaphores are implemented using a two-way counter: | ||
13 | * The "count" variable is decremented for each process | ||
14 | * that tries to acquire the semaphore, while the "sleeping" | ||
15 | * variable is a count of such acquires. | ||
16 | * | ||
17 | * Notably, the inline "up()" and "down()" functions can | ||
18 | * efficiently test if they need to do any extra work (up | ||
19 | * needs to do something only if count was negative before | ||
20 | * the increment operation. | ||
21 | * | ||
22 | * "sleeping" and the contention routine ordering is | ||
23 | * protected by the semaphore spinlock. | ||
24 | * | ||
25 | * Note that these functions are only called when there is | ||
26 | * contention on the lock, and as such all this is the | ||
27 | * "non-critical" part of the whole semaphore business. The | ||
28 | * critical part is the inline stuff in <asm/semaphore.h> | ||
29 | * where we want to avoid any extra jumps and calls. | ||
30 | */ | ||
31 | |||
32 | /* | ||
33 | * Logic: | ||
34 | * - only on a boundary condition do we need to care. When we go | ||
35 | * from a negative count to a non-negative, we wake people up. | ||
36 | * - when we go from a non-negative count to a negative do we | ||
37 | * (a) synchronize with the "sleeper" count and (b) make sure | ||
38 | * that we're on the wakeup list before we synchronize so that | ||
39 | * we cannot lose wakeup events. | ||
40 | */ | ||
41 | |||
42 | void __up(struct semaphore *sem) | ||
43 | { | ||
44 | wake_up(&sem->wait); | ||
45 | } | ||
46 | |||
47 | static DEFINE_SPINLOCK(semaphore_lock); | ||
48 | |||
49 | void __sched __down(struct semaphore * sem) | ||
50 | { | ||
51 | struct task_struct *tsk = current; | ||
52 | DECLARE_WAITQUEUE(wait, tsk); | ||
53 | tsk->state = TASK_UNINTERRUPTIBLE; | ||
54 | add_wait_queue_exclusive(&sem->wait, &wait); | ||
55 | |||
56 | spin_lock_irq(&semaphore_lock); | ||
57 | sem->sleepers++; | ||
58 | for (;;) { | ||
59 | int sleepers = sem->sleepers; | ||
60 | |||
61 | /* | ||
62 | * Add "everybody else" into it. They aren't | ||
63 | * playing, because we own the spinlock. | ||
64 | */ | ||
65 | if (!atomic24_add_negative(sleepers - 1, &sem->count)) { | ||
66 | sem->sleepers = 0; | ||
67 | break; | ||
68 | } | ||
69 | sem->sleepers = 1; /* us - see -1 above */ | ||
70 | spin_unlock_irq(&semaphore_lock); | ||
71 | |||
72 | schedule(); | ||
73 | tsk->state = TASK_UNINTERRUPTIBLE; | ||
74 | spin_lock_irq(&semaphore_lock); | ||
75 | } | ||
76 | spin_unlock_irq(&semaphore_lock); | ||
77 | remove_wait_queue(&sem->wait, &wait); | ||
78 | tsk->state = TASK_RUNNING; | ||
79 | wake_up(&sem->wait); | ||
80 | } | ||
81 | |||
82 | int __sched __down_interruptible(struct semaphore * sem) | ||
83 | { | ||
84 | int retval = 0; | ||
85 | struct task_struct *tsk = current; | ||
86 | DECLARE_WAITQUEUE(wait, tsk); | ||
87 | tsk->state = TASK_INTERRUPTIBLE; | ||
88 | add_wait_queue_exclusive(&sem->wait, &wait); | ||
89 | |||
90 | spin_lock_irq(&semaphore_lock); | ||
91 | sem->sleepers ++; | ||
92 | for (;;) { | ||
93 | int sleepers = sem->sleepers; | ||
94 | |||
95 | /* | ||
96 | * With signals pending, this turns into | ||
97 | * the trylock failure case - we won't be | ||
98 | * sleeping, and we* can't get the lock as | ||
99 | * it has contention. Just correct the count | ||
100 | * and exit. | ||
101 | */ | ||
102 | if (signal_pending(current)) { | ||
103 | retval = -EINTR; | ||
104 | sem->sleepers = 0; | ||
105 | atomic24_add(sleepers, &sem->count); | ||
106 | break; | ||
107 | } | ||
108 | |||
109 | /* | ||
110 | * Add "everybody else" into it. They aren't | ||
111 | * playing, because we own the spinlock. The | ||
112 | * "-1" is because we're still hoping to get | ||
113 | * the lock. | ||
114 | */ | ||
115 | if (!atomic24_add_negative(sleepers - 1, &sem->count)) { | ||
116 | sem->sleepers = 0; | ||
117 | break; | ||
118 | } | ||
119 | sem->sleepers = 1; /* us - see -1 above */ | ||
120 | spin_unlock_irq(&semaphore_lock); | ||
121 | |||
122 | schedule(); | ||
123 | tsk->state = TASK_INTERRUPTIBLE; | ||
124 | spin_lock_irq(&semaphore_lock); | ||
125 | } | ||
126 | spin_unlock_irq(&semaphore_lock); | ||
127 | tsk->state = TASK_RUNNING; | ||
128 | remove_wait_queue(&sem->wait, &wait); | ||
129 | wake_up(&sem->wait); | ||
130 | return retval; | ||
131 | } | ||
132 | |||
133 | /* | ||
134 | * Trylock failed - make sure we correct for | ||
135 | * having decremented the count. | ||
136 | */ | ||
137 | int __down_trylock(struct semaphore * sem) | ||
138 | { | ||
139 | int sleepers; | ||
140 | unsigned long flags; | ||
141 | |||
142 | spin_lock_irqsave(&semaphore_lock, flags); | ||
143 | sleepers = sem->sleepers + 1; | ||
144 | sem->sleepers = 0; | ||
145 | |||
146 | /* | ||
147 | * Add "everybody else" and us into it. They aren't | ||
148 | * playing, because we own the spinlock. | ||
149 | */ | ||
150 | if (!atomic24_add_negative(sleepers, &sem->count)) | ||
151 | wake_up(&sem->wait); | ||
152 | |||
153 | spin_unlock_irqrestore(&semaphore_lock, flags); | ||
154 | return 1; | ||
155 | } | ||
diff --git a/arch/sparc/kernel/sparc_ksyms.c b/arch/sparc/kernel/sparc_ksyms.c index c1025e551650..97b1de0e9094 100644 --- a/arch/sparc/kernel/sparc_ksyms.c +++ b/arch/sparc/kernel/sparc_ksyms.c | |||
@@ -107,11 +107,6 @@ EXPORT_SYMBOL(___rw_read_try); | |||
107 | EXPORT_SYMBOL(___rw_read_exit); | 107 | EXPORT_SYMBOL(___rw_read_exit); |
108 | EXPORT_SYMBOL(___rw_write_enter); | 108 | EXPORT_SYMBOL(___rw_write_enter); |
109 | #endif | 109 | #endif |
110 | /* semaphores */ | ||
111 | EXPORT_SYMBOL(__up); | ||
112 | EXPORT_SYMBOL(__down); | ||
113 | EXPORT_SYMBOL(__down_trylock); | ||
114 | EXPORT_SYMBOL(__down_interruptible); | ||
115 | 110 | ||
116 | EXPORT_SYMBOL(sparc_valid_addr_bitmap); | 111 | EXPORT_SYMBOL(sparc_valid_addr_bitmap); |
117 | EXPORT_SYMBOL(phys_base); | 112 | EXPORT_SYMBOL(phys_base); |
diff --git a/arch/sparc64/kernel/Makefile b/arch/sparc64/kernel/Makefile index 1bf5b187de49..459462e80a12 100644 --- a/arch/sparc64/kernel/Makefile +++ b/arch/sparc64/kernel/Makefile | |||
@@ -10,7 +10,7 @@ extra-y := head.o init_task.o vmlinux.lds | |||
10 | obj-y := process.o setup.o cpu.o idprom.o \ | 10 | obj-y := process.o setup.o cpu.o idprom.o \ |
11 | traps.o auxio.o una_asm.o sysfs.o iommu.o \ | 11 | traps.o auxio.o una_asm.o sysfs.o iommu.o \ |
12 | irq.o ptrace.o time.o sys_sparc.o signal.o \ | 12 | irq.o ptrace.o time.o sys_sparc.o signal.o \ |
13 | unaligned.o central.o pci.o starfire.o semaphore.o \ | 13 | unaligned.o central.o pci.o starfire.o \ |
14 | power.o sbus.o sparc64_ksyms.o chmc.o \ | 14 | power.o sbus.o sparc64_ksyms.o chmc.o \ |
15 | visemul.o prom.o of_device.o hvapi.o sstate.o mdesc.o | 15 | visemul.o prom.o of_device.o hvapi.o sstate.o mdesc.o |
16 | 16 | ||
diff --git a/arch/sparc64/kernel/semaphore.c b/arch/sparc64/kernel/semaphore.c deleted file mode 100644 index 9974a6899551..000000000000 --- a/arch/sparc64/kernel/semaphore.c +++ /dev/null | |||
@@ -1,254 +0,0 @@ | |||
1 | /* semaphore.c: Sparc64 semaphore implementation. | ||
2 | * | ||
3 | * This is basically the PPC semaphore scheme ported to use | ||
4 | * the sparc64 atomic instructions, so see the PPC code for | ||
5 | * credits. | ||
6 | */ | ||
7 | |||
8 | #include <linux/sched.h> | ||
9 | #include <linux/errno.h> | ||
10 | #include <linux/init.h> | ||
11 | |||
12 | /* | ||
13 | * Atomically update sem->count. | ||
14 | * This does the equivalent of the following: | ||
15 | * | ||
16 | * old_count = sem->count; | ||
17 | * tmp = MAX(old_count, 0) + incr; | ||
18 | * sem->count = tmp; | ||
19 | * return old_count; | ||
20 | */ | ||
21 | static inline int __sem_update_count(struct semaphore *sem, int incr) | ||
22 | { | ||
23 | int old_count, tmp; | ||
24 | |||
25 | __asm__ __volatile__("\n" | ||
26 | " ! __sem_update_count old_count(%0) tmp(%1) incr(%4) &sem->count(%3)\n" | ||
27 | "1: ldsw [%3], %0\n" | ||
28 | " mov %0, %1\n" | ||
29 | " cmp %0, 0\n" | ||
30 | " movl %%icc, 0, %1\n" | ||
31 | " add %1, %4, %1\n" | ||
32 | " cas [%3], %0, %1\n" | ||
33 | " cmp %0, %1\n" | ||
34 | " membar #StoreLoad | #StoreStore\n" | ||
35 | " bne,pn %%icc, 1b\n" | ||
36 | " nop\n" | ||
37 | : "=&r" (old_count), "=&r" (tmp), "=m" (sem->count) | ||
38 | : "r" (&sem->count), "r" (incr), "m" (sem->count) | ||
39 | : "cc"); | ||
40 | |||
41 | return old_count; | ||
42 | } | ||
43 | |||
44 | static void __up(struct semaphore *sem) | ||
45 | { | ||
46 | __sem_update_count(sem, 1); | ||
47 | wake_up(&sem->wait); | ||
48 | } | ||
49 | |||
50 | void up(struct semaphore *sem) | ||
51 | { | ||
52 | /* This atomically does: | ||
53 | * old_val = sem->count; | ||
54 | * new_val = sem->count + 1; | ||
55 | * sem->count = new_val; | ||
56 | * if (old_val < 0) | ||
57 | * __up(sem); | ||
58 | * | ||
59 | * The (old_val < 0) test is equivalent to | ||
60 | * the more straightforward (new_val <= 0), | ||
61 | * but it is easier to test the former because | ||
62 | * of how the CAS instruction works. | ||
63 | */ | ||
64 | |||
65 | __asm__ __volatile__("\n" | ||
66 | " ! up sem(%0)\n" | ||
67 | " membar #StoreLoad | #LoadLoad\n" | ||
68 | "1: lduw [%0], %%g1\n" | ||
69 | " add %%g1, 1, %%g7\n" | ||
70 | " cas [%0], %%g1, %%g7\n" | ||
71 | " cmp %%g1, %%g7\n" | ||
72 | " bne,pn %%icc, 1b\n" | ||
73 | " addcc %%g7, 1, %%g0\n" | ||
74 | " membar #StoreLoad | #StoreStore\n" | ||
75 | " ble,pn %%icc, 3f\n" | ||
76 | " nop\n" | ||
77 | "2:\n" | ||
78 | " .subsection 2\n" | ||
79 | "3: mov %0, %%g1\n" | ||
80 | " save %%sp, -160, %%sp\n" | ||
81 | " call %1\n" | ||
82 | " mov %%g1, %%o0\n" | ||
83 | " ba,pt %%xcc, 2b\n" | ||
84 | " restore\n" | ||
85 | " .previous\n" | ||
86 | : : "r" (sem), "i" (__up) | ||
87 | : "g1", "g2", "g3", "g7", "memory", "cc"); | ||
88 | } | ||
89 | |||
90 | static void __sched __down(struct semaphore * sem) | ||
91 | { | ||
92 | struct task_struct *tsk = current; | ||
93 | DECLARE_WAITQUEUE(wait, tsk); | ||
94 | |||
95 | tsk->state = TASK_UNINTERRUPTIBLE; | ||
96 | add_wait_queue_exclusive(&sem->wait, &wait); | ||
97 | |||
98 | while (__sem_update_count(sem, -1) <= 0) { | ||
99 | schedule(); | ||
100 | tsk->state = TASK_UNINTERRUPTIBLE; | ||
101 | } | ||
102 | remove_wait_queue(&sem->wait, &wait); | ||
103 | tsk->state = TASK_RUNNING; | ||
104 | |||
105 | wake_up(&sem->wait); | ||
106 | } | ||
107 | |||
108 | void __sched down(struct semaphore *sem) | ||
109 | { | ||
110 | might_sleep(); | ||
111 | /* This atomically does: | ||
112 | * old_val = sem->count; | ||
113 | * new_val = sem->count - 1; | ||
114 | * sem->count = new_val; | ||
115 | * if (old_val < 1) | ||
116 | * __down(sem); | ||
117 | * | ||
118 | * The (old_val < 1) test is equivalent to | ||
119 | * the more straightforward (new_val < 0), | ||
120 | * but it is easier to test the former because | ||
121 | * of how the CAS instruction works. | ||
122 | */ | ||
123 | |||
124 | __asm__ __volatile__("\n" | ||
125 | " ! down sem(%0)\n" | ||
126 | "1: lduw [%0], %%g1\n" | ||
127 | " sub %%g1, 1, %%g7\n" | ||
128 | " cas [%0], %%g1, %%g7\n" | ||
129 | " cmp %%g1, %%g7\n" | ||
130 | " bne,pn %%icc, 1b\n" | ||
131 | " cmp %%g7, 1\n" | ||
132 | " membar #StoreLoad | #StoreStore\n" | ||
133 | " bl,pn %%icc, 3f\n" | ||
134 | " nop\n" | ||
135 | "2:\n" | ||
136 | " .subsection 2\n" | ||
137 | "3: mov %0, %%g1\n" | ||
138 | " save %%sp, -160, %%sp\n" | ||
139 | " call %1\n" | ||
140 | " mov %%g1, %%o0\n" | ||
141 | " ba,pt %%xcc, 2b\n" | ||
142 | " restore\n" | ||
143 | " .previous\n" | ||
144 | : : "r" (sem), "i" (__down) | ||
145 | : "g1", "g2", "g3", "g7", "memory", "cc"); | ||
146 | } | ||
147 | |||
148 | int down_trylock(struct semaphore *sem) | ||
149 | { | ||
150 | int ret; | ||
151 | |||
152 | /* This atomically does: | ||
153 | * old_val = sem->count; | ||
154 | * new_val = sem->count - 1; | ||
155 | * if (old_val < 1) { | ||
156 | * ret = 1; | ||
157 | * } else { | ||
158 | * sem->count = new_val; | ||
159 | * ret = 0; | ||
160 | * } | ||
161 | * | ||
162 | * The (old_val < 1) test is equivalent to | ||
163 | * the more straightforward (new_val < 0), | ||
164 | * but it is easier to test the former because | ||
165 | * of how the CAS instruction works. | ||
166 | */ | ||
167 | |||
168 | __asm__ __volatile__("\n" | ||
169 | " ! down_trylock sem(%1) ret(%0)\n" | ||
170 | "1: lduw [%1], %%g1\n" | ||
171 | " sub %%g1, 1, %%g7\n" | ||
172 | " cmp %%g1, 1\n" | ||
173 | " bl,pn %%icc, 2f\n" | ||
174 | " mov 1, %0\n" | ||
175 | " cas [%1], %%g1, %%g7\n" | ||
176 | " cmp %%g1, %%g7\n" | ||
177 | " bne,pn %%icc, 1b\n" | ||
178 | " mov 0, %0\n" | ||
179 | " membar #StoreLoad | #StoreStore\n" | ||
180 | "2:\n" | ||
181 | : "=&r" (ret) | ||
182 | : "r" (sem) | ||
183 | : "g1", "g7", "memory", "cc"); | ||
184 | |||
185 | return ret; | ||
186 | } | ||
187 | |||
188 | static int __sched __down_interruptible(struct semaphore * sem) | ||
189 | { | ||
190 | int retval = 0; | ||
191 | struct task_struct *tsk = current; | ||
192 | DECLARE_WAITQUEUE(wait, tsk); | ||
193 | |||
194 | tsk->state = TASK_INTERRUPTIBLE; | ||
195 | add_wait_queue_exclusive(&sem->wait, &wait); | ||
196 | |||
197 | while (__sem_update_count(sem, -1) <= 0) { | ||
198 | if (signal_pending(current)) { | ||
199 | __sem_update_count(sem, 0); | ||
200 | retval = -EINTR; | ||
201 | break; | ||
202 | } | ||
203 | schedule(); | ||
204 | tsk->state = TASK_INTERRUPTIBLE; | ||
205 | } | ||
206 | tsk->state = TASK_RUNNING; | ||
207 | remove_wait_queue(&sem->wait, &wait); | ||
208 | wake_up(&sem->wait); | ||
209 | return retval; | ||
210 | } | ||
211 | |||
212 | int __sched down_interruptible(struct semaphore *sem) | ||
213 | { | ||
214 | int ret = 0; | ||
215 | |||
216 | might_sleep(); | ||
217 | /* This atomically does: | ||
218 | * old_val = sem->count; | ||
219 | * new_val = sem->count - 1; | ||
220 | * sem->count = new_val; | ||
221 | * if (old_val < 1) | ||
222 | * ret = __down_interruptible(sem); | ||
223 | * | ||
224 | * The (old_val < 1) test is equivalent to | ||
225 | * the more straightforward (new_val < 0), | ||
226 | * but it is easier to test the former because | ||
227 | * of how the CAS instruction works. | ||
228 | */ | ||
229 | |||
230 | __asm__ __volatile__("\n" | ||
231 | " ! down_interruptible sem(%2) ret(%0)\n" | ||
232 | "1: lduw [%2], %%g1\n" | ||
233 | " sub %%g1, 1, %%g7\n" | ||
234 | " cas [%2], %%g1, %%g7\n" | ||
235 | " cmp %%g1, %%g7\n" | ||
236 | " bne,pn %%icc, 1b\n" | ||
237 | " cmp %%g7, 1\n" | ||
238 | " membar #StoreLoad | #StoreStore\n" | ||
239 | " bl,pn %%icc, 3f\n" | ||
240 | " nop\n" | ||
241 | "2:\n" | ||
242 | " .subsection 2\n" | ||
243 | "3: mov %2, %%g1\n" | ||
244 | " save %%sp, -160, %%sp\n" | ||
245 | " call %3\n" | ||
246 | " mov %%g1, %%o0\n" | ||
247 | " ba,pt %%xcc, 2b\n" | ||
248 | " restore\n" | ||
249 | " .previous\n" | ||
250 | : "=r" (ret) | ||
251 | : "0" (ret), "r" (sem), "i" (__down_interruptible) | ||
252 | : "g1", "g2", "g3", "g7", "memory", "cc"); | ||
253 | return ret; | ||
254 | } | ||
diff --git a/arch/sparc64/kernel/sparc64_ksyms.c b/arch/sparc64/kernel/sparc64_ksyms.c index 51fa773f38c9..051b8d9cb989 100644 --- a/arch/sparc64/kernel/sparc64_ksyms.c +++ b/arch/sparc64/kernel/sparc64_ksyms.c | |||
@@ -130,12 +130,6 @@ EXPORT_SYMBOL(_mcount); | |||
130 | 130 | ||
131 | EXPORT_SYMBOL(sparc64_get_clock_tick); | 131 | EXPORT_SYMBOL(sparc64_get_clock_tick); |
132 | 132 | ||
133 | /* semaphores */ | ||
134 | EXPORT_SYMBOL(down); | ||
135 | EXPORT_SYMBOL(down_trylock); | ||
136 | EXPORT_SYMBOL(down_interruptible); | ||
137 | EXPORT_SYMBOL(up); | ||
138 | |||
139 | /* RW semaphores */ | 133 | /* RW semaphores */ |
140 | EXPORT_SYMBOL(__down_read); | 134 | EXPORT_SYMBOL(__down_read); |
141 | EXPORT_SYMBOL(__down_read_trylock); | 135 | EXPORT_SYMBOL(__down_read_trylock); |
diff --git a/arch/um/Kconfig.i386 b/arch/um/Kconfig.i386 index 3cd8a04d66d8..e09edfa560da 100644 --- a/arch/um/Kconfig.i386 +++ b/arch/um/Kconfig.i386 | |||
@@ -19,10 +19,6 @@ config 64BIT | |||
19 | bool | 19 | bool |
20 | default n | 20 | default n |
21 | 21 | ||
22 | config SEMAPHORE_SLEEPERS | ||
23 | bool | ||
24 | default y | ||
25 | |||
26 | config 3_LEVEL_PGTABLES | 22 | config 3_LEVEL_PGTABLES |
27 | bool "Three-level pagetables (EXPERIMENTAL)" | 23 | bool "Three-level pagetables (EXPERIMENTAL)" |
28 | default n | 24 | default n |
diff --git a/arch/um/Kconfig.x86_64 b/arch/um/Kconfig.x86_64 index 6533b349f061..3fbe69e359ed 100644 --- a/arch/um/Kconfig.x86_64 +++ b/arch/um/Kconfig.x86_64 | |||
@@ -11,10 +11,6 @@ config RWSEM_GENERIC_SPINLOCK | |||
11 | bool | 11 | bool |
12 | default y | 12 | default y |
13 | 13 | ||
14 | config SEMAPHORE_SLEEPERS | ||
15 | bool | ||
16 | default y | ||
17 | |||
18 | config 3_LEVEL_PGTABLES | 14 | config 3_LEVEL_PGTABLES |
19 | bool | 15 | bool |
20 | default y | 16 | default y |
diff --git a/arch/um/sys-i386/ksyms.c b/arch/um/sys-i386/ksyms.c index 2a1eac1859ce..bfbefd30db8f 100644 --- a/arch/um/sys-i386/ksyms.c +++ b/arch/um/sys-i386/ksyms.c | |||
@@ -1,17 +1,5 @@ | |||
1 | #include "linux/module.h" | 1 | #include "linux/module.h" |
2 | #include "linux/in6.h" | ||
3 | #include "linux/rwsem.h" | ||
4 | #include "asm/byteorder.h" | ||
5 | #include "asm/delay.h" | ||
6 | #include "asm/semaphore.h" | ||
7 | #include "asm/uaccess.h" | ||
8 | #include "asm/checksum.h" | 2 | #include "asm/checksum.h" |
9 | #include "asm/errno.h" | ||
10 | |||
11 | EXPORT_SYMBOL(__down_failed); | ||
12 | EXPORT_SYMBOL(__down_failed_interruptible); | ||
13 | EXPORT_SYMBOL(__down_failed_trylock); | ||
14 | EXPORT_SYMBOL(__up_wakeup); | ||
15 | 3 | ||
16 | /* Networking helper routines. */ | 4 | /* Networking helper routines. */ |
17 | EXPORT_SYMBOL(csum_partial); | 5 | EXPORT_SYMBOL(csum_partial); |
diff --git a/arch/um/sys-ppc/Makefile b/arch/um/sys-ppc/Makefile index 08901526e893..b8bc844fd2c4 100644 --- a/arch/um/sys-ppc/Makefile +++ b/arch/um/sys-ppc/Makefile | |||
@@ -3,7 +3,7 @@ OBJ = built-in.o | |||
3 | .S.o: | 3 | .S.o: |
4 | $(CC) $(KBUILD_AFLAGS) -D__ASSEMBLY__ -D__UM_PPC__ -c $< -o $*.o | 4 | $(CC) $(KBUILD_AFLAGS) -D__ASSEMBLY__ -D__UM_PPC__ -c $< -o $*.o |
5 | 5 | ||
6 | OBJS = ptrace.o sigcontext.o semaphore.o checksum.o miscthings.o misc.o \ | 6 | OBJS = ptrace.o sigcontext.o checksum.o miscthings.o misc.o \ |
7 | ptrace_user.o sysrq.o | 7 | ptrace_user.o sysrq.o |
8 | 8 | ||
9 | EXTRA_AFLAGS := -DCONFIG_PPC32 -I. -I$(srctree)/arch/ppc/kernel | 9 | EXTRA_AFLAGS := -DCONFIG_PPC32 -I. -I$(srctree)/arch/ppc/kernel |
@@ -20,10 +20,6 @@ ptrace_user.o: ptrace_user.c | |||
20 | sigcontext.o: sigcontext.c | 20 | sigcontext.o: sigcontext.c |
21 | $(CC) $(USER_CFLAGS) $(EXTRA_CFLAGS) -c -o $@ $< | 21 | $(CC) $(USER_CFLAGS) $(EXTRA_CFLAGS) -c -o $@ $< |
22 | 22 | ||
23 | semaphore.c: | ||
24 | rm -f $@ | ||
25 | ln -s $(srctree)/arch/ppc/kernel/$@ $@ | ||
26 | |||
27 | checksum.S: | 23 | checksum.S: |
28 | rm -f $@ | 24 | rm -f $@ |
29 | ln -s $(srctree)/arch/ppc/lib/$@ $@ | 25 | ln -s $(srctree)/arch/ppc/lib/$@ $@ |
@@ -66,4 +62,4 @@ misc.o: misc.S ppc_defs.h | |||
66 | $(CC) $(EXTRA_AFLAGS) $(KBUILD_AFLAGS) -D__ASSEMBLY__ -D__UM_PPC__ -c $< -o $*.o | 62 | $(CC) $(EXTRA_AFLAGS) $(KBUILD_AFLAGS) -D__ASSEMBLY__ -D__UM_PPC__ -c $< -o $*.o |
67 | rm -f asm | 63 | rm -f asm |
68 | 64 | ||
69 | clean-files := $(OBJS) ppc_defs.h checksum.S semaphore.c mk_defs.c | 65 | clean-files := $(OBJS) ppc_defs.h checksum.S mk_defs.c |
diff --git a/arch/um/sys-x86_64/ksyms.c b/arch/um/sys-x86_64/ksyms.c index 12c593607c59..4d7d1a812d8f 100644 --- a/arch/um/sys-x86_64/ksyms.c +++ b/arch/um/sys-x86_64/ksyms.c | |||
@@ -1,16 +1,5 @@ | |||
1 | #include "linux/module.h" | 1 | #include "linux/module.h" |
2 | #include "linux/in6.h" | 2 | #include "asm/string.h" |
3 | #include "linux/rwsem.h" | ||
4 | #include "asm/byteorder.h" | ||
5 | #include "asm/semaphore.h" | ||
6 | #include "asm/uaccess.h" | ||
7 | #include "asm/checksum.h" | ||
8 | #include "asm/errno.h" | ||
9 | |||
10 | EXPORT_SYMBOL(__down_failed); | ||
11 | EXPORT_SYMBOL(__down_failed_interruptible); | ||
12 | EXPORT_SYMBOL(__down_failed_trylock); | ||
13 | EXPORT_SYMBOL(__up_wakeup); | ||
14 | 3 | ||
15 | /*XXX: we need them because they would be exported by x86_64 */ | 4 | /*XXX: we need them because they would be exported by x86_64 */ |
16 | EXPORT_SYMBOL(__memcpy); | 5 | EXPORT_SYMBOL(__memcpy); |
diff --git a/arch/v850/kernel/Makefile b/arch/v850/kernel/Makefile index 3930482bddc4..da5889c53576 100644 --- a/arch/v850/kernel/Makefile +++ b/arch/v850/kernel/Makefile | |||
@@ -11,7 +11,7 @@ | |||
11 | 11 | ||
12 | extra-y := head.o init_task.o vmlinux.lds | 12 | extra-y := head.o init_task.o vmlinux.lds |
13 | 13 | ||
14 | obj-y += intv.o entry.o process.o syscalls.o time.o semaphore.o setup.o \ | 14 | obj-y += intv.o entry.o process.o syscalls.o time.o setup.o \ |
15 | signal.o irq.o mach.o ptrace.o bug.o | 15 | signal.o irq.o mach.o ptrace.o bug.o |
16 | obj-$(CONFIG_MODULES) += module.o v850_ksyms.o | 16 | obj-$(CONFIG_MODULES) += module.o v850_ksyms.o |
17 | # chip-specific code | 17 | # chip-specific code |
diff --git a/arch/v850/kernel/semaphore.c b/arch/v850/kernel/semaphore.c deleted file mode 100644 index fc89fd661c99..000000000000 --- a/arch/v850/kernel/semaphore.c +++ /dev/null | |||
@@ -1,166 +0,0 @@ | |||
1 | /* | ||
2 | * arch/v850/kernel/semaphore.c -- Semaphore support | ||
3 | * | ||
4 | * Copyright (C) 1998-2000 IBM Corporation | ||
5 | * Copyright (C) 1999 Linus Torvalds | ||
6 | * | ||
7 | * This file is subject to the terms and conditions of the GNU General | ||
8 | * Public License. See the file COPYING in the main directory of this | ||
9 | * archive for more details. | ||
10 | * | ||
11 | * This file is a copy of the s390 version, arch/s390/kernel/semaphore.c | ||
12 | * Author(s): Martin Schwidefsky | ||
13 | * which was derived from the i386 version, linux/arch/i386/kernel/semaphore.c | ||
14 | */ | ||
15 | |||
16 | #include <linux/errno.h> | ||
17 | #include <linux/sched.h> | ||
18 | #include <linux/init.h> | ||
19 | |||
20 | #include <asm/semaphore.h> | ||
21 | |||
22 | /* | ||
23 | * Semaphores are implemented using a two-way counter: | ||
24 | * The "count" variable is decremented for each process | ||
25 | * that tries to acquire the semaphore, while the "sleeping" | ||
26 | * variable is a count of such acquires. | ||
27 | * | ||
28 | * Notably, the inline "up()" and "down()" functions can | ||
29 | * efficiently test if they need to do any extra work (up | ||
30 | * needs to do something only if count was negative before | ||
31 | * the increment operation. | ||
32 | * | ||
33 | * "sleeping" and the contention routine ordering is | ||
34 | * protected by the semaphore spinlock. | ||
35 | * | ||
36 | * Note that these functions are only called when there is | ||
37 | * contention on the lock, and as such all this is the | ||
38 | * "non-critical" part of the whole semaphore business. The | ||
39 | * critical part is the inline stuff in <asm/semaphore.h> | ||
40 | * where we want to avoid any extra jumps and calls. | ||
41 | */ | ||
42 | |||
43 | /* | ||
44 | * Logic: | ||
45 | * - only on a boundary condition do we need to care. When we go | ||
46 | * from a negative count to a non-negative, we wake people up. | ||
47 | * - when we go from a non-negative count to a negative do we | ||
48 | * (a) synchronize with the "sleeper" count and (b) make sure | ||
49 | * that we're on the wakeup list before we synchronize so that | ||
50 | * we cannot lose wakeup events. | ||
51 | */ | ||
52 | |||
53 | void __up(struct semaphore *sem) | ||
54 | { | ||
55 | wake_up(&sem->wait); | ||
56 | } | ||
57 | |||
58 | static DEFINE_SPINLOCK(semaphore_lock); | ||
59 | |||
60 | void __sched __down(struct semaphore * sem) | ||
61 | { | ||
62 | struct task_struct *tsk = current; | ||
63 | DECLARE_WAITQUEUE(wait, tsk); | ||
64 | tsk->state = TASK_UNINTERRUPTIBLE; | ||
65 | add_wait_queue_exclusive(&sem->wait, &wait); | ||
66 | |||
67 | spin_lock_irq(&semaphore_lock); | ||
68 | sem->sleepers++; | ||
69 | for (;;) { | ||
70 | int sleepers = sem->sleepers; | ||
71 | |||
72 | /* | ||
73 | * Add "everybody else" into it. They aren't | ||
74 | * playing, because we own the spinlock. | ||
75 | */ | ||
76 | if (!atomic_add_negative(sleepers - 1, &sem->count)) { | ||
77 | sem->sleepers = 0; | ||
78 | break; | ||
79 | } | ||
80 | sem->sleepers = 1; /* us - see -1 above */ | ||
81 | spin_unlock_irq(&semaphore_lock); | ||
82 | |||
83 | schedule(); | ||
84 | tsk->state = TASK_UNINTERRUPTIBLE; | ||
85 | spin_lock_irq(&semaphore_lock); | ||
86 | } | ||
87 | spin_unlock_irq(&semaphore_lock); | ||
88 | remove_wait_queue(&sem->wait, &wait); | ||
89 | tsk->state = TASK_RUNNING; | ||
90 | wake_up(&sem->wait); | ||
91 | } | ||
92 | |||
93 | int __sched __down_interruptible(struct semaphore * sem) | ||
94 | { | ||
95 | int retval = 0; | ||
96 | struct task_struct *tsk = current; | ||
97 | DECLARE_WAITQUEUE(wait, tsk); | ||
98 | tsk->state = TASK_INTERRUPTIBLE; | ||
99 | add_wait_queue_exclusive(&sem->wait, &wait); | ||
100 | |||
101 | spin_lock_irq(&semaphore_lock); | ||
102 | sem->sleepers ++; | ||
103 | for (;;) { | ||
104 | int sleepers = sem->sleepers; | ||
105 | |||
106 | /* | ||
107 | * With signals pending, this turns into | ||
108 | * the trylock failure case - we won't be | ||
109 | * sleeping, and we* can't get the lock as | ||
110 | * it has contention. Just correct the count | ||
111 | * and exit. | ||
112 | */ | ||
113 | if (signal_pending(current)) { | ||
114 | retval = -EINTR; | ||
115 | sem->sleepers = 0; | ||
116 | atomic_add(sleepers, &sem->count); | ||
117 | break; | ||
118 | } | ||
119 | |||
120 | /* | ||
121 | * Add "everybody else" into it. They aren't | ||
122 | * playing, because we own the spinlock. The | ||
123 | * "-1" is because we're still hoping to get | ||
124 | * the lock. | ||
125 | */ | ||
126 | if (!atomic_add_negative(sleepers - 1, &sem->count)) { | ||
127 | sem->sleepers = 0; | ||
128 | break; | ||
129 | } | ||
130 | sem->sleepers = 1; /* us - see -1 above */ | ||
131 | spin_unlock_irq(&semaphore_lock); | ||
132 | |||
133 | schedule(); | ||
134 | tsk->state = TASK_INTERRUPTIBLE; | ||
135 | spin_lock_irq(&semaphore_lock); | ||
136 | } | ||
137 | spin_unlock_irq(&semaphore_lock); | ||
138 | tsk->state = TASK_RUNNING; | ||
139 | remove_wait_queue(&sem->wait, &wait); | ||
140 | wake_up(&sem->wait); | ||
141 | return retval; | ||
142 | } | ||
143 | |||
144 | /* | ||
145 | * Trylock failed - make sure we correct for | ||
146 | * having decremented the count. | ||
147 | */ | ||
148 | int __down_trylock(struct semaphore * sem) | ||
149 | { | ||
150 | unsigned long flags; | ||
151 | int sleepers; | ||
152 | |||
153 | spin_lock_irqsave(&semaphore_lock, flags); | ||
154 | sleepers = sem->sleepers + 1; | ||
155 | sem->sleepers = 0; | ||
156 | |||
157 | /* | ||
158 | * Add "everybody else" and us into it. They aren't | ||
159 | * playing, because we own the spinlock. | ||
160 | */ | ||
161 | if (!atomic_add_negative(sleepers, &sem->count)) | ||
162 | wake_up(&sem->wait); | ||
163 | |||
164 | spin_unlock_irqrestore(&semaphore_lock, flags); | ||
165 | return 1; | ||
166 | } | ||
diff --git a/arch/v850/kernel/v850_ksyms.c b/arch/v850/kernel/v850_ksyms.c index 93575fdc874d..8d386a5dbc4a 100644 --- a/arch/v850/kernel/v850_ksyms.c +++ b/arch/v850/kernel/v850_ksyms.c | |||
@@ -11,7 +11,6 @@ | |||
11 | #include <asm/pgalloc.h> | 11 | #include <asm/pgalloc.h> |
12 | #include <asm/irq.h> | 12 | #include <asm/irq.h> |
13 | #include <asm/io.h> | 13 | #include <asm/io.h> |
14 | #include <asm/semaphore.h> | ||
15 | #include <asm/checksum.h> | 14 | #include <asm/checksum.h> |
16 | #include <asm/current.h> | 15 | #include <asm/current.h> |
17 | 16 | ||
@@ -34,12 +33,6 @@ EXPORT_SYMBOL (memset); | |||
34 | EXPORT_SYMBOL (memcpy); | 33 | EXPORT_SYMBOL (memcpy); |
35 | EXPORT_SYMBOL (memmove); | 34 | EXPORT_SYMBOL (memmove); |
36 | 35 | ||
37 | /* semaphores */ | ||
38 | EXPORT_SYMBOL (__down); | ||
39 | EXPORT_SYMBOL (__down_interruptible); | ||
40 | EXPORT_SYMBOL (__down_trylock); | ||
41 | EXPORT_SYMBOL (__up); | ||
42 | |||
43 | /* | 36 | /* |
44 | * libgcc functions - functions that are used internally by the | 37 | * libgcc functions - functions that are used internally by the |
45 | * compiler... (prototypes are not correct though, but that | 38 | * compiler... (prototypes are not correct though, but that |
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index 6c70fed0f9a0..e4b38861ea52 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig | |||
@@ -53,9 +53,6 @@ config STACKTRACE_SUPPORT | |||
53 | config HAVE_LATENCYTOP_SUPPORT | 53 | config HAVE_LATENCYTOP_SUPPORT |
54 | def_bool y | 54 | def_bool y |
55 | 55 | ||
56 | config SEMAPHORE_SLEEPERS | ||
57 | def_bool y | ||
58 | |||
59 | config FAST_CMPXCHG_LOCAL | 56 | config FAST_CMPXCHG_LOCAL |
60 | bool | 57 | bool |
61 | default y | 58 | default y |
diff --git a/arch/x86/kernel/i386_ksyms_32.c b/arch/x86/kernel/i386_ksyms_32.c index 061627806a2d..deb43785e923 100644 --- a/arch/x86/kernel/i386_ksyms_32.c +++ b/arch/x86/kernel/i386_ksyms_32.c | |||
@@ -1,13 +1,8 @@ | |||
1 | #include <linux/module.h> | 1 | #include <linux/module.h> |
2 | #include <asm/semaphore.h> | ||
3 | #include <asm/checksum.h> | 2 | #include <asm/checksum.h> |
4 | #include <asm/desc.h> | 3 | #include <asm/desc.h> |
5 | #include <asm/pgtable.h> | 4 | #include <asm/pgtable.h> |
6 | 5 | ||
7 | EXPORT_SYMBOL(__down_failed); | ||
8 | EXPORT_SYMBOL(__down_failed_interruptible); | ||
9 | EXPORT_SYMBOL(__down_failed_trylock); | ||
10 | EXPORT_SYMBOL(__up_wakeup); | ||
11 | /* Networking helper routines. */ | 6 | /* Networking helper routines. */ |
12 | EXPORT_SYMBOL(csum_partial_copy_generic); | 7 | EXPORT_SYMBOL(csum_partial_copy_generic); |
13 | 8 | ||
diff --git a/arch/x86/kernel/x8664_ksyms_64.c b/arch/x86/kernel/x8664_ksyms_64.c index a66e9c1a0537..95a993e18165 100644 --- a/arch/x86/kernel/x8664_ksyms_64.c +++ b/arch/x86/kernel/x8664_ksyms_64.c | |||
@@ -4,7 +4,6 @@ | |||
4 | #include <linux/module.h> | 4 | #include <linux/module.h> |
5 | #include <linux/smp.h> | 5 | #include <linux/smp.h> |
6 | 6 | ||
7 | #include <asm/semaphore.h> | ||
8 | #include <asm/processor.h> | 7 | #include <asm/processor.h> |
9 | #include <asm/uaccess.h> | 8 | #include <asm/uaccess.h> |
10 | #include <asm/pgtable.h> | 9 | #include <asm/pgtable.h> |
@@ -12,11 +11,6 @@ | |||
12 | 11 | ||
13 | EXPORT_SYMBOL(kernel_thread); | 12 | EXPORT_SYMBOL(kernel_thread); |
14 | 13 | ||
15 | EXPORT_SYMBOL(__down_failed); | ||
16 | EXPORT_SYMBOL(__down_failed_interruptible); | ||
17 | EXPORT_SYMBOL(__down_failed_trylock); | ||
18 | EXPORT_SYMBOL(__up_wakeup); | ||
19 | |||
20 | EXPORT_SYMBOL(__get_user_1); | 14 | EXPORT_SYMBOL(__get_user_1); |
21 | EXPORT_SYMBOL(__get_user_2); | 15 | EXPORT_SYMBOL(__get_user_2); |
22 | EXPORT_SYMBOL(__get_user_4); | 16 | EXPORT_SYMBOL(__get_user_4); |
diff --git a/arch/x86/lib/semaphore_32.S b/arch/x86/lib/semaphore_32.S index 3899bd37fdf0..648fe4741782 100644 --- a/arch/x86/lib/semaphore_32.S +++ b/arch/x86/lib/semaphore_32.S | |||
@@ -30,89 +30,6 @@ | |||
30 | * value or just clobbered.. | 30 | * value or just clobbered.. |
31 | */ | 31 | */ |
32 | .section .sched.text, "ax" | 32 | .section .sched.text, "ax" |
33 | ENTRY(__down_failed) | ||
34 | CFI_STARTPROC | ||
35 | FRAME | ||
36 | pushl %edx | ||
37 | CFI_ADJUST_CFA_OFFSET 4 | ||
38 | CFI_REL_OFFSET edx,0 | ||
39 | pushl %ecx | ||
40 | CFI_ADJUST_CFA_OFFSET 4 | ||
41 | CFI_REL_OFFSET ecx,0 | ||
42 | call __down | ||
43 | popl %ecx | ||
44 | CFI_ADJUST_CFA_OFFSET -4 | ||
45 | CFI_RESTORE ecx | ||
46 | popl %edx | ||
47 | CFI_ADJUST_CFA_OFFSET -4 | ||
48 | CFI_RESTORE edx | ||
49 | ENDFRAME | ||
50 | ret | ||
51 | CFI_ENDPROC | ||
52 | ENDPROC(__down_failed) | ||
53 | |||
54 | ENTRY(__down_failed_interruptible) | ||
55 | CFI_STARTPROC | ||
56 | FRAME | ||
57 | pushl %edx | ||
58 | CFI_ADJUST_CFA_OFFSET 4 | ||
59 | CFI_REL_OFFSET edx,0 | ||
60 | pushl %ecx | ||
61 | CFI_ADJUST_CFA_OFFSET 4 | ||
62 | CFI_REL_OFFSET ecx,0 | ||
63 | call __down_interruptible | ||
64 | popl %ecx | ||
65 | CFI_ADJUST_CFA_OFFSET -4 | ||
66 | CFI_RESTORE ecx | ||
67 | popl %edx | ||
68 | CFI_ADJUST_CFA_OFFSET -4 | ||
69 | CFI_RESTORE edx | ||
70 | ENDFRAME | ||
71 | ret | ||
72 | CFI_ENDPROC | ||
73 | ENDPROC(__down_failed_interruptible) | ||
74 | |||
75 | ENTRY(__down_failed_trylock) | ||
76 | CFI_STARTPROC | ||
77 | FRAME | ||
78 | pushl %edx | ||
79 | CFI_ADJUST_CFA_OFFSET 4 | ||
80 | CFI_REL_OFFSET edx,0 | ||
81 | pushl %ecx | ||
82 | CFI_ADJUST_CFA_OFFSET 4 | ||
83 | CFI_REL_OFFSET ecx,0 | ||
84 | call __down_trylock | ||
85 | popl %ecx | ||
86 | CFI_ADJUST_CFA_OFFSET -4 | ||
87 | CFI_RESTORE ecx | ||
88 | popl %edx | ||
89 | CFI_ADJUST_CFA_OFFSET -4 | ||
90 | CFI_RESTORE edx | ||
91 | ENDFRAME | ||
92 | ret | ||
93 | CFI_ENDPROC | ||
94 | ENDPROC(__down_failed_trylock) | ||
95 | |||
96 | ENTRY(__up_wakeup) | ||
97 | CFI_STARTPROC | ||
98 | FRAME | ||
99 | pushl %edx | ||
100 | CFI_ADJUST_CFA_OFFSET 4 | ||
101 | CFI_REL_OFFSET edx,0 | ||
102 | pushl %ecx | ||
103 | CFI_ADJUST_CFA_OFFSET 4 | ||
104 | CFI_REL_OFFSET ecx,0 | ||
105 | call __up | ||
106 | popl %ecx | ||
107 | CFI_ADJUST_CFA_OFFSET -4 | ||
108 | CFI_RESTORE ecx | ||
109 | popl %edx | ||
110 | CFI_ADJUST_CFA_OFFSET -4 | ||
111 | CFI_RESTORE edx | ||
112 | ENDFRAME | ||
113 | ret | ||
114 | CFI_ENDPROC | ||
115 | ENDPROC(__up_wakeup) | ||
116 | 33 | ||
117 | /* | 34 | /* |
118 | * rw spinlock fallbacks | 35 | * rw spinlock fallbacks |
diff --git a/arch/x86/lib/thunk_64.S b/arch/x86/lib/thunk_64.S index 8b92d428ab02..e009251d4e9f 100644 --- a/arch/x86/lib/thunk_64.S +++ b/arch/x86/lib/thunk_64.S | |||
@@ -41,11 +41,6 @@ | |||
41 | thunk rwsem_downgrade_thunk,rwsem_downgrade_wake | 41 | thunk rwsem_downgrade_thunk,rwsem_downgrade_wake |
42 | #endif | 42 | #endif |
43 | 43 | ||
44 | thunk __down_failed,__down | ||
45 | thunk_retrax __down_failed_interruptible,__down_interruptible | ||
46 | thunk_retrax __down_failed_trylock,__down_trylock | ||
47 | thunk __up_wakeup,__up | ||
48 | |||
49 | #ifdef CONFIG_TRACE_IRQFLAGS | 44 | #ifdef CONFIG_TRACE_IRQFLAGS |
50 | thunk trace_hardirqs_on_thunk,trace_hardirqs_on | 45 | thunk trace_hardirqs_on_thunk,trace_hardirqs_on |
51 | thunk trace_hardirqs_off_thunk,trace_hardirqs_off | 46 | thunk trace_hardirqs_off_thunk,trace_hardirqs_off |
diff --git a/arch/xtensa/kernel/Makefile b/arch/xtensa/kernel/Makefile index f582d6a24ec2..7419dbccf027 100644 --- a/arch/xtensa/kernel/Makefile +++ b/arch/xtensa/kernel/Makefile | |||
@@ -5,7 +5,7 @@ | |||
5 | extra-y := head.o vmlinux.lds | 5 | extra-y := head.o vmlinux.lds |
6 | 6 | ||
7 | 7 | ||
8 | obj-y := align.o entry.o irq.o coprocessor.o process.o ptrace.o semaphore.o \ | 8 | obj-y := align.o entry.o irq.o coprocessor.o process.o ptrace.o \ |
9 | setup.o signal.o syscall.o time.o traps.o vectors.o platform.o \ | 9 | setup.o signal.o syscall.o time.o traps.o vectors.o platform.o \ |
10 | pci-dma.o init_task.o io.o | 10 | pci-dma.o init_task.o io.o |
11 | 11 | ||
diff --git a/arch/xtensa/kernel/semaphore.c b/arch/xtensa/kernel/semaphore.c deleted file mode 100644 index 995c6410ae10..000000000000 --- a/arch/xtensa/kernel/semaphore.c +++ /dev/null | |||
@@ -1,226 +0,0 @@ | |||
1 | /* | ||
2 | * arch/xtensa/kernel/semaphore.c | ||
3 | * | ||
4 | * Generic semaphore code. Buyer beware. Do your own specific changes | ||
5 | * in <asm/semaphore-helper.h> | ||
6 | * | ||
7 | * This file is subject to the terms and conditions of the GNU General Public | ||
8 | * License. See the file "COPYING" in the main directory of this archive | ||
9 | * for more details. | ||
10 | * | ||
11 | * Copyright (C) 2001 - 2005 Tensilica Inc. | ||
12 | * | ||
13 | * Joe Taylor <joe@tensilica.com, joetylr@yahoo.com> | ||
14 | * Chris Zankel <chris@zankel.net> | ||
15 | * Marc Gauthier<marc@tensilica.com, marc@alumni.uwaterloo.ca> | ||
16 | * Kevin Chea | ||
17 | */ | ||
18 | |||
19 | #include <linux/sched.h> | ||
20 | #include <linux/wait.h> | ||
21 | #include <linux/init.h> | ||
22 | #include <asm/semaphore.h> | ||
23 | #include <asm/errno.h> | ||
24 | |||
25 | /* | ||
26 | * These two _must_ execute atomically wrt each other. | ||
27 | */ | ||
28 | |||
29 | static __inline__ void wake_one_more(struct semaphore * sem) | ||
30 | { | ||
31 | atomic_inc((atomic_t *)&sem->sleepers); | ||
32 | } | ||
33 | |||
34 | static __inline__ int waking_non_zero(struct semaphore *sem) | ||
35 | { | ||
36 | unsigned long flags; | ||
37 | int ret = 0; | ||
38 | |||
39 | spin_lock_irqsave(&semaphore_wake_lock, flags); | ||
40 | if (sem->sleepers > 0) { | ||
41 | sem->sleepers--; | ||
42 | ret = 1; | ||
43 | } | ||
44 | spin_unlock_irqrestore(&semaphore_wake_lock, flags); | ||
45 | return ret; | ||
46 | } | ||
47 | |||
48 | /* | ||
49 | * waking_non_zero_interruptible: | ||
50 | * 1 got the lock | ||
51 | * 0 go to sleep | ||
52 | * -EINTR interrupted | ||
53 | * | ||
54 | * We must undo the sem->count down_interruptible() increment while we are | ||
55 | * protected by the spinlock in order to make atomic this atomic_inc() with the | ||
56 | * atomic_read() in wake_one_more(), otherwise we can race. -arca | ||
57 | */ | ||
58 | |||
59 | static __inline__ int waking_non_zero_interruptible(struct semaphore *sem, | ||
60 | struct task_struct *tsk) | ||
61 | { | ||
62 | unsigned long flags; | ||
63 | int ret = 0; | ||
64 | |||
65 | spin_lock_irqsave(&semaphore_wake_lock, flags); | ||
66 | if (sem->sleepers > 0) { | ||
67 | sem->sleepers--; | ||
68 | ret = 1; | ||
69 | } else if (signal_pending(tsk)) { | ||
70 | atomic_inc(&sem->count); | ||
71 | ret = -EINTR; | ||
72 | } | ||
73 | spin_unlock_irqrestore(&semaphore_wake_lock, flags); | ||
74 | return ret; | ||
75 | } | ||
76 | |||
77 | /* | ||
78 | * waking_non_zero_trylock: | ||
79 | * 1 failed to lock | ||
80 | * 0 got the lock | ||
81 | * | ||
82 | * We must undo the sem->count down_trylock() increment while we are | ||
83 | * protected by the spinlock in order to make atomic this atomic_inc() with the | ||
84 | * atomic_read() in wake_one_more(), otherwise we can race. -arca | ||
85 | */ | ||
86 | |||
87 | static __inline__ int waking_non_zero_trylock(struct semaphore *sem) | ||
88 | { | ||
89 | unsigned long flags; | ||
90 | int ret = 1; | ||
91 | |||
92 | spin_lock_irqsave(&semaphore_wake_lock, flags); | ||
93 | if (sem->sleepers <= 0) | ||
94 | atomic_inc(&sem->count); | ||
95 | else { | ||
96 | sem->sleepers--; | ||
97 | ret = 0; | ||
98 | } | ||
99 | spin_unlock_irqrestore(&semaphore_wake_lock, flags); | ||
100 | return ret; | ||
101 | } | ||
102 | |||
103 | DEFINE_SPINLOCK(semaphore_wake_lock); | ||
104 | |||
105 | /* | ||
106 | * Semaphores are implemented using a two-way counter: | ||
107 | * The "count" variable is decremented for each process | ||
108 | * that tries to sleep, while the "waking" variable is | ||
109 | * incremented when the "up()" code goes to wake up waiting | ||
110 | * processes. | ||
111 | * | ||
112 | * Notably, the inline "up()" and "down()" functions can | ||
113 | * efficiently test if they need to do any extra work (up | ||
114 | * needs to do something only if count was negative before | ||
115 | * the increment operation. | ||
116 | * | ||
117 | * waking_non_zero() (from asm/semaphore.h) must execute | ||
118 | * atomically. | ||
119 | * | ||
120 | * When __up() is called, the count was negative before | ||
121 | * incrementing it, and we need to wake up somebody. | ||
122 | * | ||
123 | * This routine adds one to the count of processes that need to | ||
124 | * wake up and exit. ALL waiting processes actually wake up but | ||
125 | * only the one that gets to the "waking" field first will gate | ||
126 | * through and acquire the semaphore. The others will go back | ||
127 | * to sleep. | ||
128 | * | ||
129 | * Note that these functions are only called when there is | ||
130 | * contention on the lock, and as such all this is the | ||
131 | * "non-critical" part of the whole semaphore business. The | ||
132 | * critical part is the inline stuff in <asm/semaphore.h> | ||
133 | * where we want to avoid any extra jumps and calls. | ||
134 | */ | ||
135 | |||
136 | void __up(struct semaphore *sem) | ||
137 | { | ||
138 | wake_one_more(sem); | ||
139 | wake_up(&sem->wait); | ||
140 | } | ||
141 | |||
142 | /* | ||
143 | * Perform the "down" function. Return zero for semaphore acquired, | ||
144 | * return negative for signalled out of the function. | ||
145 | * | ||
146 | * If called from __down, the return is ignored and the wait loop is | ||
147 | * not interruptible. This means that a task waiting on a semaphore | ||
148 | * using "down()" cannot be killed until someone does an "up()" on | ||
149 | * the semaphore. | ||
150 | * | ||
151 | * If called from __down_interruptible, the return value gets checked | ||
152 | * upon return. If the return value is negative then the task continues | ||
153 | * with the negative value in the return register (it can be tested by | ||
154 | * the caller). | ||
155 | * | ||
156 | * Either form may be used in conjunction with "up()". | ||
157 | * | ||
158 | */ | ||
159 | |||
160 | #define DOWN_VAR \ | ||
161 | struct task_struct *tsk = current; \ | ||
162 | wait_queue_t wait; \ | ||
163 | init_waitqueue_entry(&wait, tsk); | ||
164 | |||
165 | #define DOWN_HEAD(task_state) \ | ||
166 | \ | ||
167 | \ | ||
168 | tsk->state = (task_state); \ | ||
169 | add_wait_queue(&sem->wait, &wait); \ | ||
170 | \ | ||
171 | /* \ | ||
172 | * Ok, we're set up. sem->count is known to be less than zero \ | ||
173 | * so we must wait. \ | ||
174 | * \ | ||
175 | * We can let go the lock for purposes of waiting. \ | ||
176 | * We re-acquire it after awaking so as to protect \ | ||
177 | * all semaphore operations. \ | ||
178 | * \ | ||
179 | * If "up()" is called before we call waking_non_zero() then \ | ||
180 | * we will catch it right away. If it is called later then \ | ||
181 | * we will have to go through a wakeup cycle to catch it. \ | ||
182 | * \ | ||
183 | * Multiple waiters contend for the semaphore lock to see \ | ||
184 | * who gets to gate through and who has to wait some more. \ | ||
185 | */ \ | ||
186 | for (;;) { | ||
187 | |||
188 | #define DOWN_TAIL(task_state) \ | ||
189 | tsk->state = (task_state); \ | ||
190 | } \ | ||
191 | tsk->state = TASK_RUNNING; \ | ||
192 | remove_wait_queue(&sem->wait, &wait); | ||
193 | |||
194 | void __sched __down(struct semaphore * sem) | ||
195 | { | ||
196 | DOWN_VAR | ||
197 | DOWN_HEAD(TASK_UNINTERRUPTIBLE) | ||
198 | if (waking_non_zero(sem)) | ||
199 | break; | ||
200 | schedule(); | ||
201 | DOWN_TAIL(TASK_UNINTERRUPTIBLE) | ||
202 | } | ||
203 | |||
204 | int __sched __down_interruptible(struct semaphore * sem) | ||
205 | { | ||
206 | int ret = 0; | ||
207 | DOWN_VAR | ||
208 | DOWN_HEAD(TASK_INTERRUPTIBLE) | ||
209 | |||
210 | ret = waking_non_zero_interruptible(sem, tsk); | ||
211 | if (ret) | ||
212 | { | ||
213 | if (ret == 1) | ||
214 | /* ret != 0 only if we get interrupted -arca */ | ||
215 | ret = 0; | ||
216 | break; | ||
217 | } | ||
218 | schedule(); | ||
219 | DOWN_TAIL(TASK_INTERRUPTIBLE) | ||
220 | return ret; | ||
221 | } | ||
222 | |||
223 | int __down_trylock(struct semaphore * sem) | ||
224 | { | ||
225 | return waking_non_zero_trylock(sem); | ||
226 | } | ||
diff --git a/arch/xtensa/kernel/xtensa_ksyms.c b/arch/xtensa/kernel/xtensa_ksyms.c index 60dbdb43fb4c..6e52cdd6166f 100644 --- a/arch/xtensa/kernel/xtensa_ksyms.c +++ b/arch/xtensa/kernel/xtensa_ksyms.c | |||
@@ -26,7 +26,6 @@ | |||
26 | #include <asm/io.h> | 26 | #include <asm/io.h> |
27 | #include <asm/page.h> | 27 | #include <asm/page.h> |
28 | #include <asm/pgalloc.h> | 28 | #include <asm/pgalloc.h> |
29 | #include <asm/semaphore.h> | ||
30 | #ifdef CONFIG_BLK_DEV_FD | 29 | #ifdef CONFIG_BLK_DEV_FD |
31 | #include <asm/floppy.h> | 30 | #include <asm/floppy.h> |
32 | #endif | 31 | #endif |
@@ -71,14 +70,6 @@ EXPORT_SYMBOL(__umodsi3); | |||
71 | EXPORT_SYMBOL(__udivdi3); | 70 | EXPORT_SYMBOL(__udivdi3); |
72 | EXPORT_SYMBOL(__umoddi3); | 71 | EXPORT_SYMBOL(__umoddi3); |
73 | 72 | ||
74 | /* | ||
75 | * Semaphore operations | ||
76 | */ | ||
77 | EXPORT_SYMBOL(__down); | ||
78 | EXPORT_SYMBOL(__down_interruptible); | ||
79 | EXPORT_SYMBOL(__down_trylock); | ||
80 | EXPORT_SYMBOL(__up); | ||
81 | |||
82 | #ifdef CONFIG_NET | 73 | #ifdef CONFIG_NET |
83 | /* | 74 | /* |
84 | * Networking support | 75 | * Networking support |
diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c index a697fb6cf050..a498a6cc68fe 100644 --- a/drivers/acpi/osl.c +++ b/drivers/acpi/osl.c | |||
@@ -4,6 +4,8 @@ | |||
4 | * Copyright (C) 2000 Andrew Henroid | 4 | * Copyright (C) 2000 Andrew Henroid |
5 | * Copyright (C) 2001, 2002 Andy Grover <andrew.grover@intel.com> | 5 | * Copyright (C) 2001, 2002 Andy Grover <andrew.grover@intel.com> |
6 | * Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com> | 6 | * Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com> |
7 | * Copyright (c) 2008 Intel Corporation | ||
8 | * Author: Matthew Wilcox <willy@linux.intel.com> | ||
7 | * | 9 | * |
8 | * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | 10 | * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
9 | * | 11 | * |
@@ -37,15 +39,18 @@ | |||
37 | #include <linux/workqueue.h> | 39 | #include <linux/workqueue.h> |
38 | #include <linux/nmi.h> | 40 | #include <linux/nmi.h> |
39 | #include <linux/acpi.h> | 41 | #include <linux/acpi.h> |
40 | #include <acpi/acpi.h> | ||
41 | #include <asm/io.h> | ||
42 | #include <acpi/acpi_bus.h> | ||
43 | #include <acpi/processor.h> | ||
44 | #include <asm/uaccess.h> | ||
45 | |||
46 | #include <linux/efi.h> | 42 | #include <linux/efi.h> |
47 | #include <linux/ioport.h> | 43 | #include <linux/ioport.h> |
48 | #include <linux/list.h> | 44 | #include <linux/list.h> |
45 | #include <linux/jiffies.h> | ||
46 | #include <linux/semaphore.h> | ||
47 | |||
48 | #include <asm/io.h> | ||
49 | #include <asm/uaccess.h> | ||
50 | |||
51 | #include <acpi/acpi.h> | ||
52 | #include <acpi/acpi_bus.h> | ||
53 | #include <acpi/processor.h> | ||
49 | 54 | ||
50 | #define _COMPONENT ACPI_OS_SERVICES | 55 | #define _COMPONENT ACPI_OS_SERVICES |
51 | ACPI_MODULE_NAME("osl"); | 56 | ACPI_MODULE_NAME("osl"); |
@@ -764,7 +769,6 @@ acpi_os_create_semaphore(u32 max_units, u32 initial_units, acpi_handle * handle) | |||
764 | { | 769 | { |
765 | struct semaphore *sem = NULL; | 770 | struct semaphore *sem = NULL; |
766 | 771 | ||
767 | |||
768 | sem = acpi_os_allocate(sizeof(struct semaphore)); | 772 | sem = acpi_os_allocate(sizeof(struct semaphore)); |
769 | if (!sem) | 773 | if (!sem) |
770 | return AE_NO_MEMORY; | 774 | return AE_NO_MEMORY; |
@@ -791,12 +795,12 @@ acpi_status acpi_os_delete_semaphore(acpi_handle handle) | |||
791 | { | 795 | { |
792 | struct semaphore *sem = (struct semaphore *)handle; | 796 | struct semaphore *sem = (struct semaphore *)handle; |
793 | 797 | ||
794 | |||
795 | if (!sem) | 798 | if (!sem) |
796 | return AE_BAD_PARAMETER; | 799 | return AE_BAD_PARAMETER; |
797 | 800 | ||
798 | ACPI_DEBUG_PRINT((ACPI_DB_MUTEX, "Deleting semaphore[%p].\n", handle)); | 801 | ACPI_DEBUG_PRINT((ACPI_DB_MUTEX, "Deleting semaphore[%p].\n", handle)); |
799 | 802 | ||
803 | BUG_ON(!list_empty(&sem->wait_list)); | ||
800 | kfree(sem); | 804 | kfree(sem); |
801 | sem = NULL; | 805 | sem = NULL; |
802 | 806 | ||
@@ -804,21 +808,15 @@ acpi_status acpi_os_delete_semaphore(acpi_handle handle) | |||
804 | } | 808 | } |
805 | 809 | ||
806 | /* | 810 | /* |
807 | * TODO: The kernel doesn't have a 'down_timeout' function -- had to | ||
808 | * improvise. The process is to sleep for one scheduler quantum | ||
809 | * until the semaphore becomes available. Downside is that this | ||
810 | * may result in starvation for timeout-based waits when there's | ||
811 | * lots of semaphore activity. | ||
812 | * | ||
813 | * TODO: Support for units > 1? | 811 | * TODO: Support for units > 1? |
814 | */ | 812 | */ |
815 | acpi_status acpi_os_wait_semaphore(acpi_handle handle, u32 units, u16 timeout) | 813 | acpi_status acpi_os_wait_semaphore(acpi_handle handle, u32 units, u16 timeout) |
816 | { | 814 | { |
817 | acpi_status status = AE_OK; | 815 | acpi_status status = AE_OK; |
818 | struct semaphore *sem = (struct semaphore *)handle; | 816 | struct semaphore *sem = (struct semaphore *)handle; |
817 | long jiffies; | ||
819 | int ret = 0; | 818 | int ret = 0; |
820 | 819 | ||
821 | |||
822 | if (!sem || (units < 1)) | 820 | if (!sem || (units < 1)) |
823 | return AE_BAD_PARAMETER; | 821 | return AE_BAD_PARAMETER; |
824 | 822 | ||
@@ -828,58 +826,14 @@ acpi_status acpi_os_wait_semaphore(acpi_handle handle, u32 units, u16 timeout) | |||
828 | ACPI_DEBUG_PRINT((ACPI_DB_MUTEX, "Waiting for semaphore[%p|%d|%d]\n", | 826 | ACPI_DEBUG_PRINT((ACPI_DB_MUTEX, "Waiting for semaphore[%p|%d|%d]\n", |
829 | handle, units, timeout)); | 827 | handle, units, timeout)); |
830 | 828 | ||
831 | /* | 829 | if (timeout == ACPI_WAIT_FOREVER) |
832 | * This can be called during resume with interrupts off. | 830 | jiffies = MAX_SCHEDULE_TIMEOUT; |
833 | * Like boot-time, we should be single threaded and will | 831 | else |
834 | * always get the lock if we try -- timeout or not. | 832 | jiffies = msecs_to_jiffies(timeout); |
835 | * If this doesn't succeed, then we will oops courtesy of | 833 | |
836 | * might_sleep() in down(). | 834 | ret = down_timeout(sem, jiffies); |
837 | */ | 835 | if (ret) |
838 | if (!down_trylock(sem)) | 836 | status = AE_TIME; |
839 | return AE_OK; | ||
840 | |||
841 | switch (timeout) { | ||
842 | /* | ||
843 | * No Wait: | ||
844 | * -------- | ||
845 | * A zero timeout value indicates that we shouldn't wait - just | ||
846 | * acquire the semaphore if available otherwise return AE_TIME | ||
847 | * (a.k.a. 'would block'). | ||
848 | */ | ||
849 | case 0: | ||
850 | if (down_trylock(sem)) | ||
851 | status = AE_TIME; | ||
852 | break; | ||
853 | |||
854 | /* | ||
855 | * Wait Indefinitely: | ||
856 | * ------------------ | ||
857 | */ | ||
858 | case ACPI_WAIT_FOREVER: | ||
859 | down(sem); | ||
860 | break; | ||
861 | |||
862 | /* | ||
863 | * Wait w/ Timeout: | ||
864 | * ---------------- | ||
865 | */ | ||
866 | default: | ||
867 | // TODO: A better timeout algorithm? | ||
868 | { | ||
869 | int i = 0; | ||
870 | static const int quantum_ms = 1000 / HZ; | ||
871 | |||
872 | ret = down_trylock(sem); | ||
873 | for (i = timeout; (i > 0 && ret != 0); i -= quantum_ms) { | ||
874 | schedule_timeout_interruptible(1); | ||
875 | ret = down_trylock(sem); | ||
876 | } | ||
877 | |||
878 | if (ret != 0) | ||
879 | status = AE_TIME; | ||
880 | } | ||
881 | break; | ||
882 | } | ||
883 | 837 | ||
884 | if (ACPI_FAILURE(status)) { | 838 | if (ACPI_FAILURE(status)) { |
885 | ACPI_DEBUG_PRINT((ACPI_DB_MUTEX, | 839 | ACPI_DEBUG_PRINT((ACPI_DB_MUTEX, |
@@ -902,7 +856,6 @@ acpi_status acpi_os_signal_semaphore(acpi_handle handle, u32 units) | |||
902 | { | 856 | { |
903 | struct semaphore *sem = (struct semaphore *)handle; | 857 | struct semaphore *sem = (struct semaphore *)handle; |
904 | 858 | ||
905 | |||
906 | if (!sem || (units < 1)) | 859 | if (!sem || (units < 1)) |
907 | return AE_BAD_PARAMETER; | 860 | return AE_BAD_PARAMETER; |
908 | 861 | ||
diff --git a/include/asm-alpha/semaphore.h b/include/asm-alpha/semaphore.h index f1e9278a9fe2..d9b2034ed1d2 100644 --- a/include/asm-alpha/semaphore.h +++ b/include/asm-alpha/semaphore.h | |||
@@ -1,149 +1 @@ | |||
1 | #ifndef _ALPHA_SEMAPHORE_H | #include <linux/semaphore.h> | |
2 | #define _ALPHA_SEMAPHORE_H | ||
3 | |||
4 | /* | ||
5 | * SMP- and interrupt-safe semaphores.. | ||
6 | * | ||
7 | * (C) Copyright 1996 Linus Torvalds | ||
8 | * (C) Copyright 1996, 2000 Richard Henderson | ||
9 | */ | ||
10 | |||
11 | #include <asm/current.h> | ||
12 | #include <asm/system.h> | ||
13 | #include <asm/atomic.h> | ||
14 | #include <linux/compiler.h> | ||
15 | #include <linux/wait.h> | ||
16 | #include <linux/rwsem.h> | ||
17 | |||
18 | struct semaphore { | ||
19 | atomic_t count; | ||
20 | wait_queue_head_t wait; | ||
21 | }; | ||
22 | |||
23 | #define __SEMAPHORE_INITIALIZER(name, n) \ | ||
24 | { \ | ||
25 | .count = ATOMIC_INIT(n), \ | ||
26 | .wait = __WAIT_QUEUE_HEAD_INITIALIZER((name).wait), \ | ||
27 | } | ||
28 | |||
29 | #define __DECLARE_SEMAPHORE_GENERIC(name,count) \ | ||
30 | struct semaphore name = __SEMAPHORE_INITIALIZER(name,count) | ||
31 | |||
32 | #define DECLARE_MUTEX(name) __DECLARE_SEMAPHORE_GENERIC(name,1) | ||
33 | |||
34 | static inline void sema_init(struct semaphore *sem, int val) | ||
35 | { | ||
36 | /* | ||
37 | * Logically, | ||
38 | * *sem = (struct semaphore)__SEMAPHORE_INITIALIZER((*sem),val); | ||
39 | * except that gcc produces better initializing by parts yet. | ||
40 | */ | ||
41 | |||
42 | atomic_set(&sem->count, val); | ||
43 | init_waitqueue_head(&sem->wait); | ||
44 | } | ||
45 | |||
46 | static inline void init_MUTEX (struct semaphore *sem) | ||
47 | { | ||
48 | sema_init(sem, 1); | ||
49 | } | ||
50 | |||
51 | static inline void init_MUTEX_LOCKED (struct semaphore *sem) | ||
52 | { | ||
53 | sema_init(sem, 0); | ||
54 | } | ||
55 | |||
56 | extern void down(struct semaphore *); | ||
57 | extern void __down_failed(struct semaphore *); | ||
58 | extern int down_interruptible(struct semaphore *); | ||
59 | extern int __down_failed_interruptible(struct semaphore *); | ||
60 | extern int down_trylock(struct semaphore *); | ||
61 | extern void up(struct semaphore *); | ||
62 | extern void __up_wakeup(struct semaphore *); | ||
63 | |||
64 | /* | ||
65 | * Hidden out of line code is fun, but extremely messy. Rely on newer | ||
66 | * compilers to do a respectable job with this. The contention cases | ||
67 | * are handled out of line in arch/alpha/kernel/semaphore.c. | ||
68 | */ | ||
69 | |||
70 | static inline void __down(struct semaphore *sem) | ||
71 | { | ||
72 | long count; | ||
73 | might_sleep(); | ||
74 | count = atomic_dec_return(&sem->count); | ||
75 | if (unlikely(count < 0)) | ||
76 | __down_failed(sem); | ||
77 | } | ||
78 | |||
79 | static inline int __down_interruptible(struct semaphore *sem) | ||
80 | { | ||
81 | long count; | ||
82 | might_sleep(); | ||
83 | count = atomic_dec_return(&sem->count); | ||
84 | if (unlikely(count < 0)) | ||
85 | return __down_failed_interruptible(sem); | ||
86 | return 0; | ||
87 | } | ||
88 | |||
89 | /* | ||
90 | * down_trylock returns 0 on success, 1 if we failed to get the lock. | ||
91 | */ | ||
92 | |||
93 | static inline int __down_trylock(struct semaphore *sem) | ||
94 | { | ||
95 | long ret; | ||
96 | |||
97 | /* "Equivalent" C: | ||
98 | |||
99 | do { | ||
100 | ret = ldl_l; | ||
101 | --ret; | ||
102 | if (ret < 0) | ||
103 | break; | ||
104 | ret = stl_c = ret; | ||
105 | } while (ret == 0); | ||
106 | */ | ||
107 | __asm__ __volatile__( | ||
108 | "1: ldl_l %0,%1\n" | ||
109 | " subl %0,1,%0\n" | ||
110 | " blt %0,2f\n" | ||
111 | " stl_c %0,%1\n" | ||
112 | " beq %0,3f\n" | ||
113 | " mb\n" | ||
114 | "2:\n" | ||
115 | ".subsection 2\n" | ||
116 | "3: br 1b\n" | ||
117 | ".previous" | ||
118 | : "=&r" (ret), "=m" (sem->count) | ||
119 | : "m" (sem->count)); | ||
120 | |||
121 | return ret < 0; | ||
122 | } | ||
123 | |||
124 | static inline void __up(struct semaphore *sem) | ||
125 | { | ||
126 | if (unlikely(atomic_inc_return(&sem->count) <= 0)) | ||
127 | __up_wakeup(sem); | ||
128 | } | ||
129 | |||
130 | #if !defined(CONFIG_DEBUG_SEMAPHORE) | ||
131 | extern inline void down(struct semaphore *sem) | ||
132 | { | ||
133 | __down(sem); | ||
134 | } | ||
135 | extern inline int down_interruptible(struct semaphore *sem) | ||
136 | { | ||
137 | return __down_interruptible(sem); | ||
138 | } | ||
139 | extern inline int down_trylock(struct semaphore *sem) | ||
140 | { | ||
141 | return __down_trylock(sem); | ||
142 | } | ||
143 | extern inline void up(struct semaphore *sem) | ||
144 | { | ||
145 | __up(sem); | ||
146 | } | ||
147 | #endif | ||
148 | |||
149 | #endif | ||
diff --git a/include/asm-arm/semaphore-helper.h b/include/asm-arm/semaphore-helper.h deleted file mode 100644 index 1d7f1987edb9..000000000000 --- a/include/asm-arm/semaphore-helper.h +++ /dev/null | |||
@@ -1,84 +0,0 @@ | |||
1 | #ifndef ASMARM_SEMAPHORE_HELPER_H | ||
2 | #define ASMARM_SEMAPHORE_HELPER_H | ||
3 | |||
4 | /* | ||
5 | * These two _must_ execute atomically wrt each other. | ||
6 | */ | ||
7 | static inline void wake_one_more(struct semaphore * sem) | ||
8 | { | ||
9 | unsigned long flags; | ||
10 | |||
11 | spin_lock_irqsave(&semaphore_wake_lock, flags); | ||
12 | if (atomic_read(&sem->count) <= 0) | ||
13 | sem->waking++; | ||
14 | spin_unlock_irqrestore(&semaphore_wake_lock, flags); | ||
15 | } | ||
16 | |||
17 | static inline int waking_non_zero(struct semaphore *sem) | ||
18 | { | ||
19 | unsigned long flags; | ||
20 | int ret = 0; | ||
21 | |||
22 | spin_lock_irqsave(&semaphore_wake_lock, flags); | ||
23 | if (sem->waking > 0) { | ||
24 | sem->waking--; | ||
25 | ret = 1; | ||
26 | } | ||
27 | spin_unlock_irqrestore(&semaphore_wake_lock, flags); | ||
28 | return ret; | ||
29 | } | ||
30 | |||
31 | /* | ||
32 | * waking non zero interruptible | ||
33 | * 1 got the lock | ||
34 | * 0 go to sleep | ||
35 | * -EINTR interrupted | ||
36 | * | ||
37 | * We must undo the sem->count down_interruptible() increment while we are | ||
38 | * protected by the spinlock in order to make this atomic_inc() with the | ||
39 | * atomic_read() in wake_one_more(), otherwise we can race. -arca | ||
40 | */ | ||
41 | static inline int waking_non_zero_interruptible(struct semaphore *sem, | ||
42 | struct task_struct *tsk) | ||
43 | { | ||
44 | unsigned long flags; | ||
45 | int ret = 0; | ||
46 | |||
47 | spin_lock_irqsave(&semaphore_wake_lock, flags); | ||
48 | if (sem->waking > 0) { | ||
49 | sem->waking--; | ||
50 | ret = 1; | ||
51 | } else if (signal_pending(tsk)) { | ||
52 | atomic_inc(&sem->count); | ||
53 | ret = -EINTR; | ||
54 | } | ||
55 | spin_unlock_irqrestore(&semaphore_wake_lock, flags); | ||
56 | return ret; | ||
57 | } | ||
58 | |||
59 | /* | ||
60 | * waking_non_zero_try_lock: | ||
61 | * 1 failed to lock | ||
62 | * 0 got the lock | ||
63 | * | ||
64 | * We must undo the sem->count down_interruptible() increment while we are | ||
65 | * protected by the spinlock in order to make this atomic_inc() with the | ||
66 | * atomic_read() in wake_one_more(), otherwise we can race. -arca | ||
67 | */ | ||
68 | static inline int waking_non_zero_trylock(struct semaphore *sem) | ||
69 | { | ||
70 | unsigned long flags; | ||
71 | int ret = 1; | ||
72 | |||
73 | spin_lock_irqsave(&semaphore_wake_lock, flags); | ||
74 | if (sem->waking <= 0) | ||
75 | atomic_inc(&sem->count); | ||
76 | else { | ||
77 | sem->waking--; | ||
78 | ret = 0; | ||
79 | } | ||
80 | spin_unlock_irqrestore(&semaphore_wake_lock, flags); | ||
81 | return ret; | ||
82 | } | ||
83 | |||
84 | #endif | ||
diff --git a/include/asm-arm/semaphore.h b/include/asm-arm/semaphore.h index 1c8b441f89e3..d9b2034ed1d2 100644 --- a/include/asm-arm/semaphore.h +++ b/include/asm-arm/semaphore.h | |||
@@ -1,98 +1 @@ | |||
1 | /* | #include <linux/semaphore.h> | |
2 | * linux/include/asm-arm/semaphore.h | ||
3 | */ | ||
4 | #ifndef __ASM_ARM_SEMAPHORE_H | ||
5 | #define __ASM_ARM_SEMAPHORE_H | ||
6 | |||
7 | #include <linux/linkage.h> | ||
8 | #include <linux/spinlock.h> | ||
9 | #include <linux/wait.h> | ||
10 | #include <linux/rwsem.h> | ||
11 | |||
12 | #include <asm/atomic.h> | ||
13 | #include <asm/locks.h> | ||
14 | |||
15 | struct semaphore { | ||
16 | atomic_t count; | ||
17 | int sleepers; | ||
18 | wait_queue_head_t wait; | ||
19 | }; | ||
20 | |||
21 | #define __SEMAPHORE_INIT(name, cnt) \ | ||
22 | { \ | ||
23 | .count = ATOMIC_INIT(cnt), \ | ||
24 | .wait = __WAIT_QUEUE_HEAD_INITIALIZER((name).wait), \ | ||
25 | } | ||
26 | |||
27 | #define __DECLARE_SEMAPHORE_GENERIC(name,count) \ | ||
28 | struct semaphore name = __SEMAPHORE_INIT(name,count) | ||
29 | |||
30 | #define DECLARE_MUTEX(name) __DECLARE_SEMAPHORE_GENERIC(name,1) | ||
31 | |||
32 | static inline void sema_init(struct semaphore *sem, int val) | ||
33 | { | ||
34 | atomic_set(&sem->count, val); | ||
35 | sem->sleepers = 0; | ||
36 | init_waitqueue_head(&sem->wait); | ||
37 | } | ||
38 | |||
39 | static inline void init_MUTEX(struct semaphore *sem) | ||
40 | { | ||
41 | sema_init(sem, 1); | ||
42 | } | ||
43 | |||
44 | static inline void init_MUTEX_LOCKED(struct semaphore *sem) | ||
45 | { | ||
46 | sema_init(sem, 0); | ||
47 | } | ||
48 | |||
49 | /* | ||
50 | * special register calling convention | ||
51 | */ | ||
52 | asmlinkage void __down_failed(void); | ||
53 | asmlinkage int __down_interruptible_failed(void); | ||
54 | asmlinkage int __down_trylock_failed(void); | ||
55 | asmlinkage void __up_wakeup(void); | ||
56 | |||
57 | extern void __down(struct semaphore * sem); | ||
58 | extern int __down_interruptible(struct semaphore * sem); | ||
59 | extern int __down_trylock(struct semaphore * sem); | ||
60 | extern void __up(struct semaphore * sem); | ||
61 | |||
62 | /* | ||
63 | * This is ugly, but we want the default case to fall through. | ||
64 | * "__down" is the actual routine that waits... | ||
65 | */ | ||
66 | static inline void down(struct semaphore * sem) | ||
67 | { | ||
68 | might_sleep(); | ||
69 | __down_op(sem, __down_failed); | ||
70 | } | ||
71 | |||
72 | /* | ||
73 | * This is ugly, but we want the default case to fall through. | ||
74 | * "__down_interruptible" is the actual routine that waits... | ||
75 | */ | ||
76 | static inline int down_interruptible (struct semaphore * sem) | ||
77 | { | ||
78 | might_sleep(); | ||
79 | return __down_op_ret(sem, __down_interruptible_failed); | ||
80 | } | ||
81 | |||
82 | static inline int down_trylock(struct semaphore *sem) | ||
83 | { | ||
84 | return __down_op_ret(sem, __down_trylock_failed); | ||
85 | } | ||
86 | |||
87 | /* | ||
88 | * Note! This is subtle. We jump to wake people up only if | ||
89 | * the semaphore was negative (== somebody was waiting on it). | ||
90 | * The default case (no contention) will result in NO | ||
91 | * jumps for both down() and up(). | ||
92 | */ | ||
93 | static inline void up(struct semaphore * sem) | ||
94 | { | ||
95 | __up_op(sem, __up_wakeup); | ||
96 | } | ||
97 | |||
98 | #endif | ||
diff --git a/include/asm-avr32/semaphore.h b/include/asm-avr32/semaphore.h index feaf1d453386..d9b2034ed1d2 100644 --- a/include/asm-avr32/semaphore.h +++ b/include/asm-avr32/semaphore.h | |||
@@ -1,108 +1 @@ | |||
1 | /* | #include <linux/semaphore.h> | |
2 | * SMP- and interrupt-safe semaphores. | ||
3 | * | ||
4 | * Copyright (C) 2006 Atmel Corporation | ||
5 | * | ||
6 | * Based on include/asm-i386/semaphore.h | ||
7 | * Copyright (C) 1996 Linus Torvalds | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify | ||
10 | * it under the terms of the GNU General Public License version 2 as | ||
11 | * published by the Free Software Foundation. | ||
12 | */ | ||
13 | #ifndef __ASM_AVR32_SEMAPHORE_H | ||
14 | #define __ASM_AVR32_SEMAPHORE_H | ||
15 | |||
16 | #include <linux/linkage.h> | ||
17 | |||
18 | #include <asm/system.h> | ||
19 | #include <asm/atomic.h> | ||
20 | #include <linux/wait.h> | ||
21 | #include <linux/rwsem.h> | ||
22 | |||
23 | struct semaphore { | ||
24 | atomic_t count; | ||
25 | int sleepers; | ||
26 | wait_queue_head_t wait; | ||
27 | }; | ||
28 | |||
29 | #define __SEMAPHORE_INITIALIZER(name, n) \ | ||
30 | { \ | ||
31 | .count = ATOMIC_INIT(n), \ | ||
32 | .wait = __WAIT_QUEUE_HEAD_INITIALIZER((name).wait) \ | ||
33 | } | ||
34 | |||
35 | #define __DECLARE_SEMAPHORE_GENERIC(name,count) \ | ||
36 | struct semaphore name = __SEMAPHORE_INITIALIZER(name,count) | ||
37 | |||
38 | #define DECLARE_MUTEX(name) __DECLARE_SEMAPHORE_GENERIC(name,1) | ||
39 | |||
40 | static inline void sema_init (struct semaphore *sem, int val) | ||
41 | { | ||
42 | atomic_set(&sem->count, val); | ||
43 | sem->sleepers = 0; | ||
44 | init_waitqueue_head(&sem->wait); | ||
45 | } | ||
46 | |||
47 | static inline void init_MUTEX (struct semaphore *sem) | ||
48 | { | ||
49 | sema_init(sem, 1); | ||
50 | } | ||
51 | |||
52 | static inline void init_MUTEX_LOCKED (struct semaphore *sem) | ||
53 | { | ||
54 | sema_init(sem, 0); | ||
55 | } | ||
56 | |||
57 | void __down(struct semaphore * sem); | ||
58 | int __down_interruptible(struct semaphore * sem); | ||
59 | void __up(struct semaphore * sem); | ||
60 | |||
61 | /* | ||
62 | * This is ugly, but we want the default case to fall through. | ||
63 | * "__down_failed" is a special asm handler that calls the C | ||
64 | * routine that actually waits. See arch/i386/kernel/semaphore.c | ||
65 | */ | ||
66 | static inline void down(struct semaphore * sem) | ||
67 | { | ||
68 | might_sleep(); | ||
69 | if (unlikely(atomic_dec_return (&sem->count) < 0)) | ||
70 | __down (sem); | ||
71 | } | ||
72 | |||
73 | /* | ||
74 | * Interruptible try to acquire a semaphore. If we obtained | ||
75 | * it, return zero. If we were interrupted, returns -EINTR | ||
76 | */ | ||
77 | static inline int down_interruptible(struct semaphore * sem) | ||
78 | { | ||
79 | int ret = 0; | ||
80 | |||
81 | might_sleep(); | ||
82 | if (unlikely(atomic_dec_return (&sem->count) < 0)) | ||
83 | ret = __down_interruptible (sem); | ||
84 | return ret; | ||
85 | } | ||
86 | |||
87 | /* | ||
88 | * Non-blockingly attempt to down() a semaphore. | ||
89 | * Returns zero if we acquired it | ||
90 | */ | ||
91 | static inline int down_trylock(struct semaphore * sem) | ||
92 | { | ||
93 | return atomic_dec_if_positive(&sem->count) < 0; | ||
94 | } | ||
95 | |||
96 | /* | ||
97 | * Note! This is subtle. We jump to wake people up only if | ||
98 | * the semaphore was negative (== somebody was waiting on it). | ||
99 | * The default case (no contention) will result in NO | ||
100 | * jumps for both down() and up(). | ||
101 | */ | ||
102 | static inline void up(struct semaphore * sem) | ||
103 | { | ||
104 | if (unlikely(atomic_inc_return (&sem->count) <= 0)) | ||
105 | __up (sem); | ||
106 | } | ||
107 | |||
108 | #endif /*__ASM_AVR32_SEMAPHORE_H */ | ||
diff --git a/include/asm-blackfin/semaphore-helper.h b/include/asm-blackfin/semaphore-helper.h deleted file mode 100644 index 9082b0dc3eb5..000000000000 --- a/include/asm-blackfin/semaphore-helper.h +++ /dev/null | |||
@@ -1,82 +0,0 @@ | |||
1 | /* Based on M68K version, Lineo Inc. May 2001 */ | ||
2 | |||
3 | #ifndef _BFIN_SEMAPHORE_HELPER_H | ||
4 | #define _BFIN_SEMAPHORE_HELPER_H | ||
5 | |||
6 | /* | ||
7 | * SMP- and interrupt-safe semaphores helper functions. | ||
8 | * | ||
9 | * (C) Copyright 1996 Linus Torvalds | ||
10 | * | ||
11 | */ | ||
12 | |||
13 | #include <asm/errno.h> | ||
14 | |||
15 | /* | ||
16 | * These two _must_ execute atomically wrt each other. | ||
17 | */ | ||
18 | static inline void wake_one_more(struct semaphore *sem) | ||
19 | { | ||
20 | atomic_inc(&sem->waking); | ||
21 | } | ||
22 | |||
23 | static inline int waking_non_zero(struct semaphore *sem) | ||
24 | { | ||
25 | int ret; | ||
26 | unsigned long flags = 0; | ||
27 | |||
28 | spin_lock_irqsave(&semaphore_wake_lock, flags); | ||
29 | ret = 0; | ||
30 | if (atomic_read(&sem->waking) > 0) { | ||
31 | atomic_dec(&sem->waking); | ||
32 | ret = 1; | ||
33 | } | ||
34 | spin_unlock_irqrestore(&semaphore_wake_lock, flags); | ||
35 | return ret; | ||
36 | } | ||
37 | |||
38 | /* | ||
39 | * waking_non_zero_interruptible: | ||
40 | * 1 got the lock | ||
41 | * 0 go to sleep | ||
42 | * -EINTR interrupted | ||
43 | */ | ||
44 | static inline int waking_non_zero_interruptible(struct semaphore *sem, | ||
45 | struct task_struct *tsk) | ||
46 | { | ||
47 | int ret = 0; | ||
48 | unsigned long flags = 0; | ||
49 | |||
50 | spin_lock_irqsave(&semaphore_wake_lock, flags); | ||
51 | if (atomic_read(&sem->waking) > 0) { | ||
52 | atomic_dec(&sem->waking); | ||
53 | ret = 1; | ||
54 | } else if (signal_pending(tsk)) { | ||
55 | atomic_inc(&sem->count); | ||
56 | ret = -EINTR; | ||
57 | } | ||
58 | spin_unlock_irqrestore(&semaphore_wake_lock, flags); | ||
59 | return ret; | ||
60 | } | ||
61 | |||
62 | /* | ||
63 | * waking_non_zero_trylock: | ||
64 | * 1 failed to lock | ||
65 | * 0 got the lock | ||
66 | */ | ||
67 | static inline int waking_non_zero_trylock(struct semaphore *sem) | ||
68 | { | ||
69 | int ret = 1; | ||
70 | unsigned long flags = 0; | ||
71 | |||
72 | spin_lock_irqsave(&semaphore_wake_lock, flags); | ||
73 | if (atomic_read(&sem->waking) > 0) { | ||
74 | atomic_dec(&sem->waking); | ||
75 | ret = 0; | ||
76 | } else | ||
77 | atomic_inc(&sem->count); | ||
78 | spin_unlock_irqrestore(&semaphore_wake_lock, flags); | ||
79 | return ret; | ||
80 | } | ||
81 | |||
82 | #endif /* _BFIN_SEMAPHORE_HELPER_H */ | ||
diff --git a/include/asm-blackfin/semaphore.h b/include/asm-blackfin/semaphore.h index 533f90fb2e4e..d9b2034ed1d2 100644 --- a/include/asm-blackfin/semaphore.h +++ b/include/asm-blackfin/semaphore.h | |||
@@ -1,105 +1 @@ | |||
1 | #ifndef _BFIN_SEMAPHORE_H | #include <linux/semaphore.h> | |
2 | #define _BFIN_SEMAPHORE_H | ||
3 | |||
4 | #ifndef __ASSEMBLY__ | ||
5 | |||
6 | #include <linux/linkage.h> | ||
7 | #include <linux/wait.h> | ||
8 | #include <linux/spinlock.h> | ||
9 | #include <linux/rwsem.h> | ||
10 | #include <asm/atomic.h> | ||
11 | |||
12 | /* | ||
13 | * Interrupt-safe semaphores.. | ||
14 | * | ||
15 | * (C) Copyright 1996 Linus Torvalds | ||
16 | * | ||
17 | * BFIN version by akbar hussain Lineo Inc April 2001 | ||
18 | * | ||
19 | */ | ||
20 | |||
21 | struct semaphore { | ||
22 | atomic_t count; | ||
23 | int sleepers; | ||
24 | wait_queue_head_t wait; | ||
25 | }; | ||
26 | |||
27 | #define __SEMAPHORE_INITIALIZER(name, n) \ | ||
28 | { \ | ||
29 | .count = ATOMIC_INIT(n), \ | ||
30 | .sleepers = 0, \ | ||
31 | .wait = __WAIT_QUEUE_HEAD_INITIALIZER((name).wait) \ | ||
32 | } | ||
33 | |||
34 | #define __DECLARE_SEMAPHORE_GENERIC(name,count) \ | ||
35 | struct semaphore name = __SEMAPHORE_INITIALIZER(name,count) | ||
36 | |||
37 | #define DECLARE_MUTEX(name) __DECLARE_SEMAPHORE_GENERIC(name,1) | ||
38 | |||
39 | static inline void sema_init(struct semaphore *sem, int val) | ||
40 | { | ||
41 | *sem = (struct semaphore)__SEMAPHORE_INITIALIZER(*sem, val); | ||
42 | } | ||
43 | |||
44 | static inline void init_MUTEX(struct semaphore *sem) | ||
45 | { | ||
46 | sema_init(sem, 1); | ||
47 | } | ||
48 | |||
49 | static inline void init_MUTEX_LOCKED(struct semaphore *sem) | ||
50 | { | ||
51 | sema_init(sem, 0); | ||
52 | } | ||
53 | |||
54 | asmlinkage void __down(struct semaphore *sem); | ||
55 | asmlinkage int __down_interruptible(struct semaphore *sem); | ||
56 | asmlinkage int __down_trylock(struct semaphore *sem); | ||
57 | asmlinkage void __up(struct semaphore *sem); | ||
58 | |||
59 | extern spinlock_t semaphore_wake_lock; | ||
60 | |||
61 | /* | ||
62 | * This is ugly, but we want the default case to fall through. | ||
63 | * "down_failed" is a special asm handler that calls the C | ||
64 | * routine that actually waits. | ||
65 | */ | ||
66 | static inline void down(struct semaphore *sem) | ||
67 | { | ||
68 | might_sleep(); | ||
69 | if (atomic_dec_return(&sem->count) < 0) | ||
70 | __down(sem); | ||
71 | } | ||
72 | |||
73 | static inline int down_interruptible(struct semaphore *sem) | ||
74 | { | ||
75 | int ret = 0; | ||
76 | |||
77 | might_sleep(); | ||
78 | if (atomic_dec_return(&sem->count) < 0) | ||
79 | ret = __down_interruptible(sem); | ||
80 | return (ret); | ||
81 | } | ||
82 | |||
83 | static inline int down_trylock(struct semaphore *sem) | ||
84 | { | ||
85 | int ret = 0; | ||
86 | |||
87 | if (atomic_dec_return(&sem->count) < 0) | ||
88 | ret = __down_trylock(sem); | ||
89 | return ret; | ||
90 | } | ||
91 | |||
92 | /* | ||
93 | * Note! This is subtle. We jump to wake people up only if | ||
94 | * the semaphore was negative (== somebody was waiting on it). | ||
95 | * The default case (no contention) will result in NO | ||
96 | * jumps for both down() and up(). | ||
97 | */ | ||
98 | static inline void up(struct semaphore *sem) | ||
99 | { | ||
100 | if (atomic_inc_return(&sem->count) <= 0) | ||
101 | __up(sem); | ||
102 | } | ||
103 | |||
104 | #endif /* __ASSEMBLY__ */ | ||
105 | #endif /* _BFIN_SEMAPHORE_H */ | ||
diff --git a/include/asm-cris/semaphore-helper.h b/include/asm-cris/semaphore-helper.h deleted file mode 100644 index 27bfeca1b981..000000000000 --- a/include/asm-cris/semaphore-helper.h +++ /dev/null | |||
@@ -1,78 +0,0 @@ | |||
1 | /* $Id: semaphore-helper.h,v 1.3 2001/03/26 15:00:33 orjanf Exp $ | ||
2 | * | ||
3 | * SMP- and interrupt-safe semaphores helper functions. Generic versions, no | ||
4 | * optimizations whatsoever... | ||
5 | * | ||
6 | */ | ||
7 | |||
8 | #ifndef _ASM_SEMAPHORE_HELPER_H | ||
9 | #define _ASM_SEMAPHORE_HELPER_H | ||
10 | |||
11 | #include <asm/atomic.h> | ||
12 | #include <linux/errno.h> | ||
13 | |||
14 | #define read(a) ((a)->counter) | ||
15 | #define inc(a) (((a)->counter)++) | ||
16 | #define dec(a) (((a)->counter)--) | ||
17 | |||
18 | #define count_inc(a) ((*(a))++) | ||
19 | |||
20 | /* | ||
21 | * These two _must_ execute atomically wrt each other. | ||
22 | */ | ||
23 | static inline void wake_one_more(struct semaphore * sem) | ||
24 | { | ||
25 | atomic_inc(&sem->waking); | ||
26 | } | ||
27 | |||
28 | static inline int waking_non_zero(struct semaphore *sem) | ||
29 | { | ||
30 | unsigned long flags; | ||
31 | int ret = 0; | ||
32 | |||
33 | local_irq_save(flags); | ||
34 | if (read(&sem->waking) > 0) { | ||
35 | dec(&sem->waking); | ||
36 | ret = 1; | ||
37 | } | ||
38 | local_irq_restore(flags); | ||
39 | return ret; | ||
40 | } | ||
41 | |||
42 | static inline int waking_non_zero_interruptible(struct semaphore *sem, | ||
43 | struct task_struct *tsk) | ||
44 | { | ||
45 | int ret = 0; | ||
46 | unsigned long flags; | ||
47 | |||
48 | local_irq_save(flags); | ||
49 | if (read(&sem->waking) > 0) { | ||
50 | dec(&sem->waking); | ||
51 | ret = 1; | ||
52 | } else if (signal_pending(tsk)) { | ||
53 | inc(&sem->count); | ||
54 | ret = -EINTR; | ||
55 | } | ||
56 | local_irq_restore(flags); | ||
57 | return ret; | ||
58 | } | ||
59 | |||
60 | static inline int waking_non_zero_trylock(struct semaphore *sem) | ||
61 | { | ||
62 | int ret = 1; | ||
63 | unsigned long flags; | ||
64 | |||
65 | local_irq_save(flags); | ||
66 | if (read(&sem->waking) <= 0) | ||
67 | inc(&sem->count); | ||
68 | else { | ||
69 | dec(&sem->waking); | ||
70 | ret = 0; | ||
71 | } | ||
72 | local_irq_restore(flags); | ||
73 | return ret; | ||
74 | } | ||
75 | |||
76 | #endif /* _ASM_SEMAPHORE_HELPER_H */ | ||
77 | |||
78 | |||
diff --git a/include/asm-cris/semaphore.h b/include/asm-cris/semaphore.h index 31a4ac448195..d9b2034ed1d2 100644 --- a/include/asm-cris/semaphore.h +++ b/include/asm-cris/semaphore.h | |||
@@ -1,133 +1 @@ | |||
1 | /* $Id: semaphore.h,v 1.3 2001/05/08 13:54:09 bjornw Exp $ */ | #include <linux/semaphore.h> | |
2 | |||
3 | /* On the i386 these are coded in asm, perhaps we should as well. Later.. */ | ||
4 | |||
5 | #ifndef _CRIS_SEMAPHORE_H | ||
6 | #define _CRIS_SEMAPHORE_H | ||
7 | |||
8 | #define RW_LOCK_BIAS 0x01000000 | ||
9 | |||
10 | #include <linux/wait.h> | ||
11 | #include <linux/spinlock.h> | ||
12 | #include <linux/rwsem.h> | ||
13 | |||
14 | #include <asm/system.h> | ||
15 | #include <asm/atomic.h> | ||
16 | |||
17 | /* | ||
18 | * CRIS semaphores, implemented in C-only so far. | ||
19 | */ | ||
20 | |||
21 | struct semaphore { | ||
22 | atomic_t count; | ||
23 | atomic_t waking; | ||
24 | wait_queue_head_t wait; | ||
25 | }; | ||
26 | |||
27 | #define __SEMAPHORE_INITIALIZER(name, n) \ | ||
28 | { \ | ||
29 | .count = ATOMIC_INIT(n), \ | ||
30 | .waking = ATOMIC_INIT(0), \ | ||
31 | .wait = __WAIT_QUEUE_HEAD_INITIALIZER((name).wait) \ | ||
32 | } | ||
33 | |||
34 | #define __DECLARE_SEMAPHORE_GENERIC(name,count) \ | ||
35 | struct semaphore name = __SEMAPHORE_INITIALIZER(name,count) | ||
36 | |||
37 | #define DECLARE_MUTEX(name) __DECLARE_SEMAPHORE_GENERIC(name,1) | ||
38 | |||
39 | static inline void sema_init(struct semaphore *sem, int val) | ||
40 | { | ||
41 | *sem = (struct semaphore)__SEMAPHORE_INITIALIZER((*sem),val); | ||
42 | } | ||
43 | |||
44 | static inline void init_MUTEX (struct semaphore *sem) | ||
45 | { | ||
46 | sema_init(sem, 1); | ||
47 | } | ||
48 | |||
49 | static inline void init_MUTEX_LOCKED (struct semaphore *sem) | ||
50 | { | ||
51 | sema_init(sem, 0); | ||
52 | } | ||
53 | |||
54 | extern void __down(struct semaphore * sem); | ||
55 | extern int __down_interruptible(struct semaphore * sem); | ||
56 | extern int __down_trylock(struct semaphore * sem); | ||
57 | extern void __up(struct semaphore * sem); | ||
58 | |||
59 | /* notice - we probably can do cli/sti here instead of saving */ | ||
60 | |||
61 | static inline void down(struct semaphore * sem) | ||
62 | { | ||
63 | unsigned long flags; | ||
64 | int failed; | ||
65 | |||
66 | might_sleep(); | ||
67 | |||
68 | /* atomically decrement the semaphores count, and if its negative, we wait */ | ||
69 | cris_atomic_save(sem, flags); | ||
70 | failed = --(sem->count.counter) < 0; | ||
71 | cris_atomic_restore(sem, flags); | ||
72 | if(failed) { | ||
73 | __down(sem); | ||
74 | } | ||
75 | } | ||
76 | |||
77 | /* | ||
78 | * This version waits in interruptible state so that the waiting | ||
79 | * process can be killed. The down_interruptible routine | ||
80 | * returns negative for signalled and zero for semaphore acquired. | ||
81 | */ | ||
82 | |||
83 | static inline int down_interruptible(struct semaphore * sem) | ||
84 | { | ||
85 | unsigned long flags; | ||
86 | int failed; | ||
87 | |||
88 | might_sleep(); | ||
89 | |||
90 | /* atomically decrement the semaphores count, and if its negative, we wait */ | ||
91 | cris_atomic_save(sem, flags); | ||
92 | failed = --(sem->count.counter) < 0; | ||
93 | cris_atomic_restore(sem, flags); | ||
94 | if(failed) | ||
95 | failed = __down_interruptible(sem); | ||
96 | return(failed); | ||
97 | } | ||
98 | |||
99 | static inline int down_trylock(struct semaphore * sem) | ||
100 | { | ||
101 | unsigned long flags; | ||
102 | int failed; | ||
103 | |||
104 | cris_atomic_save(sem, flags); | ||
105 | failed = --(sem->count.counter) < 0; | ||
106 | cris_atomic_restore(sem, flags); | ||
107 | if(failed) | ||
108 | failed = __down_trylock(sem); | ||
109 | return(failed); | ||
110 | |||
111 | } | ||
112 | |||
113 | /* | ||
114 | * Note! This is subtle. We jump to wake people up only if | ||
115 | * the semaphore was negative (== somebody was waiting on it). | ||
116 | * The default case (no contention) will result in NO | ||
117 | * jumps for both down() and up(). | ||
118 | */ | ||
119 | static inline void up(struct semaphore * sem) | ||
120 | { | ||
121 | unsigned long flags; | ||
122 | int wakeup; | ||
123 | |||
124 | /* atomically increment the semaphores count, and if it was negative, we wake people */ | ||
125 | cris_atomic_save(sem, flags); | ||
126 | wakeup = ++(sem->count.counter) <= 0; | ||
127 | cris_atomic_restore(sem, flags); | ||
128 | if(wakeup) { | ||
129 | __up(sem); | ||
130 | } | ||
131 | } | ||
132 | |||
133 | #endif | ||
diff --git a/include/asm-frv/semaphore.h b/include/asm-frv/semaphore.h index d7aaa1911a1a..d9b2034ed1d2 100644 --- a/include/asm-frv/semaphore.h +++ b/include/asm-frv/semaphore.h | |||
@@ -1,155 +1 @@ | |||
1 | /* semaphore.h: semaphores for the FR-V | #include <linux/semaphore.h> | |
2 | * | ||
3 | * Copyright (C) 2003 Red Hat, Inc. All Rights Reserved. | ||
4 | * Written by David Howells (dhowells@redhat.com) | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or | ||
7 | * modify it under the terms of the GNU General Public License | ||
8 | * as published by the Free Software Foundation; either version | ||
9 | * 2 of the License, or (at your option) any later version. | ||
10 | */ | ||
11 | #ifndef _ASM_SEMAPHORE_H | ||
12 | #define _ASM_SEMAPHORE_H | ||
13 | |||
14 | #define RW_LOCK_BIAS 0x01000000 | ||
15 | |||
16 | #ifndef __ASSEMBLY__ | ||
17 | |||
18 | #include <linux/linkage.h> | ||
19 | #include <linux/wait.h> | ||
20 | #include <linux/spinlock.h> | ||
21 | #include <linux/rwsem.h> | ||
22 | |||
23 | /* | ||
24 | * the semaphore definition | ||
25 | * - if counter is >0 then there are tokens available on the semaphore for down to collect | ||
26 | * - if counter is <=0 then there are no spare tokens, and anyone that wants one must wait | ||
27 | * - if wait_list is not empty, then there are processes waiting for the semaphore | ||
28 | */ | ||
29 | struct semaphore { | ||
30 | unsigned counter; | ||
31 | spinlock_t wait_lock; | ||
32 | struct list_head wait_list; | ||
33 | #ifdef CONFIG_DEBUG_SEMAPHORE | ||
34 | unsigned __magic; | ||
35 | #endif | ||
36 | }; | ||
37 | |||
38 | #ifdef CONFIG_DEBUG_SEMAPHORE | ||
39 | # define __SEM_DEBUG_INIT(name) , (long)&(name).__magic | ||
40 | #else | ||
41 | # define __SEM_DEBUG_INIT(name) | ||
42 | #endif | ||
43 | |||
44 | |||
45 | #define __SEMAPHORE_INITIALIZER(name,count) \ | ||
46 | { count, SPIN_LOCK_UNLOCKED, LIST_HEAD_INIT((name).wait_list) __SEM_DEBUG_INIT(name) } | ||
47 | |||
48 | #define __DECLARE_SEMAPHORE_GENERIC(name,count) \ | ||
49 | struct semaphore name = __SEMAPHORE_INITIALIZER(name,count) | ||
50 | |||
51 | #define DECLARE_MUTEX(name) __DECLARE_SEMAPHORE_GENERIC(name,1) | ||
52 | |||
53 | static inline void sema_init (struct semaphore *sem, int val) | ||
54 | { | ||
55 | *sem = (struct semaphore) __SEMAPHORE_INITIALIZER(*sem, val); | ||
56 | } | ||
57 | |||
58 | static inline void init_MUTEX (struct semaphore *sem) | ||
59 | { | ||
60 | sema_init(sem, 1); | ||
61 | } | ||
62 | |||
63 | static inline void init_MUTEX_LOCKED (struct semaphore *sem) | ||
64 | { | ||
65 | sema_init(sem, 0); | ||
66 | } | ||
67 | |||
68 | extern void __down(struct semaphore *sem, unsigned long flags); | ||
69 | extern int __down_interruptible(struct semaphore *sem, unsigned long flags); | ||
70 | extern void __up(struct semaphore *sem); | ||
71 | |||
72 | static inline void down(struct semaphore *sem) | ||
73 | { | ||
74 | unsigned long flags; | ||
75 | |||
76 | #ifdef CONFIG_DEBUG_SEMAPHORE | ||
77 | CHECK_MAGIC(sem->__magic); | ||
78 | #endif | ||
79 | |||
80 | spin_lock_irqsave(&sem->wait_lock, flags); | ||
81 | if (likely(sem->counter > 0)) { | ||
82 | sem->counter--; | ||
83 | spin_unlock_irqrestore(&sem->wait_lock, flags); | ||
84 | } | ||
85 | else { | ||
86 | __down(sem, flags); | ||
87 | } | ||
88 | } | ||
89 | |||
90 | static inline int down_interruptible(struct semaphore *sem) | ||
91 | { | ||
92 | unsigned long flags; | ||
93 | int ret = 0; | ||
94 | |||
95 | #ifdef CONFIG_DEBUG_SEMAPHORE | ||
96 | CHECK_MAGIC(sem->__magic); | ||
97 | #endif | ||
98 | |||
99 | spin_lock_irqsave(&sem->wait_lock, flags); | ||
100 | if (likely(sem->counter > 0)) { | ||
101 | sem->counter--; | ||
102 | spin_unlock_irqrestore(&sem->wait_lock, flags); | ||
103 | } | ||
104 | else { | ||
105 | ret = __down_interruptible(sem, flags); | ||
106 | } | ||
107 | return ret; | ||
108 | } | ||
109 | |||
110 | /* | ||
111 | * non-blockingly attempt to down() a semaphore. | ||
112 | * - returns zero if we acquired it | ||
113 | */ | ||
114 | static inline int down_trylock(struct semaphore *sem) | ||
115 | { | ||
116 | unsigned long flags; | ||
117 | int success = 0; | ||
118 | |||
119 | #ifdef CONFIG_DEBUG_SEMAPHORE | ||
120 | CHECK_MAGIC(sem->__magic); | ||
121 | #endif | ||
122 | |||
123 | spin_lock_irqsave(&sem->wait_lock, flags); | ||
124 | if (sem->counter > 0) { | ||
125 | sem->counter--; | ||
126 | success = 1; | ||
127 | } | ||
128 | spin_unlock_irqrestore(&sem->wait_lock, flags); | ||
129 | return !success; | ||
130 | } | ||
131 | |||
132 | static inline void up(struct semaphore *sem) | ||
133 | { | ||
134 | unsigned long flags; | ||
135 | |||
136 | #ifdef CONFIG_DEBUG_SEMAPHORE | ||
137 | CHECK_MAGIC(sem->__magic); | ||
138 | #endif | ||
139 | |||
140 | spin_lock_irqsave(&sem->wait_lock, flags); | ||
141 | if (!list_empty(&sem->wait_list)) | ||
142 | __up(sem); | ||
143 | else | ||
144 | sem->counter++; | ||
145 | spin_unlock_irqrestore(&sem->wait_lock, flags); | ||
146 | } | ||
147 | |||
148 | static inline int sem_getcount(struct semaphore *sem) | ||
149 | { | ||
150 | return sem->counter; | ||
151 | } | ||
152 | |||
153 | #endif /* __ASSEMBLY__ */ | ||
154 | |||
155 | #endif | ||
diff --git a/include/asm-h8300/semaphore-helper.h b/include/asm-h8300/semaphore-helper.h deleted file mode 100644 index 4fea36be5fd8..000000000000 --- a/include/asm-h8300/semaphore-helper.h +++ /dev/null | |||
@@ -1,85 +0,0 @@ | |||
1 | #ifndef _H8300_SEMAPHORE_HELPER_H | ||
2 | #define _H8300_SEMAPHORE_HELPER_H | ||
3 | |||
4 | /* | ||
5 | * SMP- and interrupt-safe semaphores helper functions. | ||
6 | * | ||
7 | * (C) Copyright 1996 Linus Torvalds | ||
8 | * | ||
9 | * based on | ||
10 | * m68k version by Andreas Schwab | ||
11 | */ | ||
12 | |||
13 | #include <linux/errno.h> | ||
14 | |||
15 | /* | ||
16 | * These two _must_ execute atomically wrt each other. | ||
17 | */ | ||
18 | static inline void wake_one_more(struct semaphore * sem) | ||
19 | { | ||
20 | atomic_inc((atomic_t *)&sem->sleepers); | ||
21 | } | ||
22 | |||
23 | static inline int waking_non_zero(struct semaphore *sem) | ||
24 | { | ||
25 | int ret; | ||
26 | unsigned long flags; | ||
27 | |||
28 | spin_lock_irqsave(&semaphore_wake_lock, flags); | ||
29 | ret = 0; | ||
30 | if (sem->sleepers > 0) { | ||
31 | sem->sleepers--; | ||
32 | ret = 1; | ||
33 | } | ||
34 | spin_unlock_irqrestore(&semaphore_wake_lock, flags); | ||
35 | return ret; | ||
36 | } | ||
37 | |||
38 | /* | ||
39 | * waking_non_zero_interruptible: | ||
40 | * 1 got the lock | ||
41 | * 0 go to sleep | ||
42 | * -EINTR interrupted | ||
43 | */ | ||
44 | static inline int waking_non_zero_interruptible(struct semaphore *sem, | ||
45 | struct task_struct *tsk) | ||
46 | { | ||
47 | int ret; | ||
48 | unsigned long flags; | ||
49 | |||
50 | spin_lock_irqsave(&semaphore_wake_lock, flags); | ||
51 | ret = 0; | ||
52 | if (sem->sleepers > 0) { | ||
53 | sem->sleepers--; | ||
54 | ret = 1; | ||
55 | } else if (signal_pending(tsk)) { | ||
56 | atomic_inc(&sem->count); | ||
57 | ret = -EINTR; | ||
58 | } | ||
59 | spin_unlock_irqrestore(&semaphore_wake_lock, flags); | ||
60 | return ret; | ||
61 | } | ||
62 | |||
63 | /* | ||
64 | * waking_non_zero_trylock: | ||
65 | * 1 failed to lock | ||
66 | * 0 got the lock | ||
67 | */ | ||
68 | static inline int waking_non_zero_trylock(struct semaphore *sem) | ||
69 | { | ||
70 | int ret; | ||
71 | unsigned long flags; | ||
72 | |||
73 | spin_lock_irqsave(&semaphore_wake_lock, flags); | ||
74 | ret = 1; | ||
75 | if (sem->sleepers <= 0) | ||
76 | atomic_inc(&sem->count); | ||
77 | else { | ||
78 | sem->sleepers--; | ||
79 | ret = 0; | ||
80 | } | ||
81 | spin_unlock_irqrestore(&semaphore_wake_lock, flags); | ||
82 | return ret; | ||
83 | } | ||
84 | |||
85 | #endif | ||
diff --git a/include/asm-h8300/semaphore.h b/include/asm-h8300/semaphore.h index f3ffff83ff09..d9b2034ed1d2 100644 --- a/include/asm-h8300/semaphore.h +++ b/include/asm-h8300/semaphore.h | |||
@@ -1,190 +1 @@ | |||
1 | #ifndef _H8300_SEMAPHORE_H | #include <linux/semaphore.h> | |
2 | #define _H8300_SEMAPHORE_H | ||
3 | |||
4 | #define RW_LOCK_BIAS 0x01000000 | ||
5 | |||
6 | #ifndef __ASSEMBLY__ | ||
7 | |||
8 | #include <linux/linkage.h> | ||
9 | #include <linux/wait.h> | ||
10 | #include <linux/spinlock.h> | ||
11 | #include <linux/rwsem.h> | ||
12 | |||
13 | #include <asm/system.h> | ||
14 | #include <asm/atomic.h> | ||
15 | |||
16 | /* | ||
17 | * Interrupt-safe semaphores.. | ||
18 | * | ||
19 | * (C) Copyright 1996 Linus Torvalds | ||
20 | * | ||
21 | * H8/300 version by Yoshinori Sato | ||
22 | */ | ||
23 | |||
24 | |||
25 | struct semaphore { | ||
26 | atomic_t count; | ||
27 | int sleepers; | ||
28 | wait_queue_head_t wait; | ||
29 | }; | ||
30 | |||
31 | #define __SEMAPHORE_INITIALIZER(name, n) \ | ||
32 | { \ | ||
33 | .count = ATOMIC_INIT(n), \ | ||
34 | .sleepers = 0, \ | ||
35 | .wait = __WAIT_QUEUE_HEAD_INITIALIZER((name).wait) \ | ||
36 | } | ||
37 | |||
38 | #define __DECLARE_SEMAPHORE_GENERIC(name,count) \ | ||
39 | struct semaphore name = __SEMAPHORE_INITIALIZER(name,count) | ||
40 | |||
41 | #define DECLARE_MUTEX(name) __DECLARE_SEMAPHORE_GENERIC(name,1) | ||
42 | |||
43 | static inline void sema_init (struct semaphore *sem, int val) | ||
44 | { | ||
45 | *sem = (struct semaphore)__SEMAPHORE_INITIALIZER(*sem, val); | ||
46 | } | ||
47 | |||
48 | static inline void init_MUTEX (struct semaphore *sem) | ||
49 | { | ||
50 | sema_init(sem, 1); | ||
51 | } | ||
52 | |||
53 | static inline void init_MUTEX_LOCKED (struct semaphore *sem) | ||
54 | { | ||
55 | sema_init(sem, 0); | ||
56 | } | ||
57 | |||
58 | asmlinkage void __down_failed(void /* special register calling convention */); | ||
59 | asmlinkage int __down_failed_interruptible(void /* params in registers */); | ||
60 | asmlinkage int __down_failed_trylock(void /* params in registers */); | ||
61 | asmlinkage void __up_wakeup(void /* special register calling convention */); | ||
62 | |||
63 | asmlinkage void __down(struct semaphore * sem); | ||
64 | asmlinkage int __down_interruptible(struct semaphore * sem); | ||
65 | asmlinkage int __down_trylock(struct semaphore * sem); | ||
66 | asmlinkage void __up(struct semaphore * sem); | ||
67 | |||
68 | extern spinlock_t semaphore_wake_lock; | ||
69 | |||
70 | /* | ||
71 | * This is ugly, but we want the default case to fall through. | ||
72 | * "down_failed" is a special asm handler that calls the C | ||
73 | * routine that actually waits. See arch/m68k/lib/semaphore.S | ||
74 | */ | ||
75 | static inline void down(struct semaphore * sem) | ||
76 | { | ||
77 | register atomic_t *count asm("er0"); | ||
78 | |||
79 | might_sleep(); | ||
80 | |||
81 | count = &(sem->count); | ||
82 | __asm__ __volatile__( | ||
83 | "stc ccr,r3l\n\t" | ||
84 | "orc #0x80,ccr\n\t" | ||
85 | "mov.l %2, er1\n\t" | ||
86 | "dec.l #1,er1\n\t" | ||
87 | "mov.l er1,%0\n\t" | ||
88 | "bpl 1f\n\t" | ||
89 | "ldc r3l,ccr\n\t" | ||
90 | "mov.l %1,er0\n\t" | ||
91 | "jsr @___down\n\t" | ||
92 | "bra 2f\n" | ||
93 | "1:\n\t" | ||
94 | "ldc r3l,ccr\n" | ||
95 | "2:" | ||
96 | : "=m"(*count) | ||
97 | : "g"(sem),"m"(*count) | ||
98 | : "cc", "er1", "er2", "er3"); | ||
99 | } | ||
100 | |||
101 | static inline int down_interruptible(struct semaphore * sem) | ||
102 | { | ||
103 | register atomic_t *count asm("er0"); | ||
104 | |||
105 | might_sleep(); | ||
106 | |||
107 | count = &(sem->count); | ||
108 | __asm__ __volatile__( | ||
109 | "stc ccr,r1l\n\t" | ||
110 | "orc #0x80,ccr\n\t" | ||
111 | "mov.l %3, er2\n\t" | ||
112 | "dec.l #1,er2\n\t" | ||
113 | "mov.l er2,%1\n\t" | ||
114 | "bpl 1f\n\t" | ||
115 | "ldc r1l,ccr\n\t" | ||
116 | "mov.l %2,er0\n\t" | ||
117 | "jsr @___down_interruptible\n\t" | ||
118 | "bra 2f\n" | ||
119 | "1:\n\t" | ||
120 | "ldc r1l,ccr\n\t" | ||
121 | "sub.l %0,%0\n\t" | ||
122 | "2:\n\t" | ||
123 | : "=r" (count),"=m" (*count) | ||
124 | : "g"(sem),"m"(*count) | ||
125 | : "cc", "er1", "er2", "er3"); | ||
126 | return (int)count; | ||
127 | } | ||
128 | |||
129 | static inline int down_trylock(struct semaphore * sem) | ||
130 | { | ||
131 | register atomic_t *count asm("er0"); | ||
132 | |||
133 | count = &(sem->count); | ||
134 | __asm__ __volatile__( | ||
135 | "stc ccr,r3l\n\t" | ||
136 | "orc #0x80,ccr\n\t" | ||
137 | "mov.l %3,er2\n\t" | ||
138 | "dec.l #1,er2\n\t" | ||
139 | "mov.l er2,%0\n\t" | ||
140 | "bpl 1f\n\t" | ||
141 | "ldc r3l,ccr\n\t" | ||
142 | "jmp @3f\n\t" | ||
143 | LOCK_SECTION_START(".align 2\n\t") | ||
144 | "3:\n\t" | ||
145 | "mov.l %2,er0\n\t" | ||
146 | "jsr @___down_trylock\n\t" | ||
147 | "jmp @2f\n\t" | ||
148 | LOCK_SECTION_END | ||
149 | "1:\n\t" | ||
150 | "ldc r3l,ccr\n\t" | ||
151 | "sub.l %1,%1\n" | ||
152 | "2:" | ||
153 | : "=m" (*count),"=r"(count) | ||
154 | : "g"(sem),"m"(*count) | ||
155 | : "cc", "er1","er2", "er3"); | ||
156 | return (int)count; | ||
157 | } | ||
158 | |||
159 | /* | ||
160 | * Note! This is subtle. We jump to wake people up only if | ||
161 | * the semaphore was negative (== somebody was waiting on it). | ||
162 | * The default case (no contention) will result in NO | ||
163 | * jumps for both down() and up(). | ||
164 | */ | ||
165 | static inline void up(struct semaphore * sem) | ||
166 | { | ||
167 | register atomic_t *count asm("er0"); | ||
168 | |||
169 | count = &(sem->count); | ||
170 | __asm__ __volatile__( | ||
171 | "stc ccr,r3l\n\t" | ||
172 | "orc #0x80,ccr\n\t" | ||
173 | "mov.l %2,er1\n\t" | ||
174 | "inc.l #1,er1\n\t" | ||
175 | "mov.l er1,%0\n\t" | ||
176 | "ldc r3l,ccr\n\t" | ||
177 | "sub.l er2,er2\n\t" | ||
178 | "cmp.l er2,er1\n\t" | ||
179 | "bgt 1f\n\t" | ||
180 | "mov.l %1,er0\n\t" | ||
181 | "jsr @___up\n" | ||
182 | "1:" | ||
183 | : "=m"(*count) | ||
184 | : "g"(sem),"m"(*count) | ||
185 | : "cc", "er1", "er2", "er3"); | ||
186 | } | ||
187 | |||
188 | #endif /* __ASSEMBLY__ */ | ||
189 | |||
190 | #endif | ||
diff --git a/include/asm-ia64/semaphore.h b/include/asm-ia64/semaphore.h index d8393d11288d..d9b2034ed1d2 100644 --- a/include/asm-ia64/semaphore.h +++ b/include/asm-ia64/semaphore.h | |||
@@ -1,99 +1 @@ | |||
1 | #ifndef _ASM_IA64_SEMAPHORE_H | #include <linux/semaphore.h> | |
2 | #define _ASM_IA64_SEMAPHORE_H | ||
3 | |||
4 | /* | ||
5 | * Copyright (C) 1998-2000 Hewlett-Packard Co | ||
6 | * Copyright (C) 1998-2000 David Mosberger-Tang <davidm@hpl.hp.com> | ||
7 | */ | ||
8 | |||
9 | #include <linux/wait.h> | ||
10 | #include <linux/rwsem.h> | ||
11 | |||
12 | #include <asm/atomic.h> | ||
13 | |||
14 | struct semaphore { | ||
15 | atomic_t count; | ||
16 | int sleepers; | ||
17 | wait_queue_head_t wait; | ||
18 | }; | ||
19 | |||
20 | #define __SEMAPHORE_INITIALIZER(name, n) \ | ||
21 | { \ | ||
22 | .count = ATOMIC_INIT(n), \ | ||
23 | .sleepers = 0, \ | ||
24 | .wait = __WAIT_QUEUE_HEAD_INITIALIZER((name).wait) \ | ||
25 | } | ||
26 | |||
27 | #define __DECLARE_SEMAPHORE_GENERIC(name,count) \ | ||
28 | struct semaphore name = __SEMAPHORE_INITIALIZER(name, count) | ||
29 | |||
30 | #define DECLARE_MUTEX(name) __DECLARE_SEMAPHORE_GENERIC(name, 1) | ||
31 | |||
32 | static inline void | ||
33 | sema_init (struct semaphore *sem, int val) | ||
34 | { | ||
35 | *sem = (struct semaphore) __SEMAPHORE_INITIALIZER(*sem, val); | ||
36 | } | ||
37 | |||
38 | static inline void | ||
39 | init_MUTEX (struct semaphore *sem) | ||
40 | { | ||
41 | sema_init(sem, 1); | ||
42 | } | ||
43 | |||
44 | static inline void | ||
45 | init_MUTEX_LOCKED (struct semaphore *sem) | ||
46 | { | ||
47 | sema_init(sem, 0); | ||
48 | } | ||
49 | |||
50 | extern void __down (struct semaphore * sem); | ||
51 | extern int __down_interruptible (struct semaphore * sem); | ||
52 | extern int __down_trylock (struct semaphore * sem); | ||
53 | extern void __up (struct semaphore * sem); | ||
54 | |||
55 | /* | ||
56 | * Atomically decrement the semaphore's count. If it goes negative, | ||
57 | * block the calling thread in the TASK_UNINTERRUPTIBLE state. | ||
58 | */ | ||
59 | static inline void | ||
60 | down (struct semaphore *sem) | ||
61 | { | ||
62 | might_sleep(); | ||
63 | if (ia64_fetchadd(-1, &sem->count.counter, acq) < 1) | ||
64 | __down(sem); | ||
65 | } | ||
66 | |||
67 | /* | ||
68 | * Atomically decrement the semaphore's count. If it goes negative, | ||
69 | * block the calling thread in the TASK_INTERRUPTIBLE state. | ||
70 | */ | ||
71 | static inline int | ||
72 | down_interruptible (struct semaphore * sem) | ||
73 | { | ||
74 | int ret = 0; | ||
75 | |||
76 | might_sleep(); | ||
77 | if (ia64_fetchadd(-1, &sem->count.counter, acq) < 1) | ||
78 | ret = __down_interruptible(sem); | ||
79 | return ret; | ||
80 | } | ||
81 | |||
82 | static inline int | ||
83 | down_trylock (struct semaphore *sem) | ||
84 | { | ||
85 | int ret = 0; | ||
86 | |||
87 | if (ia64_fetchadd(-1, &sem->count.counter, acq) < 1) | ||
88 | ret = __down_trylock(sem); | ||
89 | return ret; | ||
90 | } | ||
91 | |||
92 | static inline void | ||
93 | up (struct semaphore * sem) | ||
94 | { | ||
95 | if (ia64_fetchadd(1, &sem->count.counter, rel) <= -1) | ||
96 | __up(sem); | ||
97 | } | ||
98 | |||
99 | #endif /* _ASM_IA64_SEMAPHORE_H */ | ||
diff --git a/include/asm-m32r/semaphore.h b/include/asm-m32r/semaphore.h index b5bf95a6f2b4..d9b2034ed1d2 100644 --- a/include/asm-m32r/semaphore.h +++ b/include/asm-m32r/semaphore.h | |||
@@ -1,144 +1 @@ | |||
1 | #ifndef _ASM_M32R_SEMAPHORE_H | #include <linux/semaphore.h> | |
2 | #define _ASM_M32R_SEMAPHORE_H | ||
3 | |||
4 | #include <linux/linkage.h> | ||
5 | |||
6 | #ifdef __KERNEL__ | ||
7 | |||
8 | /* | ||
9 | * SMP- and interrupt-safe semaphores.. | ||
10 | * | ||
11 | * Copyright (C) 1996 Linus Torvalds | ||
12 | * Copyright (C) 2004, 2006 Hirokazu Takata <takata at linux-m32r.org> | ||
13 | */ | ||
14 | |||
15 | #include <linux/wait.h> | ||
16 | #include <linux/rwsem.h> | ||
17 | #include <asm/assembler.h> | ||
18 | #include <asm/system.h> | ||
19 | #include <asm/atomic.h> | ||
20 | |||
21 | struct semaphore { | ||
22 | atomic_t count; | ||
23 | int sleepers; | ||
24 | wait_queue_head_t wait; | ||
25 | }; | ||
26 | |||
27 | #define __SEMAPHORE_INITIALIZER(name, n) \ | ||
28 | { \ | ||
29 | .count = ATOMIC_INIT(n), \ | ||
30 | .sleepers = 0, \ | ||
31 | .wait = __WAIT_QUEUE_HEAD_INITIALIZER((name).wait) \ | ||
32 | } | ||
33 | |||
34 | #define __DECLARE_SEMAPHORE_GENERIC(name,count) \ | ||
35 | struct semaphore name = __SEMAPHORE_INITIALIZER(name,count) | ||
36 | |||
37 | #define DECLARE_MUTEX(name) __DECLARE_SEMAPHORE_GENERIC(name,1) | ||
38 | |||
39 | static inline void sema_init (struct semaphore *sem, int val) | ||
40 | { | ||
41 | /* | ||
42 | * *sem = (struct semaphore)__SEMAPHORE_INITIALIZER((*sem),val); | ||
43 | * | ||
44 | * i'd rather use the more flexible initialization above, but sadly | ||
45 | * GCC 2.7.2.3 emits a bogus warning. EGCS doesnt. Oh well. | ||
46 | */ | ||
47 | atomic_set(&sem->count, val); | ||
48 | sem->sleepers = 0; | ||
49 | init_waitqueue_head(&sem->wait); | ||
50 | } | ||
51 | |||
52 | static inline void init_MUTEX (struct semaphore *sem) | ||
53 | { | ||
54 | sema_init(sem, 1); | ||
55 | } | ||
56 | |||
57 | static inline void init_MUTEX_LOCKED (struct semaphore *sem) | ||
58 | { | ||
59 | sema_init(sem, 0); | ||
60 | } | ||
61 | |||
62 | asmlinkage void __down_failed(void /* special register calling convention */); | ||
63 | asmlinkage int __down_failed_interruptible(void /* params in registers */); | ||
64 | asmlinkage int __down_failed_trylock(void /* params in registers */); | ||
65 | asmlinkage void __up_wakeup(void /* special register calling convention */); | ||
66 | |||
67 | asmlinkage void __down(struct semaphore * sem); | ||
68 | asmlinkage int __down_interruptible(struct semaphore * sem); | ||
69 | asmlinkage int __down_trylock(struct semaphore * sem); | ||
70 | asmlinkage void __up(struct semaphore * sem); | ||
71 | |||
72 | /* | ||
73 | * Atomically decrement the semaphore's count. If it goes negative, | ||
74 | * block the calling thread in the TASK_UNINTERRUPTIBLE state. | ||
75 | */ | ||
76 | static inline void down(struct semaphore * sem) | ||
77 | { | ||
78 | might_sleep(); | ||
79 | if (unlikely(atomic_dec_return(&sem->count) < 0)) | ||
80 | __down(sem); | ||
81 | } | ||
82 | |||
83 | /* | ||
84 | * Interruptible try to acquire a semaphore. If we obtained | ||
85 | * it, return zero. If we were interrupted, returns -EINTR | ||
86 | */ | ||
87 | static inline int down_interruptible(struct semaphore * sem) | ||
88 | { | ||
89 | int result = 0; | ||
90 | |||
91 | might_sleep(); | ||
92 | if (unlikely(atomic_dec_return(&sem->count) < 0)) | ||
93 | result = __down_interruptible(sem); | ||
94 | |||
95 | return result; | ||
96 | } | ||
97 | |||
98 | /* | ||
99 | * Non-blockingly attempt to down() a semaphore. | ||
100 | * Returns zero if we acquired it | ||
101 | */ | ||
102 | static inline int down_trylock(struct semaphore * sem) | ||
103 | { | ||
104 | unsigned long flags; | ||
105 | long count; | ||
106 | int result = 0; | ||
107 | |||
108 | local_irq_save(flags); | ||
109 | __asm__ __volatile__ ( | ||
110 | "# down_trylock \n\t" | ||
111 | DCACHE_CLEAR("%0", "r4", "%1") | ||
112 | M32R_LOCK" %0, @%1; \n\t" | ||
113 | "addi %0, #-1; \n\t" | ||
114 | M32R_UNLOCK" %0, @%1; \n\t" | ||
115 | : "=&r" (count) | ||
116 | : "r" (&sem->count) | ||
117 | : "memory" | ||
118 | #ifdef CONFIG_CHIP_M32700_TS1 | ||
119 | , "r4" | ||
120 | #endif /* CONFIG_CHIP_M32700_TS1 */ | ||
121 | ); | ||
122 | local_irq_restore(flags); | ||
123 | |||
124 | if (unlikely(count < 0)) | ||
125 | result = __down_trylock(sem); | ||
126 | |||
127 | return result; | ||
128 | } | ||
129 | |||
130 | /* | ||
131 | * Note! This is subtle. We jump to wake people up only if | ||
132 | * the semaphore was negative (== somebody was waiting on it). | ||
133 | * The default case (no contention) will result in NO | ||
134 | * jumps for both down() and up(). | ||
135 | */ | ||
136 | static inline void up(struct semaphore * sem) | ||
137 | { | ||
138 | if (unlikely(atomic_inc_return(&sem->count) <= 0)) | ||
139 | __up(sem); | ||
140 | } | ||
141 | |||
142 | #endif /* __KERNEL__ */ | ||
143 | |||
144 | #endif /* _ASM_M32R_SEMAPHORE_H */ | ||
diff --git a/include/asm-m68k/semaphore-helper.h b/include/asm-m68k/semaphore-helper.h deleted file mode 100644 index eef30ba0b499..000000000000 --- a/include/asm-m68k/semaphore-helper.h +++ /dev/null | |||
@@ -1,142 +0,0 @@ | |||
1 | #ifndef _M68K_SEMAPHORE_HELPER_H | ||
2 | #define _M68K_SEMAPHORE_HELPER_H | ||
3 | |||
4 | /* | ||
5 | * SMP- and interrupt-safe semaphores helper functions. | ||
6 | * | ||
7 | * (C) Copyright 1996 Linus Torvalds | ||
8 | * | ||
9 | * m68k version by Andreas Schwab | ||
10 | */ | ||
11 | |||
12 | #include <linux/errno.h> | ||
13 | |||
14 | /* | ||
15 | * These two _must_ execute atomically wrt each other. | ||
16 | */ | ||
17 | static inline void wake_one_more(struct semaphore * sem) | ||
18 | { | ||
19 | atomic_inc(&sem->waking); | ||
20 | } | ||
21 | |||
22 | #ifndef CONFIG_RMW_INSNS | ||
23 | extern spinlock_t semaphore_wake_lock; | ||
24 | #endif | ||
25 | |||
26 | static inline int waking_non_zero(struct semaphore *sem) | ||
27 | { | ||
28 | int ret; | ||
29 | #ifndef CONFIG_RMW_INSNS | ||
30 | unsigned long flags; | ||
31 | |||
32 | spin_lock_irqsave(&semaphore_wake_lock, flags); | ||
33 | ret = 0; | ||
34 | if (atomic_read(&sem->waking) > 0) { | ||
35 | atomic_dec(&sem->waking); | ||
36 | ret = 1; | ||
37 | } | ||
38 | spin_unlock_irqrestore(&semaphore_wake_lock, flags); | ||
39 | #else | ||
40 | int tmp1, tmp2; | ||
41 | |||
42 | __asm__ __volatile__ | ||
43 | ("1: movel %1,%2\n" | ||
44 | " jle 2f\n" | ||
45 | " subql #1,%2\n" | ||
46 | " casl %1,%2,%3\n" | ||
47 | " jne 1b\n" | ||
48 | " moveq #1,%0\n" | ||
49 | "2:" | ||
50 | : "=d" (ret), "=d" (tmp1), "=d" (tmp2) | ||
51 | : "m" (sem->waking), "0" (0), "1" (sem->waking)); | ||
52 | #endif | ||
53 | |||
54 | return ret; | ||
55 | } | ||
56 | |||
57 | /* | ||
58 | * waking_non_zero_interruptible: | ||
59 | * 1 got the lock | ||
60 | * 0 go to sleep | ||
61 | * -EINTR interrupted | ||
62 | */ | ||
63 | static inline int waking_non_zero_interruptible(struct semaphore *sem, | ||
64 | struct task_struct *tsk) | ||
65 | { | ||
66 | int ret; | ||
67 | #ifndef CONFIG_RMW_INSNS | ||
68 | unsigned long flags; | ||
69 | |||
70 | spin_lock_irqsave(&semaphore_wake_lock, flags); | ||
71 | ret = 0; | ||
72 | if (atomic_read(&sem->waking) > 0) { | ||
73 | atomic_dec(&sem->waking); | ||
74 | ret = 1; | ||
75 | } else if (signal_pending(tsk)) { | ||
76 | atomic_inc(&sem->count); | ||
77 | ret = -EINTR; | ||
78 | } | ||
79 | spin_unlock_irqrestore(&semaphore_wake_lock, flags); | ||
80 | #else | ||
81 | int tmp1, tmp2; | ||
82 | |||
83 | __asm__ __volatile__ | ||
84 | ("1: movel %1,%2\n" | ||
85 | " jle 2f\n" | ||
86 | " subql #1,%2\n" | ||
87 | " casl %1,%2,%3\n" | ||
88 | " jne 1b\n" | ||
89 | " moveq #1,%0\n" | ||
90 | " jra %a4\n" | ||
91 | "2:" | ||
92 | : "=d" (ret), "=d" (tmp1), "=d" (tmp2) | ||
93 | : "m" (sem->waking), "i" (&&next), "0" (0), "1" (sem->waking)); | ||
94 | if (signal_pending(tsk)) { | ||
95 | atomic_inc(&sem->count); | ||
96 | ret = -EINTR; | ||
97 | } | ||
98 | next: | ||
99 | #endif | ||
100 | |||
101 | return ret; | ||
102 | } | ||
103 | |||
104 | /* | ||
105 | * waking_non_zero_trylock: | ||
106 | * 1 failed to lock | ||
107 | * 0 got the lock | ||
108 | */ | ||
109 | static inline int waking_non_zero_trylock(struct semaphore *sem) | ||
110 | { | ||
111 | int ret; | ||
112 | #ifndef CONFIG_RMW_INSNS | ||
113 | unsigned long flags; | ||
114 | |||
115 | spin_lock_irqsave(&semaphore_wake_lock, flags); | ||
116 | ret = 1; | ||
117 | if (atomic_read(&sem->waking) > 0) { | ||
118 | atomic_dec(&sem->waking); | ||
119 | ret = 0; | ||
120 | } else | ||
121 | atomic_inc(&sem->count); | ||
122 | spin_unlock_irqrestore(&semaphore_wake_lock, flags); | ||
123 | #else | ||
124 | int tmp1, tmp2; | ||
125 | |||
126 | __asm__ __volatile__ | ||
127 | ("1: movel %1,%2\n" | ||
128 | " jle 2f\n" | ||
129 | " subql #1,%2\n" | ||
130 | " casl %1,%2,%3\n" | ||
131 | " jne 1b\n" | ||
132 | " moveq #0,%0\n" | ||
133 | "2:" | ||
134 | : "=d" (ret), "=d" (tmp1), "=d" (tmp2) | ||
135 | : "m" (sem->waking), "0" (1), "1" (sem->waking)); | ||
136 | if (ret) | ||
137 | atomic_inc(&sem->count); | ||
138 | #endif | ||
139 | return ret; | ||
140 | } | ||
141 | |||
142 | #endif | ||
diff --git a/include/asm-m68k/semaphore.h b/include/asm-m68k/semaphore.h index 64d6b119bb0a..d9b2034ed1d2 100644 --- a/include/asm-m68k/semaphore.h +++ b/include/asm-m68k/semaphore.h | |||
@@ -1,163 +1 @@ | |||
1 | #ifndef _M68K_SEMAPHORE_H | #include <linux/semaphore.h> | |
2 | #define _M68K_SEMAPHORE_H | ||
3 | |||
4 | #define RW_LOCK_BIAS 0x01000000 | ||
5 | |||
6 | #ifndef __ASSEMBLY__ | ||
7 | |||
8 | #include <linux/linkage.h> | ||
9 | #include <linux/wait.h> | ||
10 | #include <linux/spinlock.h> | ||
11 | #include <linux/rwsem.h> | ||
12 | #include <linux/stringify.h> | ||
13 | |||
14 | #include <asm/system.h> | ||
15 | #include <asm/atomic.h> | ||
16 | |||
17 | /* | ||
18 | * Interrupt-safe semaphores.. | ||
19 | * | ||
20 | * (C) Copyright 1996 Linus Torvalds | ||
21 | * | ||
22 | * m68k version by Andreas Schwab | ||
23 | */ | ||
24 | |||
25 | |||
26 | struct semaphore { | ||
27 | atomic_t count; | ||
28 | atomic_t waking; | ||
29 | wait_queue_head_t wait; | ||
30 | }; | ||
31 | |||
32 | #define __SEMAPHORE_INITIALIZER(name, n) \ | ||
33 | { \ | ||
34 | .count = ATOMIC_INIT(n), \ | ||
35 | .waking = ATOMIC_INIT(0), \ | ||
36 | .wait = __WAIT_QUEUE_HEAD_INITIALIZER((name).wait) \ | ||
37 | } | ||
38 | |||
39 | #define __DECLARE_SEMAPHORE_GENERIC(name,count) \ | ||
40 | struct semaphore name = __SEMAPHORE_INITIALIZER(name,count) | ||
41 | |||
42 | #define DECLARE_MUTEX(name) __DECLARE_SEMAPHORE_GENERIC(name,1) | ||
43 | |||
44 | static inline void sema_init(struct semaphore *sem, int val) | ||
45 | { | ||
46 | *sem = (struct semaphore)__SEMAPHORE_INITIALIZER(*sem, val); | ||
47 | } | ||
48 | |||
49 | static inline void init_MUTEX (struct semaphore *sem) | ||
50 | { | ||
51 | sema_init(sem, 1); | ||
52 | } | ||
53 | |||
54 | static inline void init_MUTEX_LOCKED (struct semaphore *sem) | ||
55 | { | ||
56 | sema_init(sem, 0); | ||
57 | } | ||
58 | |||
59 | asmlinkage void __down_failed(void /* special register calling convention */); | ||
60 | asmlinkage int __down_failed_interruptible(void /* params in registers */); | ||
61 | asmlinkage int __down_failed_trylock(void /* params in registers */); | ||
62 | asmlinkage void __up_wakeup(void /* special register calling convention */); | ||
63 | |||
64 | asmlinkage void __down(struct semaphore * sem); | ||
65 | asmlinkage int __down_interruptible(struct semaphore * sem); | ||
66 | asmlinkage int __down_trylock(struct semaphore * sem); | ||
67 | asmlinkage void __up(struct semaphore * sem); | ||
68 | |||
69 | /* | ||
70 | * This is ugly, but we want the default case to fall through. | ||
71 | * "down_failed" is a special asm handler that calls the C | ||
72 | * routine that actually waits. See arch/m68k/lib/semaphore.S | ||
73 | */ | ||
74 | static inline void down(struct semaphore *sem) | ||
75 | { | ||
76 | register struct semaphore *sem1 __asm__ ("%a1") = sem; | ||
77 | |||
78 | might_sleep(); | ||
79 | __asm__ __volatile__( | ||
80 | "| atomic down operation\n\t" | ||
81 | "subql #1,%0@\n\t" | ||
82 | "jmi 2f\n\t" | ||
83 | "1:\n" | ||
84 | LOCK_SECTION_START(".even\n\t") | ||
85 | "2:\tpea 1b\n\t" | ||
86 | "jbra __down_failed\n" | ||
87 | LOCK_SECTION_END | ||
88 | : /* no outputs */ | ||
89 | : "a" (sem1) | ||
90 | : "memory"); | ||
91 | } | ||
92 | |||
93 | static inline int down_interruptible(struct semaphore *sem) | ||
94 | { | ||
95 | register struct semaphore *sem1 __asm__ ("%a1") = sem; | ||
96 | register int result __asm__ ("%d0"); | ||
97 | |||
98 | might_sleep(); | ||
99 | __asm__ __volatile__( | ||
100 | "| atomic interruptible down operation\n\t" | ||
101 | "subql #1,%1@\n\t" | ||
102 | "jmi 2f\n\t" | ||
103 | "clrl %0\n" | ||
104 | "1:\n" | ||
105 | LOCK_SECTION_START(".even\n\t") | ||
106 | "2:\tpea 1b\n\t" | ||
107 | "jbra __down_failed_interruptible\n" | ||
108 | LOCK_SECTION_END | ||
109 | : "=d" (result) | ||
110 | : "a" (sem1) | ||
111 | : "memory"); | ||
112 | return result; | ||
113 | } | ||
114 | |||
115 | static inline int down_trylock(struct semaphore *sem) | ||
116 | { | ||
117 | register struct semaphore *sem1 __asm__ ("%a1") = sem; | ||
118 | register int result __asm__ ("%d0"); | ||
119 | |||
120 | __asm__ __volatile__( | ||
121 | "| atomic down trylock operation\n\t" | ||
122 | "subql #1,%1@\n\t" | ||
123 | "jmi 2f\n\t" | ||
124 | "clrl %0\n" | ||
125 | "1:\n" | ||
126 | LOCK_SECTION_START(".even\n\t") | ||
127 | "2:\tpea 1b\n\t" | ||
128 | "jbra __down_failed_trylock\n" | ||
129 | LOCK_SECTION_END | ||
130 | : "=d" (result) | ||
131 | : "a" (sem1) | ||
132 | : "memory"); | ||
133 | return result; | ||
134 | } | ||
135 | |||
136 | /* | ||
137 | * Note! This is subtle. We jump to wake people up only if | ||
138 | * the semaphore was negative (== somebody was waiting on it). | ||
139 | * The default case (no contention) will result in NO | ||
140 | * jumps for both down() and up(). | ||
141 | */ | ||
142 | static inline void up(struct semaphore *sem) | ||
143 | { | ||
144 | register struct semaphore *sem1 __asm__ ("%a1") = sem; | ||
145 | |||
146 | __asm__ __volatile__( | ||
147 | "| atomic up operation\n\t" | ||
148 | "addql #1,%0@\n\t" | ||
149 | "jle 2f\n" | ||
150 | "1:\n" | ||
151 | LOCK_SECTION_START(".even\n\t") | ||
152 | "2:\t" | ||
153 | "pea 1b\n\t" | ||
154 | "jbra __up_wakeup\n" | ||
155 | LOCK_SECTION_END | ||
156 | : /* no outputs */ | ||
157 | : "a" (sem1) | ||
158 | : "memory"); | ||
159 | } | ||
160 | |||
161 | #endif /* __ASSEMBLY__ */ | ||
162 | |||
163 | #endif | ||
diff --git a/include/asm-m68knommu/semaphore-helper.h b/include/asm-m68knommu/semaphore-helper.h deleted file mode 100644 index 43da7bc483c7..000000000000 --- a/include/asm-m68knommu/semaphore-helper.h +++ /dev/null | |||
@@ -1,82 +0,0 @@ | |||
1 | #ifndef _M68K_SEMAPHORE_HELPER_H | ||
2 | #define _M68K_SEMAPHORE_HELPER_H | ||
3 | |||
4 | /* | ||
5 | * SMP- and interrupt-safe semaphores helper functions. | ||
6 | * | ||
7 | * (C) Copyright 1996 Linus Torvalds | ||
8 | * | ||
9 | * m68k version by Andreas Schwab | ||
10 | */ | ||
11 | |||
12 | |||
13 | /* | ||
14 | * These two _must_ execute atomically wrt each other. | ||
15 | */ | ||
16 | static inline void wake_one_more(struct semaphore * sem) | ||
17 | { | ||
18 | atomic_inc(&sem->waking); | ||
19 | } | ||
20 | |||
21 | static inline int waking_non_zero(struct semaphore *sem) | ||
22 | { | ||
23 | int ret; | ||
24 | unsigned long flags; | ||
25 | |||
26 | spin_lock_irqsave(&semaphore_wake_lock, flags); | ||
27 | ret = 0; | ||
28 | if (atomic_read(&sem->waking) > 0) { | ||
29 | atomic_dec(&sem->waking); | ||
30 | ret = 1; | ||
31 | } | ||
32 | spin_unlock_irqrestore(&semaphore_wake_lock, flags); | ||
33 | return ret; | ||
34 | } | ||
35 | |||
36 | /* | ||
37 | * waking_non_zero_interruptible: | ||
38 | * 1 got the lock | ||
39 | * 0 go to sleep | ||
40 | * -EINTR interrupted | ||
41 | */ | ||
42 | static inline int waking_non_zero_interruptible(struct semaphore *sem, | ||
43 | struct task_struct *tsk) | ||
44 | { | ||
45 | int ret; | ||
46 | unsigned long flags; | ||
47 | |||
48 | spin_lock_irqsave(&semaphore_wake_lock, flags); | ||
49 | ret = 0; | ||
50 | if (atomic_read(&sem->waking) > 0) { | ||
51 | atomic_dec(&sem->waking); | ||
52 | ret = 1; | ||
53 | } else if (signal_pending(tsk)) { | ||
54 | atomic_inc(&sem->count); | ||
55 | ret = -EINTR; | ||
56 | } | ||
57 | spin_unlock_irqrestore(&semaphore_wake_lock, flags); | ||
58 | return ret; | ||
59 | } | ||
60 | |||
61 | /* | ||
62 | * waking_non_zero_trylock: | ||
63 | * 1 failed to lock | ||
64 | * 0 got the lock | ||
65 | */ | ||
66 | static inline int waking_non_zero_trylock(struct semaphore *sem) | ||
67 | { | ||
68 | int ret; | ||
69 | unsigned long flags; | ||
70 | |||
71 | spin_lock_irqsave(&semaphore_wake_lock, flags); | ||
72 | ret = 1; | ||
73 | if (atomic_read(&sem->waking) > 0) { | ||
74 | atomic_dec(&sem->waking); | ||
75 | ret = 0; | ||
76 | } else | ||
77 | atomic_inc(&sem->count); | ||
78 | spin_unlock_irqrestore(&semaphore_wake_lock, flags); | ||
79 | return ret; | ||
80 | } | ||
81 | |||
82 | #endif | ||
diff --git a/include/asm-m68knommu/semaphore.h b/include/asm-m68knommu/semaphore.h index 5779eb6c0689..d9b2034ed1d2 100644 --- a/include/asm-m68knommu/semaphore.h +++ b/include/asm-m68knommu/semaphore.h | |||
@@ -1,153 +1 @@ | |||
1 | #ifndef _M68K_SEMAPHORE_H | #include <linux/semaphore.h> | |
2 | #define _M68K_SEMAPHORE_H | ||
3 | |||
4 | #define RW_LOCK_BIAS 0x01000000 | ||
5 | |||
6 | #ifndef __ASSEMBLY__ | ||
7 | |||
8 | #include <linux/linkage.h> | ||
9 | #include <linux/wait.h> | ||
10 | #include <linux/spinlock.h> | ||
11 | #include <linux/rwsem.h> | ||
12 | |||
13 | #include <asm/system.h> | ||
14 | #include <asm/atomic.h> | ||
15 | |||
16 | /* | ||
17 | * Interrupt-safe semaphores.. | ||
18 | * | ||
19 | * (C) Copyright 1996 Linus Torvalds | ||
20 | * | ||
21 | * m68k version by Andreas Schwab | ||
22 | */ | ||
23 | |||
24 | |||
25 | struct semaphore { | ||
26 | atomic_t count; | ||
27 | atomic_t waking; | ||
28 | wait_queue_head_t wait; | ||
29 | }; | ||
30 | |||
31 | #define __SEMAPHORE_INITIALIZER(name, n) \ | ||
32 | { \ | ||
33 | .count = ATOMIC_INIT(n), \ | ||
34 | .waking = ATOMIC_INIT(0), \ | ||
35 | .wait = __WAIT_QUEUE_HEAD_INITIALIZER((name).wait) \ | ||
36 | } | ||
37 | |||
38 | #define __DECLARE_SEMAPHORE_GENERIC(name,count) \ | ||
39 | struct semaphore name = __SEMAPHORE_INITIALIZER(name,count) | ||
40 | |||
41 | #define DECLARE_MUTEX(name) __DECLARE_SEMAPHORE_GENERIC(name,1) | ||
42 | |||
43 | static inline void sema_init (struct semaphore *sem, int val) | ||
44 | { | ||
45 | *sem = (struct semaphore)__SEMAPHORE_INITIALIZER(*sem, val); | ||
46 | } | ||
47 | |||
48 | static inline void init_MUTEX (struct semaphore *sem) | ||
49 | { | ||
50 | sema_init(sem, 1); | ||
51 | } | ||
52 | |||
53 | static inline void init_MUTEX_LOCKED (struct semaphore *sem) | ||
54 | { | ||
55 | sema_init(sem, 0); | ||
56 | } | ||
57 | |||
58 | asmlinkage void __down_failed(void /* special register calling convention */); | ||
59 | asmlinkage int __down_failed_interruptible(void /* params in registers */); | ||
60 | asmlinkage int __down_failed_trylock(void /* params in registers */); | ||
61 | asmlinkage void __up_wakeup(void /* special register calling convention */); | ||
62 | |||
63 | asmlinkage void __down(struct semaphore * sem); | ||
64 | asmlinkage int __down_interruptible(struct semaphore * sem); | ||
65 | asmlinkage int __down_trylock(struct semaphore * sem); | ||
66 | asmlinkage void __up(struct semaphore * sem); | ||
67 | |||
68 | extern spinlock_t semaphore_wake_lock; | ||
69 | |||
70 | /* | ||
71 | * This is ugly, but we want the default case to fall through. | ||
72 | * "down_failed" is a special asm handler that calls the C | ||
73 | * routine that actually waits. See arch/m68k/lib/semaphore.S | ||
74 | */ | ||
75 | static inline void down(struct semaphore * sem) | ||
76 | { | ||
77 | might_sleep(); | ||
78 | __asm__ __volatile__( | ||
79 | "| atomic down operation\n\t" | ||
80 | "movel %0, %%a1\n\t" | ||
81 | "lea %%pc@(1f), %%a0\n\t" | ||
82 | "subql #1, %%a1@\n\t" | ||
83 | "jmi __down_failed\n" | ||
84 | "1:" | ||
85 | : /* no outputs */ | ||
86 | : "g" (sem) | ||
87 | : "cc", "%a0", "%a1", "memory"); | ||
88 | } | ||
89 | |||
90 | static inline int down_interruptible(struct semaphore * sem) | ||
91 | { | ||
92 | int ret; | ||
93 | |||
94 | might_sleep(); | ||
95 | __asm__ __volatile__( | ||
96 | "| atomic down operation\n\t" | ||
97 | "movel %1, %%a1\n\t" | ||
98 | "lea %%pc@(1f), %%a0\n\t" | ||
99 | "subql #1, %%a1@\n\t" | ||
100 | "jmi __down_failed_interruptible\n\t" | ||
101 | "clrl %%d0\n" | ||
102 | "1: movel %%d0, %0\n" | ||
103 | : "=d" (ret) | ||
104 | : "g" (sem) | ||
105 | : "cc", "%d0", "%a0", "%a1", "memory"); | ||
106 | return(ret); | ||
107 | } | ||
108 | |||
109 | static inline int down_trylock(struct semaphore * sem) | ||
110 | { | ||
111 | register struct semaphore *sem1 __asm__ ("%a1") = sem; | ||
112 | register int result __asm__ ("%d0"); | ||
113 | |||
114 | __asm__ __volatile__( | ||
115 | "| atomic down trylock operation\n\t" | ||
116 | "subql #1,%1@\n\t" | ||
117 | "jmi 2f\n\t" | ||
118 | "clrl %0\n" | ||
119 | "1:\n" | ||
120 | ".section .text.lock,\"ax\"\n" | ||
121 | ".even\n" | ||
122 | "2:\tpea 1b\n\t" | ||
123 | "jbra __down_failed_trylock\n" | ||
124 | ".previous" | ||
125 | : "=d" (result) | ||
126 | : "a" (sem1) | ||
127 | : "memory"); | ||
128 | return result; | ||
129 | } | ||
130 | |||
131 | /* | ||
132 | * Note! This is subtle. We jump to wake people up only if | ||
133 | * the semaphore was negative (== somebody was waiting on it). | ||
134 | * The default case (no contention) will result in NO | ||
135 | * jumps for both down() and up(). | ||
136 | */ | ||
137 | static inline void up(struct semaphore * sem) | ||
138 | { | ||
139 | __asm__ __volatile__( | ||
140 | "| atomic up operation\n\t" | ||
141 | "movel %0, %%a1\n\t" | ||
142 | "lea %%pc@(1f), %%a0\n\t" | ||
143 | "addql #1, %%a1@\n\t" | ||
144 | "jle __up_wakeup\n" | ||
145 | "1:" | ||
146 | : /* no outputs */ | ||
147 | : "g" (sem) | ||
148 | : "cc", "%a0", "%a1", "memory"); | ||
149 | } | ||
150 | |||
151 | #endif /* __ASSEMBLY__ */ | ||
152 | |||
153 | #endif | ||
diff --git a/include/asm-mips/semaphore.h b/include/asm-mips/semaphore.h index fdf8042b784b..d9b2034ed1d2 100644 --- a/include/asm-mips/semaphore.h +++ b/include/asm-mips/semaphore.h | |||
@@ -1,108 +1 @@ | |||
1 | /* | #include <linux/semaphore.h> | |
2 | * This file is subject to the terms and conditions of the GNU General Public | ||
3 | * License. See the file "COPYING" in the main directory of this archive | ||
4 | * for more details. | ||
5 | * | ||
6 | * Copyright (C) 1996 Linus Torvalds | ||
7 | * Copyright (C) 1998, 99, 2000, 01, 04 Ralf Baechle | ||
8 | * Copyright (C) 1999, 2000, 01 Silicon Graphics, Inc. | ||
9 | * Copyright (C) 2000, 01 MIPS Technologies, Inc. | ||
10 | * | ||
11 | * In all honesty, little of the old MIPS code left - the PPC64 variant was | ||
12 | * just looking nice and portable so I ripped it. Credits to whoever wrote | ||
13 | * it. | ||
14 | */ | ||
15 | #ifndef __ASM_SEMAPHORE_H | ||
16 | #define __ASM_SEMAPHORE_H | ||
17 | |||
18 | /* | ||
19 | * Remove spinlock-based RW semaphores; RW semaphore definitions are | ||
20 | * now in rwsem.h and we use the generic lib/rwsem.c implementation. | ||
21 | * Rework semaphores to use atomic_dec_if_positive. | ||
22 | * -- Paul Mackerras (paulus@samba.org) | ||
23 | */ | ||
24 | |||
25 | #ifdef __KERNEL__ | ||
26 | |||
27 | #include <asm/atomic.h> | ||
28 | #include <asm/system.h> | ||
29 | #include <linux/wait.h> | ||
30 | #include <linux/rwsem.h> | ||
31 | |||
32 | struct semaphore { | ||
33 | /* | ||
34 | * Note that any negative value of count is equivalent to 0, | ||
35 | * but additionally indicates that some process(es) might be | ||
36 | * sleeping on `wait'. | ||
37 | */ | ||
38 | atomic_t count; | ||
39 | wait_queue_head_t wait; | ||
40 | }; | ||
41 | |||
42 | #define __SEMAPHORE_INITIALIZER(name, n) \ | ||
43 | { \ | ||
44 | .count = ATOMIC_INIT(n), \ | ||
45 | .wait = __WAIT_QUEUE_HEAD_INITIALIZER((name).wait) \ | ||
46 | } | ||
47 | |||
48 | #define __DECLARE_SEMAPHORE_GENERIC(name, count) \ | ||
49 | struct semaphore name = __SEMAPHORE_INITIALIZER(name, count) | ||
50 | |||
51 | #define DECLARE_MUTEX(name) __DECLARE_SEMAPHORE_GENERIC(name, 1) | ||
52 | |||
53 | static inline void sema_init(struct semaphore *sem, int val) | ||
54 | { | ||
55 | atomic_set(&sem->count, val); | ||
56 | init_waitqueue_head(&sem->wait); | ||
57 | } | ||
58 | |||
59 | static inline void init_MUTEX(struct semaphore *sem) | ||
60 | { | ||
61 | sema_init(sem, 1); | ||
62 | } | ||
63 | |||
64 | static inline void init_MUTEX_LOCKED(struct semaphore *sem) | ||
65 | { | ||
66 | sema_init(sem, 0); | ||
67 | } | ||
68 | |||
69 | extern void __down(struct semaphore * sem); | ||
70 | extern int __down_interruptible(struct semaphore * sem); | ||
71 | extern void __up(struct semaphore * sem); | ||
72 | |||
73 | static inline void down(struct semaphore * sem) | ||
74 | { | ||
75 | might_sleep(); | ||
76 | |||
77 | /* | ||
78 | * Try to get the semaphore, take the slow path if we fail. | ||
79 | */ | ||
80 | if (unlikely(atomic_dec_return(&sem->count) < 0)) | ||
81 | __down(sem); | ||
82 | } | ||
83 | |||
84 | static inline int down_interruptible(struct semaphore * sem) | ||
85 | { | ||
86 | int ret = 0; | ||
87 | |||
88 | might_sleep(); | ||
89 | |||
90 | if (unlikely(atomic_dec_return(&sem->count) < 0)) | ||
91 | ret = __down_interruptible(sem); | ||
92 | return ret; | ||
93 | } | ||
94 | |||
95 | static inline int down_trylock(struct semaphore * sem) | ||
96 | { | ||
97 | return atomic_dec_if_positive(&sem->count) < 0; | ||
98 | } | ||
99 | |||
100 | static inline void up(struct semaphore * sem) | ||
101 | { | ||
102 | if (unlikely(atomic_inc_return(&sem->count) <= 0)) | ||
103 | __up(sem); | ||
104 | } | ||
105 | |||
106 | #endif /* __KERNEL__ */ | ||
107 | |||
108 | #endif /* __ASM_SEMAPHORE_H */ | ||
diff --git a/include/asm-mn10300/semaphore.h b/include/asm-mn10300/semaphore.h index 5a9e1ad0b253..d9b2034ed1d2 100644 --- a/include/asm-mn10300/semaphore.h +++ b/include/asm-mn10300/semaphore.h | |||
@@ -1,169 +1 @@ | |||
1 | /* MN10300 Semaphores | #include <linux/semaphore.h> | |
2 | * | ||
3 | * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved. | ||
4 | * Written by David Howells (dhowells@redhat.com) | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or | ||
7 | * modify it under the terms of the GNU General Public Licence | ||
8 | * as published by the Free Software Foundation; either version | ||
9 | * 2 of the Licence, or (at your option) any later version. | ||
10 | */ | ||
11 | #ifndef _ASM_SEMAPHORE_H | ||
12 | #define _ASM_SEMAPHORE_H | ||
13 | |||
14 | #ifndef __ASSEMBLY__ | ||
15 | |||
16 | #include <linux/linkage.h> | ||
17 | #include <linux/wait.h> | ||
18 | #include <linux/spinlock.h> | ||
19 | #include <linux/rwsem.h> | ||
20 | |||
21 | #define SEMAPHORE_DEBUG 0 | ||
22 | |||
23 | /* | ||
24 | * the semaphore definition | ||
25 | * - if count is >0 then there are tokens available on the semaphore for down | ||
26 | * to collect | ||
27 | * - if count is <=0 then there are no spare tokens, and anyone that wants one | ||
28 | * must wait | ||
29 | * - if wait_list is not empty, then there are processes waiting for the | ||
30 | * semaphore | ||
31 | */ | ||
32 | struct semaphore { | ||
33 | atomic_t count; /* it's not really atomic, it's | ||
34 | * just that certain modules | ||
35 | * expect to be able to access | ||
36 | * it directly */ | ||
37 | spinlock_t wait_lock; | ||
38 | struct list_head wait_list; | ||
39 | #if SEMAPHORE_DEBUG | ||
40 | unsigned __magic; | ||
41 | #endif | ||
42 | }; | ||
43 | |||
44 | #if SEMAPHORE_DEBUG | ||
45 | # define __SEM_DEBUG_INIT(name) , (long)&(name).__magic | ||
46 | #else | ||
47 | # define __SEM_DEBUG_INIT(name) | ||
48 | #endif | ||
49 | |||
50 | |||
51 | #define __SEMAPHORE_INITIALIZER(name, init_count) \ | ||
52 | { \ | ||
53 | .count = ATOMIC_INIT(init_count), \ | ||
54 | .wait_lock = __SPIN_LOCK_UNLOCKED((name).wait_lock), \ | ||
55 | .wait_list = LIST_HEAD_INIT((name).wait_list) \ | ||
56 | __SEM_DEBUG_INIT(name) \ | ||
57 | } | ||
58 | |||
59 | #define __DECLARE_SEMAPHORE_GENERIC(name,count) \ | ||
60 | struct semaphore name = __SEMAPHORE_INITIALIZER(name, count) | ||
61 | |||
62 | #define DECLARE_MUTEX(name) __DECLARE_SEMAPHORE_GENERIC(name, 1) | ||
63 | #define DECLARE_MUTEX_LOCKED(name) __DECLARE_SEMAPHORE_GENERIC(name, 0) | ||
64 | |||
65 | static inline void sema_init(struct semaphore *sem, int val) | ||
66 | { | ||
67 | *sem = (struct semaphore) __SEMAPHORE_INITIALIZER(*sem, val); | ||
68 | } | ||
69 | |||
70 | static inline void init_MUTEX(struct semaphore *sem) | ||
71 | { | ||
72 | sema_init(sem, 1); | ||
73 | } | ||
74 | |||
75 | static inline void init_MUTEX_LOCKED(struct semaphore *sem) | ||
76 | { | ||
77 | sema_init(sem, 0); | ||
78 | } | ||
79 | |||
80 | extern void __down(struct semaphore *sem, unsigned long flags); | ||
81 | extern int __down_interruptible(struct semaphore *sem, unsigned long flags); | ||
82 | extern void __up(struct semaphore *sem); | ||
83 | |||
84 | static inline void down(struct semaphore *sem) | ||
85 | { | ||
86 | unsigned long flags; | ||
87 | int count; | ||
88 | |||
89 | #if SEMAPHORE_DEBUG | ||
90 | CHECK_MAGIC(sem->__magic); | ||
91 | #endif | ||
92 | |||
93 | spin_lock_irqsave(&sem->wait_lock, flags); | ||
94 | count = atomic_read(&sem->count); | ||
95 | if (likely(count > 0)) { | ||
96 | atomic_set(&sem->count, count - 1); | ||
97 | spin_unlock_irqrestore(&sem->wait_lock, flags); | ||
98 | } else { | ||
99 | __down(sem, flags); | ||
100 | } | ||
101 | } | ||
102 | |||
103 | static inline int down_interruptible(struct semaphore *sem) | ||
104 | { | ||
105 | unsigned long flags; | ||
106 | int count, ret = 0; | ||
107 | |||
108 | #if SEMAPHORE_DEBUG | ||
109 | CHECK_MAGIC(sem->__magic); | ||
110 | #endif | ||
111 | |||
112 | spin_lock_irqsave(&sem->wait_lock, flags); | ||
113 | count = atomic_read(&sem->count); | ||
114 | if (likely(count > 0)) { | ||
115 | atomic_set(&sem->count, count - 1); | ||
116 | spin_unlock_irqrestore(&sem->wait_lock, flags); | ||
117 | } else { | ||
118 | ret = __down_interruptible(sem, flags); | ||
119 | } | ||
120 | return ret; | ||
121 | } | ||
122 | |||
123 | /* | ||
124 | * non-blockingly attempt to down() a semaphore. | ||
125 | * - returns zero if we acquired it | ||
126 | */ | ||
127 | static inline int down_trylock(struct semaphore *sem) | ||
128 | { | ||
129 | unsigned long flags; | ||
130 | int count, success = 0; | ||
131 | |||
132 | #if SEMAPHORE_DEBUG | ||
133 | CHECK_MAGIC(sem->__magic); | ||
134 | #endif | ||
135 | |||
136 | spin_lock_irqsave(&sem->wait_lock, flags); | ||
137 | count = atomic_read(&sem->count); | ||
138 | if (likely(count > 0)) { | ||
139 | atomic_set(&sem->count, count - 1); | ||
140 | success = 1; | ||
141 | } | ||
142 | spin_unlock_irqrestore(&sem->wait_lock, flags); | ||
143 | return !success; | ||
144 | } | ||
145 | |||
146 | static inline void up(struct semaphore *sem) | ||
147 | { | ||
148 | unsigned long flags; | ||
149 | |||
150 | #if SEMAPHORE_DEBUG | ||
151 | CHECK_MAGIC(sem->__magic); | ||
152 | #endif | ||
153 | |||
154 | spin_lock_irqsave(&sem->wait_lock, flags); | ||
155 | if (!list_empty(&sem->wait_list)) | ||
156 | __up(sem); | ||
157 | else | ||
158 | atomic_set(&sem->count, atomic_read(&sem->count) + 1); | ||
159 | spin_unlock_irqrestore(&sem->wait_lock, flags); | ||
160 | } | ||
161 | |||
162 | static inline int sem_getcount(struct semaphore *sem) | ||
163 | { | ||
164 | return atomic_read(&sem->count); | ||
165 | } | ||
166 | |||
167 | #endif /* __ASSEMBLY__ */ | ||
168 | |||
169 | #endif | ||
diff --git a/include/asm-parisc/semaphore-helper.h b/include/asm-parisc/semaphore-helper.h deleted file mode 100644 index 387f7c1277a2..000000000000 --- a/include/asm-parisc/semaphore-helper.h +++ /dev/null | |||
@@ -1,89 +0,0 @@ | |||
1 | #ifndef _ASM_PARISC_SEMAPHORE_HELPER_H | ||
2 | #define _ASM_PARISC_SEMAPHORE_HELPER_H | ||
3 | |||
4 | /* | ||
5 | * SMP- and interrupt-safe semaphores helper functions. | ||
6 | * | ||
7 | * (C) Copyright 1996 Linus Torvalds | ||
8 | * (C) Copyright 1999 Andrea Arcangeli | ||
9 | */ | ||
10 | |||
11 | /* | ||
12 | * These two _must_ execute atomically wrt each other. | ||
13 | * | ||
14 | * This is trivially done with load_locked/store_cond, | ||
15 | * which we have. Let the rest of the losers suck eggs. | ||
16 | */ | ||
17 | static __inline__ void wake_one_more(struct semaphore * sem) | ||
18 | { | ||
19 | atomic_inc((atomic_t *)&sem->waking); | ||
20 | } | ||
21 | |||
22 | static __inline__ int waking_non_zero(struct semaphore *sem) | ||
23 | { | ||
24 | unsigned long flags; | ||
25 | int ret = 0; | ||
26 | |||
27 | spin_lock_irqsave(&semaphore_wake_lock, flags); | ||
28 | if (sem->waking > 0) { | ||
29 | sem->waking--; | ||
30 | ret = 1; | ||
31 | } | ||
32 | spin_unlock_irqrestore(&semaphore_wake_lock, flags); | ||
33 | return ret; | ||
34 | } | ||
35 | |||
36 | /* | ||
37 | * waking_non_zero_interruptible: | ||
38 | * 1 got the lock | ||
39 | * 0 go to sleep | ||
40 | * -EINTR interrupted | ||
41 | * | ||
42 | * We must undo the sem->count down_interruptible() increment while we are | ||
43 | * protected by the spinlock in order to make atomic this atomic_inc() with the | ||
44 | * atomic_read() in wake_one_more(), otherwise we can race. -arca | ||
45 | */ | ||
46 | static __inline__ int waking_non_zero_interruptible(struct semaphore *sem, | ||
47 | struct task_struct *tsk) | ||
48 | { | ||
49 | unsigned long flags; | ||
50 | int ret = 0; | ||
51 | |||
52 | spin_lock_irqsave(&semaphore_wake_lock, flags); | ||
53 | if (sem->waking > 0) { | ||
54 | sem->waking--; | ||
55 | ret = 1; | ||
56 | } else if (signal_pending(tsk)) { | ||
57 | atomic_inc(&sem->count); | ||
58 | ret = -EINTR; | ||
59 | } | ||
60 | spin_unlock_irqrestore(&semaphore_wake_lock, flags); | ||
61 | return ret; | ||
62 | } | ||
63 | |||
64 | /* | ||
65 | * waking_non_zero_trylock: | ||
66 | * 1 failed to lock | ||
67 | * 0 got the lock | ||
68 | * | ||
69 | * We must undo the sem->count down_trylock() increment while we are | ||
70 | * protected by the spinlock in order to make atomic this atomic_inc() with the | ||
71 | * atomic_read() in wake_one_more(), otherwise we can race. -arca | ||
72 | */ | ||
73 | static __inline__ int waking_non_zero_trylock(struct semaphore *sem) | ||
74 | { | ||
75 | unsigned long flags; | ||
76 | int ret = 1; | ||
77 | |||
78 | spin_lock_irqsave(&semaphore_wake_lock, flags); | ||
79 | if (sem->waking <= 0) | ||
80 | atomic_inc(&sem->count); | ||
81 | else { | ||
82 | sem->waking--; | ||
83 | ret = 0; | ||
84 | } | ||
85 | spin_unlock_irqrestore(&semaphore_wake_lock, flags); | ||
86 | return ret; | ||
87 | } | ||
88 | |||
89 | #endif /* _ASM_PARISC_SEMAPHORE_HELPER_H */ | ||
diff --git a/include/asm-parisc/semaphore.h b/include/asm-parisc/semaphore.h index a16271cdc748..d9b2034ed1d2 100644 --- a/include/asm-parisc/semaphore.h +++ b/include/asm-parisc/semaphore.h | |||
@@ -1,145 +1 @@ | |||
1 | /* SMP- and interrupt-safe semaphores. | #include <linux/semaphore.h> | |
2 | * PA-RISC version by Matthew Wilcox | ||
3 | * | ||
4 | * Linux/PA-RISC Project (http://www.parisc-linux.org/) | ||
5 | * Copyright (C) 1996 Linus Torvalds | ||
6 | * Copyright (C) 1999-2001 Matthew Wilcox < willy at debian d0T org > | ||
7 | * Copyright (C) 2000 Grant Grundler < grundler a debian org > | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify | ||
10 | * it under the terms of the GNU General Public License as published by | ||
11 | * the Free Software Foundation; either version 2 of the License, or | ||
12 | * (at your option) any later version. | ||
13 | * | ||
14 | * This program is distributed in the hope that it will be useful, | ||
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
17 | * GNU General Public License for more details. | ||
18 | * | ||
19 | * You should have received a copy of the GNU General Public License | ||
20 | * along with this program; if not, write to the Free Software | ||
21 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
22 | */ | ||
23 | |||
24 | #ifndef _ASM_PARISC_SEMAPHORE_H | ||
25 | #define _ASM_PARISC_SEMAPHORE_H | ||
26 | |||
27 | #include <linux/spinlock.h> | ||
28 | #include <linux/wait.h> | ||
29 | #include <linux/rwsem.h> | ||
30 | |||
31 | #include <asm/system.h> | ||
32 | |||
33 | /* | ||
34 | * The `count' is initialised to the number of people who are allowed to | ||
35 | * take the lock. (Normally we want a mutex, so this is `1'). if | ||
36 | * `count' is positive, the lock can be taken. if it's 0, no-one is | ||
37 | * waiting on it. if it's -1, at least one task is waiting. | ||
38 | */ | ||
39 | struct semaphore { | ||
40 | spinlock_t sentry; | ||
41 | int count; | ||
42 | wait_queue_head_t wait; | ||
43 | }; | ||
44 | |||
45 | #define __SEMAPHORE_INITIALIZER(name, n) \ | ||
46 | { \ | ||
47 | .sentry = SPIN_LOCK_UNLOCKED, \ | ||
48 | .count = n, \ | ||
49 | .wait = __WAIT_QUEUE_HEAD_INITIALIZER((name).wait) \ | ||
50 | } | ||
51 | |||
52 | #define __DECLARE_SEMAPHORE_GENERIC(name,count) \ | ||
53 | struct semaphore name = __SEMAPHORE_INITIALIZER(name,count) | ||
54 | |||
55 | #define DECLARE_MUTEX(name) __DECLARE_SEMAPHORE_GENERIC(name,1) | ||
56 | |||
57 | static inline void sema_init (struct semaphore *sem, int val) | ||
58 | { | ||
59 | *sem = (struct semaphore)__SEMAPHORE_INITIALIZER((*sem),val); | ||
60 | } | ||
61 | |||
62 | static inline void init_MUTEX (struct semaphore *sem) | ||
63 | { | ||
64 | sema_init(sem, 1); | ||
65 | } | ||
66 | |||
67 | static inline void init_MUTEX_LOCKED (struct semaphore *sem) | ||
68 | { | ||
69 | sema_init(sem, 0); | ||
70 | } | ||
71 | |||
72 | static inline int sem_getcount(struct semaphore *sem) | ||
73 | { | ||
74 | return sem->count; | ||
75 | } | ||
76 | |||
77 | asmlinkage void __down(struct semaphore * sem); | ||
78 | asmlinkage int __down_interruptible(struct semaphore * sem); | ||
79 | asmlinkage void __up(struct semaphore * sem); | ||
80 | |||
81 | /* Semaphores can be `tried' from irq context. So we have to disable | ||
82 | * interrupts while we're messing with the semaphore. Sorry. | ||
83 | */ | ||
84 | |||
85 | static inline void down(struct semaphore * sem) | ||
86 | { | ||
87 | might_sleep(); | ||
88 | spin_lock_irq(&sem->sentry); | ||
89 | if (sem->count > 0) { | ||
90 | sem->count--; | ||
91 | } else { | ||
92 | __down(sem); | ||
93 | } | ||
94 | spin_unlock_irq(&sem->sentry); | ||
95 | } | ||
96 | |||
97 | static inline int down_interruptible(struct semaphore * sem) | ||
98 | { | ||
99 | int ret = 0; | ||
100 | might_sleep(); | ||
101 | spin_lock_irq(&sem->sentry); | ||
102 | if (sem->count > 0) { | ||
103 | sem->count--; | ||
104 | } else { | ||
105 | ret = __down_interruptible(sem); | ||
106 | } | ||
107 | spin_unlock_irq(&sem->sentry); | ||
108 | return ret; | ||
109 | } | ||
110 | |||
111 | /* | ||
112 | * down_trylock returns 0 on success, 1 if we failed to get the lock. | ||
113 | * May not sleep, but must preserve irq state | ||
114 | */ | ||
115 | static inline int down_trylock(struct semaphore * sem) | ||
116 | { | ||
117 | unsigned long flags; | ||
118 | int count; | ||
119 | |||
120 | spin_lock_irqsave(&sem->sentry, flags); | ||
121 | count = sem->count - 1; | ||
122 | if (count >= 0) | ||
123 | sem->count = count; | ||
124 | spin_unlock_irqrestore(&sem->sentry, flags); | ||
125 | return (count < 0); | ||
126 | } | ||
127 | |||
128 | /* | ||
129 | * Note! This is subtle. We jump to wake people up only if | ||
130 | * the semaphore was negative (== somebody was waiting on it). | ||
131 | */ | ||
132 | static inline void up(struct semaphore * sem) | ||
133 | { | ||
134 | unsigned long flags; | ||
135 | |||
136 | spin_lock_irqsave(&sem->sentry, flags); | ||
137 | if (sem->count < 0) { | ||
138 | __up(sem); | ||
139 | } else { | ||
140 | sem->count++; | ||
141 | } | ||
142 | spin_unlock_irqrestore(&sem->sentry, flags); | ||
143 | } | ||
144 | |||
145 | #endif /* _ASM_PARISC_SEMAPHORE_H */ | ||
diff --git a/include/asm-powerpc/semaphore.h b/include/asm-powerpc/semaphore.h index 48dd32e07749..d9b2034ed1d2 100644 --- a/include/asm-powerpc/semaphore.h +++ b/include/asm-powerpc/semaphore.h | |||
@@ -1,94 +1 @@ | |||
1 | #ifndef _ASM_POWERPC_SEMAPHORE_H | #include <linux/semaphore.h> | |
2 | #define _ASM_POWERPC_SEMAPHORE_H | ||
3 | |||
4 | /* | ||
5 | * Remove spinlock-based RW semaphores; RW semaphore definitions are | ||
6 | * now in rwsem.h and we use the generic lib/rwsem.c implementation. | ||
7 | * Rework semaphores to use atomic_dec_if_positive. | ||
8 | * -- Paul Mackerras (paulus@samba.org) | ||
9 | */ | ||
10 | |||
11 | #ifdef __KERNEL__ | ||
12 | |||
13 | #include <asm/atomic.h> | ||
14 | #include <asm/system.h> | ||
15 | #include <linux/wait.h> | ||
16 | #include <linux/rwsem.h> | ||
17 | |||
18 | struct semaphore { | ||
19 | /* | ||
20 | * Note that any negative value of count is equivalent to 0, | ||
21 | * but additionally indicates that some process(es) might be | ||
22 | * sleeping on `wait'. | ||
23 | */ | ||
24 | atomic_t count; | ||
25 | wait_queue_head_t wait; | ||
26 | }; | ||
27 | |||
28 | #define __SEMAPHORE_INITIALIZER(name, n) \ | ||
29 | { \ | ||
30 | .count = ATOMIC_INIT(n), \ | ||
31 | .wait = __WAIT_QUEUE_HEAD_INITIALIZER((name).wait) \ | ||
32 | } | ||
33 | |||
34 | #define __DECLARE_SEMAPHORE_GENERIC(name, count) \ | ||
35 | struct semaphore name = __SEMAPHORE_INITIALIZER(name,count) | ||
36 | |||
37 | #define DECLARE_MUTEX(name) __DECLARE_SEMAPHORE_GENERIC(name, 1) | ||
38 | |||
39 | static inline void sema_init (struct semaphore *sem, int val) | ||
40 | { | ||
41 | atomic_set(&sem->count, val); | ||
42 | init_waitqueue_head(&sem->wait); | ||
43 | } | ||
44 | |||
45 | static inline void init_MUTEX (struct semaphore *sem) | ||
46 | { | ||
47 | sema_init(sem, 1); | ||
48 | } | ||
49 | |||
50 | static inline void init_MUTEX_LOCKED (struct semaphore *sem) | ||
51 | { | ||
52 | sema_init(sem, 0); | ||
53 | } | ||
54 | |||
55 | extern void __down(struct semaphore * sem); | ||
56 | extern int __down_interruptible(struct semaphore * sem); | ||
57 | extern void __up(struct semaphore * sem); | ||
58 | |||
59 | static inline void down(struct semaphore * sem) | ||
60 | { | ||
61 | might_sleep(); | ||
62 | |||
63 | /* | ||
64 | * Try to get the semaphore, take the slow path if we fail. | ||
65 | */ | ||
66 | if (unlikely(atomic_dec_return(&sem->count) < 0)) | ||
67 | __down(sem); | ||
68 | } | ||
69 | |||
70 | static inline int down_interruptible(struct semaphore * sem) | ||
71 | { | ||
72 | int ret = 0; | ||
73 | |||
74 | might_sleep(); | ||
75 | |||
76 | if (unlikely(atomic_dec_return(&sem->count) < 0)) | ||
77 | ret = __down_interruptible(sem); | ||
78 | return ret; | ||
79 | } | ||
80 | |||
81 | static inline int down_trylock(struct semaphore * sem) | ||
82 | { | ||
83 | return atomic_dec_if_positive(&sem->count) < 0; | ||
84 | } | ||
85 | |||
86 | static inline void up(struct semaphore * sem) | ||
87 | { | ||
88 | if (unlikely(atomic_inc_return(&sem->count) <= 0)) | ||
89 | __up(sem); | ||
90 | } | ||
91 | |||
92 | #endif /* __KERNEL__ */ | ||
93 | |||
94 | #endif /* _ASM_POWERPC_SEMAPHORE_H */ | ||
diff --git a/include/asm-s390/semaphore.h b/include/asm-s390/semaphore.h index 0e7001ad8392..d9b2034ed1d2 100644 --- a/include/asm-s390/semaphore.h +++ b/include/asm-s390/semaphore.h | |||
@@ -1,107 +1 @@ | |||
1 | /* | #include <linux/semaphore.h> | |
2 | * include/asm-s390/semaphore.h | ||
3 | * | ||
4 | * S390 version | ||
5 | * Copyright (C) 1999 IBM Deutschland Entwicklung GmbH, IBM Corporation | ||
6 | * | ||
7 | * Derived from "include/asm-i386/semaphore.h" | ||
8 | * (C) Copyright 1996 Linus Torvalds | ||
9 | */ | ||
10 | |||
11 | #ifndef _S390_SEMAPHORE_H | ||
12 | #define _S390_SEMAPHORE_H | ||
13 | |||
14 | #include <asm/system.h> | ||
15 | #include <asm/atomic.h> | ||
16 | #include <linux/wait.h> | ||
17 | #include <linux/rwsem.h> | ||
18 | |||
19 | struct semaphore { | ||
20 | /* | ||
21 | * Note that any negative value of count is equivalent to 0, | ||
22 | * but additionally indicates that some process(es) might be | ||
23 | * sleeping on `wait'. | ||
24 | */ | ||
25 | atomic_t count; | ||
26 | wait_queue_head_t wait; | ||
27 | }; | ||
28 | |||
29 | #define __SEMAPHORE_INITIALIZER(name,count) \ | ||
30 | { ATOMIC_INIT(count), __WAIT_QUEUE_HEAD_INITIALIZER((name).wait) } | ||
31 | |||
32 | #define __DECLARE_SEMAPHORE_GENERIC(name,count) \ | ||
33 | struct semaphore name = __SEMAPHORE_INITIALIZER(name,count) | ||
34 | |||
35 | #define DECLARE_MUTEX(name) __DECLARE_SEMAPHORE_GENERIC(name,1) | ||
36 | |||
37 | static inline void sema_init (struct semaphore *sem, int val) | ||
38 | { | ||
39 | atomic_set(&sem->count, val); | ||
40 | init_waitqueue_head(&sem->wait); | ||
41 | } | ||
42 | |||
43 | static inline void init_MUTEX (struct semaphore *sem) | ||
44 | { | ||
45 | sema_init(sem, 1); | ||
46 | } | ||
47 | |||
48 | static inline void init_MUTEX_LOCKED (struct semaphore *sem) | ||
49 | { | ||
50 | sema_init(sem, 0); | ||
51 | } | ||
52 | |||
53 | asmlinkage void __down(struct semaphore * sem); | ||
54 | asmlinkage int __down_interruptible(struct semaphore * sem); | ||
55 | asmlinkage int __down_trylock(struct semaphore * sem); | ||
56 | asmlinkage void __up(struct semaphore * sem); | ||
57 | |||
58 | static inline void down(struct semaphore * sem) | ||
59 | { | ||
60 | might_sleep(); | ||
61 | if (atomic_dec_return(&sem->count) < 0) | ||
62 | __down(sem); | ||
63 | } | ||
64 | |||
65 | static inline int down_interruptible(struct semaphore * sem) | ||
66 | { | ||
67 | int ret = 0; | ||
68 | |||
69 | might_sleep(); | ||
70 | if (atomic_dec_return(&sem->count) < 0) | ||
71 | ret = __down_interruptible(sem); | ||
72 | return ret; | ||
73 | } | ||
74 | |||
75 | static inline int down_trylock(struct semaphore * sem) | ||
76 | { | ||
77 | int old_val, new_val; | ||
78 | |||
79 | /* | ||
80 | * This inline assembly atomically implements the equivalent | ||
81 | * to the following C code: | ||
82 | * old_val = sem->count.counter; | ||
83 | * if ((new_val = old_val) > 0) | ||
84 | * sem->count.counter = --new_val; | ||
85 | * In the ppc code this is called atomic_dec_if_positive. | ||
86 | */ | ||
87 | asm volatile( | ||
88 | " l %0,0(%3)\n" | ||
89 | "0: ltr %1,%0\n" | ||
90 | " jle 1f\n" | ||
91 | " ahi %1,-1\n" | ||
92 | " cs %0,%1,0(%3)\n" | ||
93 | " jl 0b\n" | ||
94 | "1:" | ||
95 | : "=&d" (old_val), "=&d" (new_val), "=m" (sem->count.counter) | ||
96 | : "a" (&sem->count.counter), "m" (sem->count.counter) | ||
97 | : "cc", "memory"); | ||
98 | return old_val <= 0; | ||
99 | } | ||
100 | |||
101 | static inline void up(struct semaphore * sem) | ||
102 | { | ||
103 | if (atomic_inc_return(&sem->count) <= 0) | ||
104 | __up(sem); | ||
105 | } | ||
106 | |||
107 | #endif | ||
diff --git a/include/asm-sh/semaphore-helper.h b/include/asm-sh/semaphore-helper.h deleted file mode 100644 index bd8230c369ca..000000000000 --- a/include/asm-sh/semaphore-helper.h +++ /dev/null | |||
@@ -1,89 +0,0 @@ | |||
1 | #ifndef __ASM_SH_SEMAPHORE_HELPER_H | ||
2 | #define __ASM_SH_SEMAPHORE_HELPER_H | ||
3 | |||
4 | /* | ||
5 | * SMP- and interrupt-safe semaphores helper functions. | ||
6 | * | ||
7 | * (C) Copyright 1996 Linus Torvalds | ||
8 | * (C) Copyright 1999 Andrea Arcangeli | ||
9 | */ | ||
10 | |||
11 | /* | ||
12 | * These two _must_ execute atomically wrt each other. | ||
13 | * | ||
14 | * This is trivially done with load_locked/store_cond, | ||
15 | * which we have. Let the rest of the losers suck eggs. | ||
16 | */ | ||
17 | static __inline__ void wake_one_more(struct semaphore * sem) | ||
18 | { | ||
19 | atomic_inc((atomic_t *)&sem->sleepers); | ||
20 | } | ||
21 | |||
22 | static __inline__ int waking_non_zero(struct semaphore *sem) | ||
23 | { | ||
24 | unsigned long flags; | ||
25 | int ret = 0; | ||
26 | |||
27 | spin_lock_irqsave(&semaphore_wake_lock, flags); | ||
28 | if (sem->sleepers > 0) { | ||
29 | sem->sleepers--; | ||
30 | ret = 1; | ||
31 | } | ||
32 | spin_unlock_irqrestore(&semaphore_wake_lock, flags); | ||
33 | return ret; | ||
34 | } | ||
35 | |||
36 | /* | ||
37 | * waking_non_zero_interruptible: | ||
38 | * 1 got the lock | ||
39 | * 0 go to sleep | ||
40 | * -EINTR interrupted | ||
41 | * | ||
42 | * We must undo the sem->count down_interruptible() increment while we are | ||
43 | * protected by the spinlock in order to make atomic this atomic_inc() with the | ||
44 | * atomic_read() in wake_one_more(), otherwise we can race. -arca | ||
45 | */ | ||
46 | static __inline__ int waking_non_zero_interruptible(struct semaphore *sem, | ||
47 | struct task_struct *tsk) | ||
48 | { | ||
49 | unsigned long flags; | ||
50 | int ret = 0; | ||
51 | |||
52 | spin_lock_irqsave(&semaphore_wake_lock, flags); | ||
53 | if (sem->sleepers > 0) { | ||
54 | sem->sleepers--; | ||
55 | ret = 1; | ||
56 | } else if (signal_pending(tsk)) { | ||
57 | atomic_inc(&sem->count); | ||
58 | ret = -EINTR; | ||
59 | } | ||
60 | spin_unlock_irqrestore(&semaphore_wake_lock, flags); | ||
61 | return ret; | ||
62 | } | ||
63 | |||
64 | /* | ||
65 | * waking_non_zero_trylock: | ||
66 | * 1 failed to lock | ||
67 | * 0 got the lock | ||
68 | * | ||
69 | * We must undo the sem->count down_trylock() increment while we are | ||
70 | * protected by the spinlock in order to make atomic this atomic_inc() with the | ||
71 | * atomic_read() in wake_one_more(), otherwise we can race. -arca | ||
72 | */ | ||
73 | static __inline__ int waking_non_zero_trylock(struct semaphore *sem) | ||
74 | { | ||
75 | unsigned long flags; | ||
76 | int ret = 1; | ||
77 | |||
78 | spin_lock_irqsave(&semaphore_wake_lock, flags); | ||
79 | if (sem->sleepers <= 0) | ||
80 | atomic_inc(&sem->count); | ||
81 | else { | ||
82 | sem->sleepers--; | ||
83 | ret = 0; | ||
84 | } | ||
85 | spin_unlock_irqrestore(&semaphore_wake_lock, flags); | ||
86 | return ret; | ||
87 | } | ||
88 | |||
89 | #endif /* __ASM_SH_SEMAPHORE_HELPER_H */ | ||
diff --git a/include/asm-sh/semaphore.h b/include/asm-sh/semaphore.h index 9e5a37c4dce2..d9b2034ed1d2 100644 --- a/include/asm-sh/semaphore.h +++ b/include/asm-sh/semaphore.h | |||
@@ -1,115 +1 @@ | |||
1 | #ifndef __ASM_SH_SEMAPHORE_H | #include <linux/semaphore.h> | |
2 | #define __ASM_SH_SEMAPHORE_H | ||
3 | |||
4 | #include <linux/linkage.h> | ||
5 | |||
6 | #ifdef __KERNEL__ | ||
7 | /* | ||
8 | * SMP- and interrupt-safe semaphores. | ||
9 | * | ||
10 | * (C) Copyright 1996 Linus Torvalds | ||
11 | * | ||
12 | * SuperH verison by Niibe Yutaka | ||
13 | * (Currently no asm implementation but generic C code...) | ||
14 | */ | ||
15 | |||
16 | #include <linux/spinlock.h> | ||
17 | #include <linux/rwsem.h> | ||
18 | #include <linux/wait.h> | ||
19 | |||
20 | #include <asm/system.h> | ||
21 | #include <asm/atomic.h> | ||
22 | |||
23 | struct semaphore { | ||
24 | atomic_t count; | ||
25 | int sleepers; | ||
26 | wait_queue_head_t wait; | ||
27 | }; | ||
28 | |||
29 | #define __SEMAPHORE_INITIALIZER(name, n) \ | ||
30 | { \ | ||
31 | .count = ATOMIC_INIT(n), \ | ||
32 | .sleepers = 0, \ | ||
33 | .wait = __WAIT_QUEUE_HEAD_INITIALIZER((name).wait) \ | ||
34 | } | ||
35 | |||
36 | #define __DECLARE_SEMAPHORE_GENERIC(name,count) \ | ||
37 | struct semaphore name = __SEMAPHORE_INITIALIZER(name,count) | ||
38 | |||
39 | #define DECLARE_MUTEX(name) __DECLARE_SEMAPHORE_GENERIC(name,1) | ||
40 | |||
41 | static inline void sema_init (struct semaphore *sem, int val) | ||
42 | { | ||
43 | /* | ||
44 | * *sem = (struct semaphore)__SEMAPHORE_INITIALIZER((*sem),val); | ||
45 | * | ||
46 | * i'd rather use the more flexible initialization above, but sadly | ||
47 | * GCC 2.7.2.3 emits a bogus warning. EGCS doesn't. Oh well. | ||
48 | */ | ||
49 | atomic_set(&sem->count, val); | ||
50 | sem->sleepers = 0; | ||
51 | init_waitqueue_head(&sem->wait); | ||
52 | } | ||
53 | |||
54 | static inline void init_MUTEX (struct semaphore *sem) | ||
55 | { | ||
56 | sema_init(sem, 1); | ||
57 | } | ||
58 | |||
59 | static inline void init_MUTEX_LOCKED (struct semaphore *sem) | ||
60 | { | ||
61 | sema_init(sem, 0); | ||
62 | } | ||
63 | |||
64 | #if 0 | ||
65 | asmlinkage void __down_failed(void /* special register calling convention */); | ||
66 | asmlinkage int __down_failed_interruptible(void /* params in registers */); | ||
67 | asmlinkage int __down_failed_trylock(void /* params in registers */); | ||
68 | asmlinkage void __up_wakeup(void /* special register calling convention */); | ||
69 | #endif | ||
70 | |||
71 | asmlinkage void __down(struct semaphore * sem); | ||
72 | asmlinkage int __down_interruptible(struct semaphore * sem); | ||
73 | asmlinkage int __down_trylock(struct semaphore * sem); | ||
74 | asmlinkage void __up(struct semaphore * sem); | ||
75 | |||
76 | extern spinlock_t semaphore_wake_lock; | ||
77 | |||
78 | static inline void down(struct semaphore * sem) | ||
79 | { | ||
80 | might_sleep(); | ||
81 | if (atomic_dec_return(&sem->count) < 0) | ||
82 | __down(sem); | ||
83 | } | ||
84 | |||
85 | static inline int down_interruptible(struct semaphore * sem) | ||
86 | { | ||
87 | int ret = 0; | ||
88 | |||
89 | might_sleep(); | ||
90 | if (atomic_dec_return(&sem->count) < 0) | ||
91 | ret = __down_interruptible(sem); | ||
92 | return ret; | ||
93 | } | ||
94 | |||
95 | static inline int down_trylock(struct semaphore * sem) | ||
96 | { | ||
97 | int ret = 0; | ||
98 | |||
99 | if (atomic_dec_return(&sem->count) < 0) | ||
100 | ret = __down_trylock(sem); | ||
101 | return ret; | ||
102 | } | ||
103 | |||
104 | /* | ||
105 | * Note! This is subtle. We jump to wake people up only if | ||
106 | * the semaphore was negative (== somebody was waiting on it). | ||
107 | */ | ||
108 | static inline void up(struct semaphore * sem) | ||
109 | { | ||
110 | if (atomic_inc_return(&sem->count) <= 0) | ||
111 | __up(sem); | ||
112 | } | ||
113 | |||
114 | #endif | ||
115 | #endif /* __ASM_SH_SEMAPHORE_H */ | ||
diff --git a/include/asm-sparc/semaphore.h b/include/asm-sparc/semaphore.h index 8018f9f4d497..d9b2034ed1d2 100644 --- a/include/asm-sparc/semaphore.h +++ b/include/asm-sparc/semaphore.h | |||
@@ -1,192 +1 @@ | |||
1 | #ifndef _SPARC_SEMAPHORE_H | #include <linux/semaphore.h> | |
2 | #define _SPARC_SEMAPHORE_H | ||
3 | |||
4 | /* Dinky, good for nothing, just barely irq safe, Sparc semaphores. */ | ||
5 | |||
6 | #ifdef __KERNEL__ | ||
7 | |||
8 | #include <asm/atomic.h> | ||
9 | #include <linux/wait.h> | ||
10 | #include <linux/rwsem.h> | ||
11 | |||
12 | struct semaphore { | ||
13 | atomic24_t count; | ||
14 | int sleepers; | ||
15 | wait_queue_head_t wait; | ||
16 | }; | ||
17 | |||
18 | #define __SEMAPHORE_INITIALIZER(name, n) \ | ||
19 | { \ | ||
20 | .count = ATOMIC24_INIT(n), \ | ||
21 | .sleepers = 0, \ | ||
22 | .wait = __WAIT_QUEUE_HEAD_INITIALIZER((name).wait) \ | ||
23 | } | ||
24 | |||
25 | #define __DECLARE_SEMAPHORE_GENERIC(name,count) \ | ||
26 | struct semaphore name = __SEMAPHORE_INITIALIZER(name,count) | ||
27 | |||
28 | #define DECLARE_MUTEX(name) __DECLARE_SEMAPHORE_GENERIC(name,1) | ||
29 | |||
30 | static inline void sema_init (struct semaphore *sem, int val) | ||
31 | { | ||
32 | atomic24_set(&sem->count, val); | ||
33 | sem->sleepers = 0; | ||
34 | init_waitqueue_head(&sem->wait); | ||
35 | } | ||
36 | |||
37 | static inline void init_MUTEX (struct semaphore *sem) | ||
38 | { | ||
39 | sema_init(sem, 1); | ||
40 | } | ||
41 | |||
42 | static inline void init_MUTEX_LOCKED (struct semaphore *sem) | ||
43 | { | ||
44 | sema_init(sem, 0); | ||
45 | } | ||
46 | |||
47 | extern void __down(struct semaphore * sem); | ||
48 | extern int __down_interruptible(struct semaphore * sem); | ||
49 | extern int __down_trylock(struct semaphore * sem); | ||
50 | extern void __up(struct semaphore * sem); | ||
51 | |||
52 | static inline void down(struct semaphore * sem) | ||
53 | { | ||
54 | register volatile int *ptr asm("g1"); | ||
55 | register int increment asm("g2"); | ||
56 | |||
57 | might_sleep(); | ||
58 | |||
59 | ptr = &(sem->count.counter); | ||
60 | increment = 1; | ||
61 | |||
62 | __asm__ __volatile__( | ||
63 | "mov %%o7, %%g4\n\t" | ||
64 | "call ___atomic24_sub\n\t" | ||
65 | " add %%o7, 8, %%o7\n\t" | ||
66 | "tst %%g2\n\t" | ||
67 | "bl 2f\n\t" | ||
68 | " nop\n" | ||
69 | "1:\n\t" | ||
70 | ".subsection 2\n" | ||
71 | "2:\n\t" | ||
72 | "save %%sp, -64, %%sp\n\t" | ||
73 | "mov %%g1, %%l1\n\t" | ||
74 | "mov %%g5, %%l5\n\t" | ||
75 | "call %3\n\t" | ||
76 | " mov %%g1, %%o0\n\t" | ||
77 | "mov %%l1, %%g1\n\t" | ||
78 | "ba 1b\n\t" | ||
79 | " restore %%l5, %%g0, %%g5\n\t" | ||
80 | ".previous\n" | ||
81 | : "=&r" (increment) | ||
82 | : "0" (increment), "r" (ptr), "i" (__down) | ||
83 | : "g3", "g4", "g7", "memory", "cc"); | ||
84 | } | ||
85 | |||
86 | static inline int down_interruptible(struct semaphore * sem) | ||
87 | { | ||
88 | register volatile int *ptr asm("g1"); | ||
89 | register int increment asm("g2"); | ||
90 | |||
91 | might_sleep(); | ||
92 | |||
93 | ptr = &(sem->count.counter); | ||
94 | increment = 1; | ||
95 | |||
96 | __asm__ __volatile__( | ||
97 | "mov %%o7, %%g4\n\t" | ||
98 | "call ___atomic24_sub\n\t" | ||
99 | " add %%o7, 8, %%o7\n\t" | ||
100 | "tst %%g2\n\t" | ||
101 | "bl 2f\n\t" | ||
102 | " clr %%g2\n" | ||
103 | "1:\n\t" | ||
104 | ".subsection 2\n" | ||
105 | "2:\n\t" | ||
106 | "save %%sp, -64, %%sp\n\t" | ||
107 | "mov %%g1, %%l1\n\t" | ||
108 | "mov %%g5, %%l5\n\t" | ||
109 | "call %3\n\t" | ||
110 | " mov %%g1, %%o0\n\t" | ||
111 | "mov %%l1, %%g1\n\t" | ||
112 | "mov %%l5, %%g5\n\t" | ||
113 | "ba 1b\n\t" | ||
114 | " restore %%o0, %%g0, %%g2\n\t" | ||
115 | ".previous\n" | ||
116 | : "=&r" (increment) | ||
117 | : "0" (increment), "r" (ptr), "i" (__down_interruptible) | ||
118 | : "g3", "g4", "g7", "memory", "cc"); | ||
119 | |||
120 | return increment; | ||
121 | } | ||
122 | |||
123 | static inline int down_trylock(struct semaphore * sem) | ||
124 | { | ||
125 | register volatile int *ptr asm("g1"); | ||
126 | register int increment asm("g2"); | ||
127 | |||
128 | ptr = &(sem->count.counter); | ||
129 | increment = 1; | ||
130 | |||
131 | __asm__ __volatile__( | ||
132 | "mov %%o7, %%g4\n\t" | ||
133 | "call ___atomic24_sub\n\t" | ||
134 | " add %%o7, 8, %%o7\n\t" | ||
135 | "tst %%g2\n\t" | ||
136 | "bl 2f\n\t" | ||
137 | " clr %%g2\n" | ||
138 | "1:\n\t" | ||
139 | ".subsection 2\n" | ||
140 | "2:\n\t" | ||
141 | "save %%sp, -64, %%sp\n\t" | ||
142 | "mov %%g1, %%l1\n\t" | ||
143 | "mov %%g5, %%l5\n\t" | ||
144 | "call %3\n\t" | ||
145 | " mov %%g1, %%o0\n\t" | ||
146 | "mov %%l1, %%g1\n\t" | ||
147 | "mov %%l5, %%g5\n\t" | ||
148 | "ba 1b\n\t" | ||
149 | " restore %%o0, %%g0, %%g2\n\t" | ||
150 | ".previous\n" | ||
151 | : "=&r" (increment) | ||
152 | : "0" (increment), "r" (ptr), "i" (__down_trylock) | ||
153 | : "g3", "g4", "g7", "memory", "cc"); | ||
154 | |||
155 | return increment; | ||
156 | } | ||
157 | |||
158 | static inline void up(struct semaphore * sem) | ||
159 | { | ||
160 | register volatile int *ptr asm("g1"); | ||
161 | register int increment asm("g2"); | ||
162 | |||
163 | ptr = &(sem->count.counter); | ||
164 | increment = 1; | ||
165 | |||
166 | __asm__ __volatile__( | ||
167 | "mov %%o7, %%g4\n\t" | ||
168 | "call ___atomic24_add\n\t" | ||
169 | " add %%o7, 8, %%o7\n\t" | ||
170 | "tst %%g2\n\t" | ||
171 | "ble 2f\n\t" | ||
172 | " nop\n" | ||
173 | "1:\n\t" | ||
174 | ".subsection 2\n" | ||
175 | "2:\n\t" | ||
176 | "save %%sp, -64, %%sp\n\t" | ||
177 | "mov %%g1, %%l1\n\t" | ||
178 | "mov %%g5, %%l5\n\t" | ||
179 | "call %3\n\t" | ||
180 | " mov %%g1, %%o0\n\t" | ||
181 | "mov %%l1, %%g1\n\t" | ||
182 | "ba 1b\n\t" | ||
183 | " restore %%l5, %%g0, %%g5\n\t" | ||
184 | ".previous\n" | ||
185 | : "=&r" (increment) | ||
186 | : "0" (increment), "r" (ptr), "i" (__up) | ||
187 | : "g3", "g4", "g7", "memory", "cc"); | ||
188 | } | ||
189 | |||
190 | #endif /* __KERNEL__ */ | ||
191 | |||
192 | #endif /* !(_SPARC_SEMAPHORE_H) */ | ||
diff --git a/include/asm-sparc64/semaphore.h b/include/asm-sparc64/semaphore.h index 7f7c0c4e024f..d9b2034ed1d2 100644 --- a/include/asm-sparc64/semaphore.h +++ b/include/asm-sparc64/semaphore.h | |||
@@ -1,53 +1 @@ | |||
1 | #ifndef _SPARC64_SEMAPHORE_H | #include <linux/semaphore.h> | |
2 | #define _SPARC64_SEMAPHORE_H | ||
3 | |||
4 | /* These are actually reasonable on the V9. | ||
5 | * | ||
6 | * See asm-ppc/semaphore.h for implementation commentary, | ||
7 | * only sparc64 specific issues are commented here. | ||
8 | */ | ||
9 | #ifdef __KERNEL__ | ||
10 | |||
11 | #include <asm/atomic.h> | ||
12 | #include <asm/system.h> | ||
13 | #include <linux/wait.h> | ||
14 | #include <linux/rwsem.h> | ||
15 | |||
16 | struct semaphore { | ||
17 | atomic_t count; | ||
18 | wait_queue_head_t wait; | ||
19 | }; | ||
20 | |||
21 | #define __SEMAPHORE_INITIALIZER(name, count) \ | ||
22 | { ATOMIC_INIT(count), \ | ||
23 | __WAIT_QUEUE_HEAD_INITIALIZER((name).wait) } | ||
24 | |||
25 | #define __DECLARE_SEMAPHORE_GENERIC(name, count) \ | ||
26 | struct semaphore name = __SEMAPHORE_INITIALIZER(name,count) | ||
27 | |||
28 | #define DECLARE_MUTEX(name) __DECLARE_SEMAPHORE_GENERIC(name, 1) | ||
29 | |||
30 | static inline void sema_init (struct semaphore *sem, int val) | ||
31 | { | ||
32 | atomic_set(&sem->count, val); | ||
33 | init_waitqueue_head(&sem->wait); | ||
34 | } | ||
35 | |||
36 | static inline void init_MUTEX (struct semaphore *sem) | ||
37 | { | ||
38 | sema_init(sem, 1); | ||
39 | } | ||
40 | |||
41 | static inline void init_MUTEX_LOCKED (struct semaphore *sem) | ||
42 | { | ||
43 | sema_init(sem, 0); | ||
44 | } | ||
45 | |||
46 | extern void up(struct semaphore *sem); | ||
47 | extern void down(struct semaphore *sem); | ||
48 | extern int down_trylock(struct semaphore *sem); | ||
49 | extern int down_interruptible(struct semaphore *sem); | ||
50 | |||
51 | #endif /* __KERNEL__ */ | ||
52 | |||
53 | #endif /* !(_SPARC64_SEMAPHORE_H) */ | ||
diff --git a/include/asm-um/semaphore.h b/include/asm-um/semaphore.h index ff13c34de421..d9b2034ed1d2 100644 --- a/include/asm-um/semaphore.h +++ b/include/asm-um/semaphore.h | |||
@@ -1,6 +1 @@ | |||
1 | #ifndef __UM_SEMAPHORE_H | #include <linux/semaphore.h> | |
2 | #define __UM_SEMAPHORE_H | ||
3 | |||
4 | #include "asm/arch/semaphore.h" | ||
5 | |||
6 | #endif | ||
diff --git a/include/asm-v850/semaphore.h b/include/asm-v850/semaphore.h index 10ed0ccf37df..d9b2034ed1d2 100644 --- a/include/asm-v850/semaphore.h +++ b/include/asm-v850/semaphore.h | |||
@@ -1,84 +1 @@ | |||
1 | #ifndef __V850_SEMAPHORE_H__ | #include <linux/semaphore.h> | |
2 | #define __V850_SEMAPHORE_H__ | ||
3 | |||
4 | #include <linux/linkage.h> | ||
5 | #include <linux/spinlock.h> | ||
6 | #include <linux/wait.h> | ||
7 | #include <linux/rwsem.h> | ||
8 | |||
9 | #include <asm/atomic.h> | ||
10 | |||
11 | struct semaphore { | ||
12 | atomic_t count; | ||
13 | int sleepers; | ||
14 | wait_queue_head_t wait; | ||
15 | }; | ||
16 | |||
17 | #define __SEMAPHORE_INITIALIZER(name,count) \ | ||
18 | { ATOMIC_INIT (count), 0, \ | ||
19 | __WAIT_QUEUE_HEAD_INITIALIZER ((name).wait) } | ||
20 | |||
21 | #define __DECLARE_SEMAPHORE_GENERIC(name,count) \ | ||
22 | struct semaphore name = __SEMAPHORE_INITIALIZER (name,count) | ||
23 | |||
24 | #define DECLARE_MUTEX(name) __DECLARE_SEMAPHORE_GENERIC (name,1) | ||
25 | |||
26 | static inline void sema_init (struct semaphore *sem, int val) | ||
27 | { | ||
28 | *sem = (struct semaphore)__SEMAPHORE_INITIALIZER((*sem),val); | ||
29 | } | ||
30 | |||
31 | static inline void init_MUTEX (struct semaphore *sem) | ||
32 | { | ||
33 | sema_init (sem, 1); | ||
34 | } | ||
35 | |||
36 | static inline void init_MUTEX_LOCKED (struct semaphore *sem) | ||
37 | { | ||
38 | sema_init (sem, 0); | ||
39 | } | ||
40 | |||
41 | /* | ||
42 | * special register calling convention | ||
43 | */ | ||
44 | asmlinkage void __down_failed (void); | ||
45 | asmlinkage int __down_interruptible_failed (void); | ||
46 | asmlinkage int __down_trylock_failed (void); | ||
47 | asmlinkage void __up_wakeup (void); | ||
48 | |||
49 | extern void __down (struct semaphore * sem); | ||
50 | extern int __down_interruptible (struct semaphore * sem); | ||
51 | extern int __down_trylock (struct semaphore * sem); | ||
52 | extern void __up (struct semaphore * sem); | ||
53 | |||
54 | static inline void down (struct semaphore * sem) | ||
55 | { | ||
56 | might_sleep(); | ||
57 | if (atomic_dec_return (&sem->count) < 0) | ||
58 | __down (sem); | ||
59 | } | ||
60 | |||
61 | static inline int down_interruptible (struct semaphore * sem) | ||
62 | { | ||
63 | int ret = 0; | ||
64 | might_sleep(); | ||
65 | if (atomic_dec_return (&sem->count) < 0) | ||
66 | ret = __down_interruptible (sem); | ||
67 | return ret; | ||
68 | } | ||
69 | |||
70 | static inline int down_trylock (struct semaphore *sem) | ||
71 | { | ||
72 | int ret = 0; | ||
73 | if (atomic_dec_return (&sem->count) < 0) | ||
74 | ret = __down_trylock (sem); | ||
75 | return ret; | ||
76 | } | ||
77 | |||
78 | static inline void up (struct semaphore * sem) | ||
79 | { | ||
80 | if (atomic_inc_return (&sem->count) <= 0) | ||
81 | __up (sem); | ||
82 | } | ||
83 | |||
84 | #endif /* __V850_SEMAPHORE_H__ */ | ||
diff --git a/include/asm-x86/semaphore.h b/include/asm-x86/semaphore.h index 572c0b67a6b0..d9b2034ed1d2 100644 --- a/include/asm-x86/semaphore.h +++ b/include/asm-x86/semaphore.h | |||
@@ -1,5 +1 @@ | |||
1 | #ifdef CONFIG_X86_32 | #include <linux/semaphore.h> | |
2 | # include "semaphore_32.h" | ||
3 | #else | ||
4 | # include "semaphore_64.h" | ||
5 | #endif | ||
diff --git a/include/asm-x86/semaphore_32.h b/include/asm-x86/semaphore_32.h deleted file mode 100644 index ac96d3804d0c..000000000000 --- a/include/asm-x86/semaphore_32.h +++ /dev/null | |||
@@ -1,175 +0,0 @@ | |||
1 | #ifndef _I386_SEMAPHORE_H | ||
2 | #define _I386_SEMAPHORE_H | ||
3 | |||
4 | #include <linux/linkage.h> | ||
5 | |||
6 | #ifdef __KERNEL__ | ||
7 | |||
8 | /* | ||
9 | * SMP- and interrupt-safe semaphores.. | ||
10 | * | ||
11 | * (C) Copyright 1996 Linus Torvalds | ||
12 | * | ||
13 | * Modified 1996-12-23 by Dave Grothe <dave@gcom.com> to fix bugs in | ||
14 | * the original code and to make semaphore waits | ||
15 | * interruptible so that processes waiting on | ||
16 | * semaphores can be killed. | ||
17 | * Modified 1999-02-14 by Andrea Arcangeli, split the sched.c helper | ||
18 | * functions in asm/sempahore-helper.h while fixing a | ||
19 | * potential and subtle race discovered by Ulrich Schmid | ||
20 | * in down_interruptible(). Since I started to play here I | ||
21 | * also implemented the `trylock' semaphore operation. | ||
22 | * 1999-07-02 Artur Skawina <skawina@geocities.com> | ||
23 | * Optimized "0(ecx)" -> "(ecx)" (the assembler does not | ||
24 | * do this). Changed calling sequences from push/jmp to | ||
25 | * traditional call/ret. | ||
26 | * Modified 2001-01-01 Andreas Franck <afranck@gmx.de> | ||
27 | * Some hacks to ensure compatibility with recent | ||
28 | * GCC snapshots, to avoid stack corruption when compiling | ||
29 | * with -fomit-frame-pointer. It's not sure if this will | ||
30 | * be fixed in GCC, as our previous implementation was a | ||
31 | * bit dubious. | ||
32 | * | ||
33 | * If you would like to see an analysis of this implementation, please | ||
34 | * ftp to gcom.com and download the file | ||
35 | * /pub/linux/src/semaphore/semaphore-2.0.24.tar.gz. | ||
36 | * | ||
37 | */ | ||
38 | |||
39 | #include <asm/system.h> | ||
40 | #include <asm/atomic.h> | ||
41 | #include <linux/wait.h> | ||
42 | #include <linux/rwsem.h> | ||
43 | |||
44 | struct semaphore { | ||
45 | atomic_t count; | ||
46 | int sleepers; | ||
47 | wait_queue_head_t wait; | ||
48 | }; | ||
49 | |||
50 | |||
51 | #define __SEMAPHORE_INITIALIZER(name, n) \ | ||
52 | { \ | ||
53 | .count = ATOMIC_INIT(n), \ | ||
54 | .sleepers = 0, \ | ||
55 | .wait = __WAIT_QUEUE_HEAD_INITIALIZER((name).wait) \ | ||
56 | } | ||
57 | |||
58 | #define __DECLARE_SEMAPHORE_GENERIC(name,count) \ | ||
59 | struct semaphore name = __SEMAPHORE_INITIALIZER(name,count) | ||
60 | |||
61 | #define DECLARE_MUTEX(name) __DECLARE_SEMAPHORE_GENERIC(name,1) | ||
62 | |||
63 | static inline void sema_init (struct semaphore *sem, int val) | ||
64 | { | ||
65 | /* | ||
66 | * *sem = (struct semaphore)__SEMAPHORE_INITIALIZER((*sem),val); | ||
67 | * | ||
68 | * i'd rather use the more flexible initialization above, but sadly | ||
69 | * GCC 2.7.2.3 emits a bogus warning. EGCS doesn't. Oh well. | ||
70 | */ | ||
71 | atomic_set(&sem->count, val); | ||
72 | sem->sleepers = 0; | ||
73 | init_waitqueue_head(&sem->wait); | ||
74 | } | ||
75 | |||
76 | static inline void init_MUTEX (struct semaphore *sem) | ||
77 | { | ||
78 | sema_init(sem, 1); | ||
79 | } | ||
80 | |||
81 | static inline void init_MUTEX_LOCKED (struct semaphore *sem) | ||
82 | { | ||
83 | sema_init(sem, 0); | ||
84 | } | ||
85 | |||
86 | extern asmregparm void __down_failed(atomic_t *count_ptr); | ||
87 | extern asmregparm int __down_failed_interruptible(atomic_t *count_ptr); | ||
88 | extern asmregparm int __down_failed_trylock(atomic_t *count_ptr); | ||
89 | extern asmregparm void __up_wakeup(atomic_t *count_ptr); | ||
90 | |||
91 | /* | ||
92 | * This is ugly, but we want the default case to fall through. | ||
93 | * "__down_failed" is a special asm handler that calls the C | ||
94 | * routine that actually waits. See arch/i386/kernel/semaphore.c | ||
95 | */ | ||
96 | static inline void down(struct semaphore * sem) | ||
97 | { | ||
98 | might_sleep(); | ||
99 | __asm__ __volatile__( | ||
100 | "# atomic down operation\n\t" | ||
101 | LOCK_PREFIX "decl %0\n\t" /* --sem->count */ | ||
102 | "jns 2f\n" | ||
103 | "\tlea %0,%%eax\n\t" | ||
104 | "call __down_failed\n" | ||
105 | "2:" | ||
106 | :"+m" (sem->count) | ||
107 | : | ||
108 | :"memory","ax"); | ||
109 | } | ||
110 | |||
111 | /* | ||
112 | * Interruptible try to acquire a semaphore. If we obtained | ||
113 | * it, return zero. If we were interrupted, returns -EINTR | ||
114 | */ | ||
115 | static inline int down_interruptible(struct semaphore * sem) | ||
116 | { | ||
117 | int result; | ||
118 | |||
119 | might_sleep(); | ||
120 | __asm__ __volatile__( | ||
121 | "# atomic interruptible down operation\n\t" | ||
122 | "xorl %0,%0\n\t" | ||
123 | LOCK_PREFIX "decl %1\n\t" /* --sem->count */ | ||
124 | "jns 2f\n\t" | ||
125 | "lea %1,%%eax\n\t" | ||
126 | "call __down_failed_interruptible\n" | ||
127 | "2:" | ||
128 | :"=&a" (result), "+m" (sem->count) | ||
129 | : | ||
130 | :"memory"); | ||
131 | return result; | ||
132 | } | ||
133 | |||
134 | /* | ||
135 | * Non-blockingly attempt to down() a semaphore. | ||
136 | * Returns zero if we acquired it | ||
137 | */ | ||
138 | static inline int down_trylock(struct semaphore * sem) | ||
139 | { | ||
140 | int result; | ||
141 | |||
142 | __asm__ __volatile__( | ||
143 | "# atomic interruptible down operation\n\t" | ||
144 | "xorl %0,%0\n\t" | ||
145 | LOCK_PREFIX "decl %1\n\t" /* --sem->count */ | ||
146 | "jns 2f\n\t" | ||
147 | "lea %1,%%eax\n\t" | ||
148 | "call __down_failed_trylock\n\t" | ||
149 | "2:\n" | ||
150 | :"=&a" (result), "+m" (sem->count) | ||
151 | : | ||
152 | :"memory"); | ||
153 | return result; | ||
154 | } | ||
155 | |||
156 | /* | ||
157 | * Note! This is subtle. We jump to wake people up only if | ||
158 | * the semaphore was negative (== somebody was waiting on it). | ||
159 | */ | ||
160 | static inline void up(struct semaphore * sem) | ||
161 | { | ||
162 | __asm__ __volatile__( | ||
163 | "# atomic up operation\n\t" | ||
164 | LOCK_PREFIX "incl %0\n\t" /* ++sem->count */ | ||
165 | "jg 1f\n\t" | ||
166 | "lea %0,%%eax\n\t" | ||
167 | "call __up_wakeup\n" | ||
168 | "1:" | ||
169 | :"+m" (sem->count) | ||
170 | : | ||
171 | :"memory","ax"); | ||
172 | } | ||
173 | |||
174 | #endif | ||
175 | #endif | ||
diff --git a/include/asm-x86/semaphore_64.h b/include/asm-x86/semaphore_64.h deleted file mode 100644 index 79694306bf7d..000000000000 --- a/include/asm-x86/semaphore_64.h +++ /dev/null | |||
@@ -1,180 +0,0 @@ | |||
1 | #ifndef _X86_64_SEMAPHORE_H | ||
2 | #define _X86_64_SEMAPHORE_H | ||
3 | |||
4 | #include <linux/linkage.h> | ||
5 | |||
6 | #ifdef __KERNEL__ | ||
7 | |||
8 | /* | ||
9 | * SMP- and interrupt-safe semaphores.. | ||
10 | * | ||
11 | * (C) Copyright 1996 Linus Torvalds | ||
12 | * | ||
13 | * Modified 1996-12-23 by Dave Grothe <dave@gcom.com> to fix bugs in | ||
14 | * the original code and to make semaphore waits | ||
15 | * interruptible so that processes waiting on | ||
16 | * semaphores can be killed. | ||
17 | * Modified 1999-02-14 by Andrea Arcangeli, split the sched.c helper | ||
18 | * functions in asm/sempahore-helper.h while fixing a | ||
19 | * potential and subtle race discovered by Ulrich Schmid | ||
20 | * in down_interruptible(). Since I started to play here I | ||
21 | * also implemented the `trylock' semaphore operation. | ||
22 | * 1999-07-02 Artur Skawina <skawina@geocities.com> | ||
23 | * Optimized "0(ecx)" -> "(ecx)" (the assembler does not | ||
24 | * do this). Changed calling sequences from push/jmp to | ||
25 | * traditional call/ret. | ||
26 | * Modified 2001-01-01 Andreas Franck <afranck@gmx.de> | ||
27 | * Some hacks to ensure compatibility with recent | ||
28 | * GCC snapshots, to avoid stack corruption when compiling | ||
29 | * with -fomit-frame-pointer. It's not sure if this will | ||
30 | * be fixed in GCC, as our previous implementation was a | ||
31 | * bit dubious. | ||
32 | * | ||
33 | * If you would like to see an analysis of this implementation, please | ||
34 | * ftp to gcom.com and download the file | ||
35 | * /pub/linux/src/semaphore/semaphore-2.0.24.tar.gz. | ||
36 | * | ||
37 | */ | ||
38 | |||
39 | #include <asm/system.h> | ||
40 | #include <asm/atomic.h> | ||
41 | #include <asm/rwlock.h> | ||
42 | #include <linux/wait.h> | ||
43 | #include <linux/rwsem.h> | ||
44 | #include <linux/stringify.h> | ||
45 | |||
46 | struct semaphore { | ||
47 | atomic_t count; | ||
48 | int sleepers; | ||
49 | wait_queue_head_t wait; | ||
50 | }; | ||
51 | |||
52 | #define __SEMAPHORE_INITIALIZER(name, n) \ | ||
53 | { \ | ||
54 | .count = ATOMIC_INIT(n), \ | ||
55 | .sleepers = 0, \ | ||
56 | .wait = __WAIT_QUEUE_HEAD_INITIALIZER((name).wait) \ | ||
57 | } | ||
58 | |||
59 | #define __DECLARE_SEMAPHORE_GENERIC(name,count) \ | ||
60 | struct semaphore name = __SEMAPHORE_INITIALIZER(name,count) | ||
61 | |||
62 | #define DECLARE_MUTEX(name) __DECLARE_SEMAPHORE_GENERIC(name,1) | ||
63 | |||
64 | static inline void sema_init (struct semaphore *sem, int val) | ||
65 | { | ||
66 | /* | ||
67 | * *sem = (struct semaphore)__SEMAPHORE_INITIALIZER((*sem),val); | ||
68 | * | ||
69 | * i'd rather use the more flexible initialization above, but sadly | ||
70 | * GCC 2.7.2.3 emits a bogus warning. EGCS doesn't. Oh well. | ||
71 | */ | ||
72 | atomic_set(&sem->count, val); | ||
73 | sem->sleepers = 0; | ||
74 | init_waitqueue_head(&sem->wait); | ||
75 | } | ||
76 | |||
77 | static inline void init_MUTEX (struct semaphore *sem) | ||
78 | { | ||
79 | sema_init(sem, 1); | ||
80 | } | ||
81 | |||
82 | static inline void init_MUTEX_LOCKED (struct semaphore *sem) | ||
83 | { | ||
84 | sema_init(sem, 0); | ||
85 | } | ||
86 | |||
87 | asmlinkage void __down_failed(void /* special register calling convention */); | ||
88 | asmlinkage int __down_failed_interruptible(void /* params in registers */); | ||
89 | asmlinkage int __down_failed_trylock(void /* params in registers */); | ||
90 | asmlinkage void __up_wakeup(void /* special register calling convention */); | ||
91 | |||
92 | asmlinkage void __down(struct semaphore * sem); | ||
93 | asmlinkage int __down_interruptible(struct semaphore * sem); | ||
94 | asmlinkage int __down_trylock(struct semaphore * sem); | ||
95 | asmlinkage void __up(struct semaphore * sem); | ||
96 | |||
97 | /* | ||
98 | * This is ugly, but we want the default case to fall through. | ||
99 | * "__down_failed" is a special asm handler that calls the C | ||
100 | * routine that actually waits. See arch/x86_64/kernel/semaphore.c | ||
101 | */ | ||
102 | static inline void down(struct semaphore * sem) | ||
103 | { | ||
104 | might_sleep(); | ||
105 | |||
106 | __asm__ __volatile__( | ||
107 | "# atomic down operation\n\t" | ||
108 | LOCK_PREFIX "decl %0\n\t" /* --sem->count */ | ||
109 | "jns 1f\n\t" | ||
110 | "call __down_failed\n" | ||
111 | "1:" | ||
112 | :"=m" (sem->count) | ||
113 | :"D" (sem) | ||
114 | :"memory"); | ||
115 | } | ||
116 | |||
117 | /* | ||
118 | * Interruptible try to acquire a semaphore. If we obtained | ||
119 | * it, return zero. If we were interrupted, returns -EINTR | ||
120 | */ | ||
121 | static inline int down_interruptible(struct semaphore * sem) | ||
122 | { | ||
123 | int result; | ||
124 | |||
125 | might_sleep(); | ||
126 | |||
127 | __asm__ __volatile__( | ||
128 | "# atomic interruptible down operation\n\t" | ||
129 | "xorl %0,%0\n\t" | ||
130 | LOCK_PREFIX "decl %1\n\t" /* --sem->count */ | ||
131 | "jns 2f\n\t" | ||
132 | "call __down_failed_interruptible\n" | ||
133 | "2:\n" | ||
134 | :"=&a" (result), "=m" (sem->count) | ||
135 | :"D" (sem) | ||
136 | :"memory"); | ||
137 | return result; | ||
138 | } | ||
139 | |||
140 | /* | ||
141 | * Non-blockingly attempt to down() a semaphore. | ||
142 | * Returns zero if we acquired it | ||
143 | */ | ||
144 | static inline int down_trylock(struct semaphore * sem) | ||
145 | { | ||
146 | int result; | ||
147 | |||
148 | __asm__ __volatile__( | ||
149 | "# atomic interruptible down operation\n\t" | ||
150 | "xorl %0,%0\n\t" | ||
151 | LOCK_PREFIX "decl %1\n\t" /* --sem->count */ | ||
152 | "jns 2f\n\t" | ||
153 | "call __down_failed_trylock\n\t" | ||
154 | "2:\n" | ||
155 | :"=&a" (result), "=m" (sem->count) | ||
156 | :"D" (sem) | ||
157 | :"memory","cc"); | ||
158 | return result; | ||
159 | } | ||
160 | |||
161 | /* | ||
162 | * Note! This is subtle. We jump to wake people up only if | ||
163 | * the semaphore was negative (== somebody was waiting on it). | ||
164 | * The default case (no contention) will result in NO | ||
165 | * jumps for both down() and up(). | ||
166 | */ | ||
167 | static inline void up(struct semaphore * sem) | ||
168 | { | ||
169 | __asm__ __volatile__( | ||
170 | "# atomic up operation\n\t" | ||
171 | LOCK_PREFIX "incl %0\n\t" /* ++sem->count */ | ||
172 | "jg 1f\n\t" | ||
173 | "call __up_wakeup\n" | ||
174 | "1:" | ||
175 | :"=m" (sem->count) | ||
176 | :"D" (sem) | ||
177 | :"memory"); | ||
178 | } | ||
179 | #endif /* __KERNEL__ */ | ||
180 | #endif | ||
diff --git a/include/asm-xtensa/semaphore.h b/include/asm-xtensa/semaphore.h index 3e04167cd9dc..d9b2034ed1d2 100644 --- a/include/asm-xtensa/semaphore.h +++ b/include/asm-xtensa/semaphore.h | |||
@@ -1,99 +1 @@ | |||
1 | /* | #include <linux/semaphore.h> | |
2 | * linux/include/asm-xtensa/semaphore.h | ||
3 | * | ||
4 | * This file is subject to the terms and conditions of the GNU General Public | ||
5 | * License. See the file "COPYING" in the main directory of this archive | ||
6 | * for more details. | ||
7 | * | ||
8 | * Copyright (C) 2001 - 2005 Tensilica Inc. | ||
9 | */ | ||
10 | |||
11 | #ifndef _XTENSA_SEMAPHORE_H | ||
12 | #define _XTENSA_SEMAPHORE_H | ||
13 | |||
14 | #include <asm/atomic.h> | ||
15 | #include <asm/system.h> | ||
16 | #include <linux/wait.h> | ||
17 | #include <linux/rwsem.h> | ||
18 | |||
19 | struct semaphore { | ||
20 | atomic_t count; | ||
21 | int sleepers; | ||
22 | wait_queue_head_t wait; | ||
23 | }; | ||
24 | |||
25 | #define __SEMAPHORE_INITIALIZER(name,n) \ | ||
26 | { \ | ||
27 | .count = ATOMIC_INIT(n), \ | ||
28 | .sleepers = 0, \ | ||
29 | .wait = __WAIT_QUEUE_HEAD_INITIALIZER((name).wait) \ | ||
30 | } | ||
31 | |||
32 | #define __DECLARE_SEMAPHORE_GENERIC(name,count) \ | ||
33 | struct semaphore name = __SEMAPHORE_INITIALIZER(name,count) | ||
34 | |||
35 | #define DECLARE_MUTEX(name) __DECLARE_SEMAPHORE_GENERIC(name,1) | ||
36 | |||
37 | static inline void sema_init (struct semaphore *sem, int val) | ||
38 | { | ||
39 | atomic_set(&sem->count, val); | ||
40 | sem->sleepers = 0; | ||
41 | init_waitqueue_head(&sem->wait); | ||
42 | } | ||
43 | |||
44 | static inline void init_MUTEX (struct semaphore *sem) | ||
45 | { | ||
46 | sema_init(sem, 1); | ||
47 | } | ||
48 | |||
49 | static inline void init_MUTEX_LOCKED (struct semaphore *sem) | ||
50 | { | ||
51 | sema_init(sem, 0); | ||
52 | } | ||
53 | |||
54 | asmlinkage void __down(struct semaphore * sem); | ||
55 | asmlinkage int __down_interruptible(struct semaphore * sem); | ||
56 | asmlinkage int __down_trylock(struct semaphore * sem); | ||
57 | asmlinkage void __up(struct semaphore * sem); | ||
58 | |||
59 | extern spinlock_t semaphore_wake_lock; | ||
60 | |||
61 | static inline void down(struct semaphore * sem) | ||
62 | { | ||
63 | might_sleep(); | ||
64 | |||
65 | if (atomic_sub_return(1, &sem->count) < 0) | ||
66 | __down(sem); | ||
67 | } | ||
68 | |||
69 | static inline int down_interruptible(struct semaphore * sem) | ||
70 | { | ||
71 | int ret = 0; | ||
72 | |||
73 | might_sleep(); | ||
74 | |||
75 | if (atomic_sub_return(1, &sem->count) < 0) | ||
76 | ret = __down_interruptible(sem); | ||
77 | return ret; | ||
78 | } | ||
79 | |||
80 | static inline int down_trylock(struct semaphore * sem) | ||
81 | { | ||
82 | int ret = 0; | ||
83 | |||
84 | if (atomic_sub_return(1, &sem->count) < 0) | ||
85 | ret = __down_trylock(sem); | ||
86 | return ret; | ||
87 | } | ||
88 | |||
89 | /* | ||
90 | * Note! This is subtle. We jump to wake people up only if | ||
91 | * the semaphore was negative (== somebody was waiting on it). | ||
92 | */ | ||
93 | static inline void up(struct semaphore * sem) | ||
94 | { | ||
95 | if (atomic_add_return(1, &sem->count) <= 0) | ||
96 | __up(sem); | ||
97 | } | ||
98 | |||
99 | #endif /* _XTENSA_SEMAPHORE_H */ | ||
diff --git a/include/linux/quota.h b/include/linux/quota.h index 6e0393a5b2ea..eb560d031acd 100644 --- a/include/linux/quota.h +++ b/include/linux/quota.h | |||
@@ -160,14 +160,18 @@ enum { | |||
160 | 160 | ||
161 | 161 | ||
162 | #ifdef __KERNEL__ | 162 | #ifdef __KERNEL__ |
163 | #include <linux/spinlock.h> | 163 | #include <linux/list.h> |
164 | #include <linux/rwsem.h> | ||
165 | #include <linux/mutex.h> | 164 | #include <linux/mutex.h> |
165 | #include <linux/rwsem.h> | ||
166 | #include <linux/spinlock.h> | ||
167 | #include <linux/wait.h> | ||
166 | 168 | ||
167 | #include <linux/dqblk_xfs.h> | 169 | #include <linux/dqblk_xfs.h> |
168 | #include <linux/dqblk_v1.h> | 170 | #include <linux/dqblk_v1.h> |
169 | #include <linux/dqblk_v2.h> | 171 | #include <linux/dqblk_v2.h> |
170 | 172 | ||
173 | #include <asm/atomic.h> | ||
174 | |||
171 | extern spinlock_t dq_data_lock; | 175 | extern spinlock_t dq_data_lock; |
172 | 176 | ||
173 | /* Maximal numbers of writes for quota operation (insert/delete/update) | 177 | /* Maximal numbers of writes for quota operation (insert/delete/update) |
diff --git a/include/linux/semaphore.h b/include/linux/semaphore.h new file mode 100644 index 000000000000..9cae64b00d6b --- /dev/null +++ b/include/linux/semaphore.h | |||
@@ -0,0 +1,51 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2008 Intel Corporation | ||
3 | * Author: Matthew Wilcox <willy@linux.intel.com> | ||
4 | * | ||
5 | * Distributed under the terms of the GNU GPL, version 2 | ||
6 | * | ||
7 | * Please see kernel/semaphore.c for documentation of these functions | ||
8 | */ | ||
9 | #ifndef __LINUX_SEMAPHORE_H | ||
10 | #define __LINUX_SEMAPHORE_H | ||
11 | |||
12 | #include <linux/list.h> | ||
13 | #include <linux/spinlock.h> | ||
14 | |||
15 | /* Please don't access any members of this structure directly */ | ||
16 | struct semaphore { | ||
17 | spinlock_t lock; | ||
18 | unsigned int count; | ||
19 | struct list_head wait_list; | ||
20 | }; | ||
21 | |||
22 | #define __SEMAPHORE_INITIALIZER(name, n) \ | ||
23 | { \ | ||
24 | .lock = __SPIN_LOCK_UNLOCKED((name).lock), \ | ||
25 | .count = n, \ | ||
26 | .wait_list = LIST_HEAD_INIT((name).wait_list), \ | ||
27 | } | ||
28 | |||
29 | #define __DECLARE_SEMAPHORE_GENERIC(name, count) \ | ||
30 | struct semaphore name = __SEMAPHORE_INITIALIZER(name, count) | ||
31 | |||
32 | #define DECLARE_MUTEX(name) __DECLARE_SEMAPHORE_GENERIC(name, 1) | ||
33 | |||
34 | static inline void sema_init(struct semaphore *sem, int val) | ||
35 | { | ||
36 | static struct lock_class_key __key; | ||
37 | *sem = (struct semaphore) __SEMAPHORE_INITIALIZER(*sem, val); | ||
38 | lockdep_init_map(&sem->lock.dep_map, "semaphore->lock", &__key, 0); | ||
39 | } | ||
40 | |||
41 | #define init_MUTEX(sem) sema_init(sem, 1) | ||
42 | #define init_MUTEX_LOCKED(sem) sema_init(sem, 0) | ||
43 | |||
44 | extern void down(struct semaphore *sem); | ||
45 | extern int __must_check down_interruptible(struct semaphore *sem); | ||
46 | extern int __must_check down_killable(struct semaphore *sem); | ||
47 | extern int __must_check down_trylock(struct semaphore *sem); | ||
48 | extern int __must_check down_timeout(struct semaphore *sem, long jiffies); | ||
49 | extern void up(struct semaphore *sem); | ||
50 | |||
51 | #endif /* __LINUX_SEMAPHORE_H */ | ||
diff --git a/kernel/Makefile b/kernel/Makefile index 6c584c55a6e9..f45c69e69688 100644 --- a/kernel/Makefile +++ b/kernel/Makefile | |||
@@ -8,7 +8,7 @@ obj-y = sched.o fork.o exec_domain.o panic.o printk.o profile.o \ | |||
8 | signal.o sys.o kmod.o workqueue.o pid.o \ | 8 | signal.o sys.o kmod.o workqueue.o pid.o \ |
9 | rcupdate.o extable.o params.o posix-timers.o \ | 9 | rcupdate.o extable.o params.o posix-timers.o \ |
10 | kthread.o wait.o kfifo.o sys_ni.o posix-cpu-timers.o mutex.o \ | 10 | kthread.o wait.o kfifo.o sys_ni.o posix-cpu-timers.o mutex.o \ |
11 | hrtimer.o rwsem.o nsproxy.o srcu.o \ | 11 | hrtimer.o rwsem.o nsproxy.o srcu.o semaphore.o \ |
12 | notifier.o ksysfs.o pm_qos_params.o | 12 | notifier.o ksysfs.o pm_qos_params.o |
13 | 13 | ||
14 | obj-$(CONFIG_SYSCTL) += sysctl_check.o | 14 | obj-$(CONFIG_SYSCTL) += sysctl_check.o |
diff --git a/kernel/semaphore.c b/kernel/semaphore.c new file mode 100644 index 000000000000..5c2942e768cd --- /dev/null +++ b/kernel/semaphore.c | |||
@@ -0,0 +1,264 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2008 Intel Corporation | ||
3 | * Author: Matthew Wilcox <willy@linux.intel.com> | ||
4 | * | ||
5 | * Distributed under the terms of the GNU GPL, version 2 | ||
6 | * | ||
7 | * This file implements counting semaphores. | ||
8 | * A counting semaphore may be acquired 'n' times before sleeping. | ||
9 | * See mutex.c for single-acquisition sleeping locks which enforce | ||
10 | * rules which allow code to be debugged more easily. | ||
11 | */ | ||
12 | |||
13 | /* | ||
14 | * Some notes on the implementation: | ||
15 | * | ||
16 | * The spinlock controls access to the other members of the semaphore. | ||
17 | * down_trylock() and up() can be called from interrupt context, so we | ||
18 | * have to disable interrupts when taking the lock. It turns out various | ||
19 | * parts of the kernel expect to be able to use down() on a semaphore in | ||
20 | * interrupt context when they know it will succeed, so we have to use | ||
21 | * irqsave variants for down(), down_interruptible() and down_killable() | ||
22 | * too. | ||
23 | * | ||
24 | * The ->count variable represents how many more tasks can acquire this | ||
25 | * semaphore. If it's zero, there may be tasks waiting on the wait_list. | ||
26 | */ | ||
27 | |||
28 | #include <linux/compiler.h> | ||
29 | #include <linux/kernel.h> | ||
30 | #include <linux/module.h> | ||
31 | #include <linux/sched.h> | ||
32 | #include <linux/semaphore.h> | ||
33 | #include <linux/spinlock.h> | ||
34 | |||
35 | static noinline void __down(struct semaphore *sem); | ||
36 | static noinline int __down_interruptible(struct semaphore *sem); | ||
37 | static noinline int __down_killable(struct semaphore *sem); | ||
38 | static noinline int __down_timeout(struct semaphore *sem, long jiffies); | ||
39 | static noinline void __up(struct semaphore *sem); | ||
40 | |||
41 | /** | ||
42 | * down - acquire the semaphore | ||
43 | * @sem: the semaphore to be acquired | ||
44 | * | ||
45 | * Acquires the semaphore. If no more tasks are allowed to acquire the | ||
46 | * semaphore, calling this function will put the task to sleep until the | ||
47 | * semaphore is released. | ||
48 | * | ||
49 | * Use of this function is deprecated, please use down_interruptible() or | ||
50 | * down_killable() instead. | ||
51 | */ | ||
52 | void down(struct semaphore *sem) | ||
53 | { | ||
54 | unsigned long flags; | ||
55 | |||
56 | spin_lock_irqsave(&sem->lock, flags); | ||
57 | if (likely(sem->count > 0)) | ||
58 | sem->count--; | ||
59 | else | ||
60 | __down(sem); | ||
61 | spin_unlock_irqrestore(&sem->lock, flags); | ||
62 | } | ||
63 | EXPORT_SYMBOL(down); | ||
64 | |||
65 | /** | ||
66 | * down_interruptible - acquire the semaphore unless interrupted | ||
67 | * @sem: the semaphore to be acquired | ||
68 | * | ||
69 | * Attempts to acquire the semaphore. If no more tasks are allowed to | ||
70 | * acquire the semaphore, calling this function will put the task to sleep. | ||
71 | * If the sleep is interrupted by a signal, this function will return -EINTR. | ||
72 | * If the semaphore is successfully acquired, this function returns 0. | ||
73 | */ | ||
74 | int down_interruptible(struct semaphore *sem) | ||
75 | { | ||
76 | unsigned long flags; | ||
77 | int result = 0; | ||
78 | |||
79 | spin_lock_irqsave(&sem->lock, flags); | ||
80 | if (likely(sem->count > 0)) | ||
81 | sem->count--; | ||
82 | else | ||
83 | result = __down_interruptible(sem); | ||
84 | spin_unlock_irqrestore(&sem->lock, flags); | ||
85 | |||
86 | return result; | ||
87 | } | ||
88 | EXPORT_SYMBOL(down_interruptible); | ||
89 | |||
90 | /** | ||
91 | * down_killable - acquire the semaphore unless killed | ||
92 | * @sem: the semaphore to be acquired | ||
93 | * | ||
94 | * Attempts to acquire the semaphore. If no more tasks are allowed to | ||
95 | * acquire the semaphore, calling this function will put the task to sleep. | ||
96 | * If the sleep is interrupted by a fatal signal, this function will return | ||
97 | * -EINTR. If the semaphore is successfully acquired, this function returns | ||
98 | * 0. | ||
99 | */ | ||
100 | int down_killable(struct semaphore *sem) | ||
101 | { | ||
102 | unsigned long flags; | ||
103 | int result = 0; | ||
104 | |||
105 | spin_lock_irqsave(&sem->lock, flags); | ||
106 | if (likely(sem->count > 0)) | ||
107 | sem->count--; | ||
108 | else | ||
109 | result = __down_killable(sem); | ||
110 | spin_unlock_irqrestore(&sem->lock, flags); | ||
111 | |||
112 | return result; | ||
113 | } | ||
114 | EXPORT_SYMBOL(down_killable); | ||
115 | |||
116 | /** | ||
117 | * down_trylock - try to acquire the semaphore, without waiting | ||
118 | * @sem: the semaphore to be acquired | ||
119 | * | ||
120 | * Try to acquire the semaphore atomically. Returns 0 if the mutex has | ||
121 | * been acquired successfully or 1 if it it cannot be acquired. | ||
122 | * | ||
123 | * NOTE: This return value is inverted from both spin_trylock and | ||
124 | * mutex_trylock! Be careful about this when converting code. | ||
125 | * | ||
126 | * Unlike mutex_trylock, this function can be used from interrupt context, | ||
127 | * and the semaphore can be released by any task or interrupt. | ||
128 | */ | ||
129 | int down_trylock(struct semaphore *sem) | ||
130 | { | ||
131 | unsigned long flags; | ||
132 | int count; | ||
133 | |||
134 | spin_lock_irqsave(&sem->lock, flags); | ||
135 | count = sem->count - 1; | ||
136 | if (likely(count >= 0)) | ||
137 | sem->count = count; | ||
138 | spin_unlock_irqrestore(&sem->lock, flags); | ||
139 | |||
140 | return (count < 0); | ||
141 | } | ||
142 | EXPORT_SYMBOL(down_trylock); | ||
143 | |||
144 | /** | ||
145 | * down_timeout - acquire the semaphore within a specified time | ||
146 | * @sem: the semaphore to be acquired | ||
147 | * @jiffies: how long to wait before failing | ||
148 | * | ||
149 | * Attempts to acquire the semaphore. If no more tasks are allowed to | ||
150 | * acquire the semaphore, calling this function will put the task to sleep. | ||
151 | * If the semaphore is not released within the specified number of jiffies, | ||
152 | * this function returns -ETIME. It returns 0 if the semaphore was acquired. | ||
153 | */ | ||
154 | int down_timeout(struct semaphore *sem, long jiffies) | ||
155 | { | ||
156 | unsigned long flags; | ||
157 | int result = 0; | ||
158 | |||
159 | spin_lock_irqsave(&sem->lock, flags); | ||
160 | if (likely(sem->count > 0)) | ||
161 | sem->count--; | ||
162 | else | ||
163 | result = __down_timeout(sem, jiffies); | ||
164 | spin_unlock_irqrestore(&sem->lock, flags); | ||
165 | |||
166 | return result; | ||
167 | } | ||
168 | EXPORT_SYMBOL(down_timeout); | ||
169 | |||
170 | /** | ||
171 | * up - release the semaphore | ||
172 | * @sem: the semaphore to release | ||
173 | * | ||
174 | * Release the semaphore. Unlike mutexes, up() may be called from any | ||
175 | * context and even by tasks which have never called down(). | ||
176 | */ | ||
177 | void up(struct semaphore *sem) | ||
178 | { | ||
179 | unsigned long flags; | ||
180 | |||
181 | spin_lock_irqsave(&sem->lock, flags); | ||
182 | if (likely(list_empty(&sem->wait_list))) | ||
183 | sem->count++; | ||
184 | else | ||
185 | __up(sem); | ||
186 | spin_unlock_irqrestore(&sem->lock, flags); | ||
187 | } | ||
188 | EXPORT_SYMBOL(up); | ||
189 | |||
190 | /* Functions for the contended case */ | ||
191 | |||
192 | struct semaphore_waiter { | ||
193 | struct list_head list; | ||
194 | struct task_struct *task; | ||
195 | int up; | ||
196 | }; | ||
197 | |||
198 | /* | ||
199 | * Because this function is inlined, the 'state' parameter will be | ||
200 | * constant, and thus optimised away by the compiler. Likewise the | ||
201 | * 'timeout' parameter for the cases without timeouts. | ||
202 | */ | ||
203 | static inline int __sched __down_common(struct semaphore *sem, long state, | ||
204 | long timeout) | ||
205 | { | ||
206 | struct task_struct *task = current; | ||
207 | struct semaphore_waiter waiter; | ||
208 | |||
209 | list_add_tail(&waiter.list, &sem->wait_list); | ||
210 | waiter.task = task; | ||
211 | waiter.up = 0; | ||
212 | |||
213 | for (;;) { | ||
214 | if (state == TASK_INTERRUPTIBLE && signal_pending(task)) | ||
215 | goto interrupted; | ||
216 | if (state == TASK_KILLABLE && fatal_signal_pending(task)) | ||
217 | goto interrupted; | ||
218 | if (timeout <= 0) | ||
219 | goto timed_out; | ||
220 | __set_task_state(task, state); | ||
221 | spin_unlock_irq(&sem->lock); | ||
222 | timeout = schedule_timeout(timeout); | ||
223 | spin_lock_irq(&sem->lock); | ||
224 | if (waiter.up) | ||
225 | return 0; | ||
226 | } | ||
227 | |||
228 | timed_out: | ||
229 | list_del(&waiter.list); | ||
230 | return -ETIME; | ||
231 | |||
232 | interrupted: | ||
233 | list_del(&waiter.list); | ||
234 | return -EINTR; | ||
235 | } | ||
236 | |||
237 | static noinline void __sched __down(struct semaphore *sem) | ||
238 | { | ||
239 | __down_common(sem, TASK_UNINTERRUPTIBLE, MAX_SCHEDULE_TIMEOUT); | ||
240 | } | ||
241 | |||
242 | static noinline int __sched __down_interruptible(struct semaphore *sem) | ||
243 | { | ||
244 | return __down_common(sem, TASK_INTERRUPTIBLE, MAX_SCHEDULE_TIMEOUT); | ||
245 | } | ||
246 | |||
247 | static noinline int __sched __down_killable(struct semaphore *sem) | ||
248 | { | ||
249 | return __down_common(sem, TASK_KILLABLE, MAX_SCHEDULE_TIMEOUT); | ||
250 | } | ||
251 | |||
252 | static noinline int __sched __down_timeout(struct semaphore *sem, long jiffies) | ||
253 | { | ||
254 | return __down_common(sem, TASK_UNINTERRUPTIBLE, jiffies); | ||
255 | } | ||
256 | |||
257 | static noinline void __sched __up(struct semaphore *sem) | ||
258 | { | ||
259 | struct semaphore_waiter *waiter = list_first_entry(&sem->wait_list, | ||
260 | struct semaphore_waiter, list); | ||
261 | list_del(&waiter->list); | ||
262 | waiter->up = 1; | ||
263 | wake_up_process(waiter->task); | ||
264 | } | ||
diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug index eef557dc46c3..80db357b0a42 100644 --- a/lib/Kconfig.debug +++ b/lib/Kconfig.debug | |||
@@ -265,16 +265,6 @@ config DEBUG_MUTEXES | |||
265 | This feature allows mutex semantics violations to be detected and | 265 | This feature allows mutex semantics violations to be detected and |
266 | reported. | 266 | reported. |
267 | 267 | ||
268 | config DEBUG_SEMAPHORE | ||
269 | bool "Semaphore debugging" | ||
270 | depends on DEBUG_KERNEL | ||
271 | depends on ALPHA || FRV | ||
272 | default n | ||
273 | help | ||
274 | If you say Y here then semaphore processing will issue lots of | ||
275 | verbose debugging messages. If you suspect a semaphore problem or a | ||
276 | kernel hacker asks for this option then say Y. Otherwise say N. | ||
277 | |||
278 | config DEBUG_LOCK_ALLOC | 268 | config DEBUG_LOCK_ALLOC |
279 | bool "Lock debugging: detect incorrect freeing of live locks" | 269 | bool "Lock debugging: detect incorrect freeing of live locks" |
280 | depends on DEBUG_KERNEL && TRACE_IRQFLAGS_SUPPORT && STACKTRACE_SUPPORT && LOCKDEP_SUPPORT | 270 | depends on DEBUG_KERNEL && TRACE_IRQFLAGS_SUPPORT && STACKTRACE_SUPPORT && LOCKDEP_SUPPORT |
diff --git a/lib/Makefile b/lib/Makefile index 23de261a4c83..28dba90d5020 100644 --- a/lib/Makefile +++ b/lib/Makefile | |||
@@ -29,7 +29,6 @@ obj-$(CONFIG_DEBUG_LOCKING_API_SELFTESTS) += locking-selftest.o | |||
29 | obj-$(CONFIG_DEBUG_SPINLOCK) += spinlock_debug.o | 29 | obj-$(CONFIG_DEBUG_SPINLOCK) += spinlock_debug.o |
30 | lib-$(CONFIG_RWSEM_GENERIC_SPINLOCK) += rwsem-spinlock.o | 30 | lib-$(CONFIG_RWSEM_GENERIC_SPINLOCK) += rwsem-spinlock.o |
31 | lib-$(CONFIG_RWSEM_XCHGADD_ALGORITHM) += rwsem.o | 31 | lib-$(CONFIG_RWSEM_XCHGADD_ALGORITHM) += rwsem.o |
32 | lib-$(CONFIG_SEMAPHORE_SLEEPERS) += semaphore-sleepers.o | ||
33 | lib-$(CONFIG_GENERIC_FIND_NEXT_BIT) += find_next_bit.o | 32 | lib-$(CONFIG_GENERIC_FIND_NEXT_BIT) += find_next_bit.o |
34 | obj-$(CONFIG_GENERIC_HWEIGHT) += hweight.o | 33 | obj-$(CONFIG_GENERIC_HWEIGHT) += hweight.o |
35 | obj-$(CONFIG_LOCK_KERNEL) += kernel_lock.o | 34 | obj-$(CONFIG_LOCK_KERNEL) += kernel_lock.o |
diff --git a/lib/kernel_lock.c b/lib/kernel_lock.c index 812dbf00844b..fbc11a336bc5 100644 --- a/lib/kernel_lock.c +++ b/lib/kernel_lock.c | |||
@@ -8,6 +8,7 @@ | |||
8 | #include <linux/smp_lock.h> | 8 | #include <linux/smp_lock.h> |
9 | #include <linux/module.h> | 9 | #include <linux/module.h> |
10 | #include <linux/kallsyms.h> | 10 | #include <linux/kallsyms.h> |
11 | #include <asm/semaphore.h> | ||
11 | 12 | ||
12 | /* | 13 | /* |
13 | * The 'big kernel semaphore' | 14 | * The 'big kernel semaphore' |
diff --git a/lib/semaphore-sleepers.c b/lib/semaphore-sleepers.c deleted file mode 100644 index 0198782cdacb..000000000000 --- a/lib/semaphore-sleepers.c +++ /dev/null | |||
@@ -1,176 +0,0 @@ | |||
1 | /* | ||
2 | * i386 and x86-64 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 | #include <linux/sched.h> | ||
16 | #include <linux/err.h> | ||
17 | #include <linux/init.h> | ||
18 | #include <asm/semaphore.h> | ||
19 | |||
20 | /* | ||
21 | * Semaphores are implemented using a two-way counter: | ||
22 | * The "count" variable is decremented for each process | ||
23 | * that tries to acquire the semaphore, while the "sleeping" | ||
24 | * variable is a count of such acquires. | ||
25 | * | ||
26 | * Notably, the inline "up()" and "down()" functions can | ||
27 | * efficiently test if they need to do any extra work (up | ||
28 | * needs to do something only if count was negative before | ||
29 | * the increment operation. | ||
30 | * | ||
31 | * "sleeping" and the contention routine ordering is protected | ||
32 | * by the spinlock in the semaphore's waitqueue head. | ||
33 | * | ||
34 | * Note that these functions are only called when there is | ||
35 | * contention on the lock, and as such all this is the | ||
36 | * "non-critical" part of the whole semaphore business. The | ||
37 | * critical part is the inline stuff in <asm/semaphore.h> | ||
38 | * where we want to avoid any extra jumps and calls. | ||
39 | */ | ||
40 | |||
41 | /* | ||
42 | * Logic: | ||
43 | * - only on a boundary condition do we need to care. When we go | ||
44 | * from a negative count to a non-negative, we wake people up. | ||
45 | * - when we go from a non-negative count to a negative do we | ||
46 | * (a) synchronize with the "sleeper" count and (b) make sure | ||
47 | * that we're on the wakeup list before we synchronize so that | ||
48 | * we cannot lose wakeup events. | ||
49 | */ | ||
50 | |||
51 | void __up(struct semaphore *sem) | ||
52 | { | ||
53 | wake_up(&sem->wait); | ||
54 | } | ||
55 | |||
56 | void __sched __down(struct semaphore *sem) | ||
57 | { | ||
58 | struct task_struct *tsk = current; | ||
59 | DECLARE_WAITQUEUE(wait, tsk); | ||
60 | unsigned long flags; | ||
61 | |||
62 | tsk->state = TASK_UNINTERRUPTIBLE; | ||
63 | spin_lock_irqsave(&sem->wait.lock, flags); | ||
64 | add_wait_queue_exclusive_locked(&sem->wait, &wait); | ||
65 | |||
66 | sem->sleepers++; | ||
67 | for (;;) { | ||
68 | int sleepers = sem->sleepers; | ||
69 | |||
70 | /* | ||
71 | * Add "everybody else" into it. They aren't | ||
72 | * playing, because we own the spinlock in | ||
73 | * the wait_queue_head. | ||
74 | */ | ||
75 | if (!atomic_add_negative(sleepers - 1, &sem->count)) { | ||
76 | sem->sleepers = 0; | ||
77 | break; | ||
78 | } | ||
79 | sem->sleepers = 1; /* us - see -1 above */ | ||
80 | spin_unlock_irqrestore(&sem->wait.lock, flags); | ||
81 | |||
82 | schedule(); | ||
83 | |||
84 | spin_lock_irqsave(&sem->wait.lock, flags); | ||
85 | tsk->state = TASK_UNINTERRUPTIBLE; | ||
86 | } | ||
87 | remove_wait_queue_locked(&sem->wait, &wait); | ||
88 | wake_up_locked(&sem->wait); | ||
89 | spin_unlock_irqrestore(&sem->wait.lock, flags); | ||
90 | tsk->state = TASK_RUNNING; | ||
91 | } | ||
92 | |||
93 | int __sched __down_interruptible(struct semaphore *sem) | ||
94 | { | ||
95 | int retval = 0; | ||
96 | struct task_struct *tsk = current; | ||
97 | DECLARE_WAITQUEUE(wait, tsk); | ||
98 | unsigned long flags; | ||
99 | |||
100 | tsk->state = TASK_INTERRUPTIBLE; | ||
101 | spin_lock_irqsave(&sem->wait.lock, flags); | ||
102 | add_wait_queue_exclusive_locked(&sem->wait, &wait); | ||
103 | |||
104 | sem->sleepers++; | ||
105 | for (;;) { | ||
106 | int sleepers = sem->sleepers; | ||
107 | |||
108 | /* | ||
109 | * With signals pending, this turns into | ||
110 | * the trylock failure case - we won't be | ||
111 | * sleeping, and we* can't get the lock as | ||
112 | * it has contention. Just correct the count | ||
113 | * and exit. | ||
114 | */ | ||
115 | if (signal_pending(current)) { | ||
116 | retval = -EINTR; | ||
117 | sem->sleepers = 0; | ||
118 | atomic_add(sleepers, &sem->count); | ||
119 | break; | ||
120 | } | ||
121 | |||
122 | /* | ||
123 | * Add "everybody else" into it. They aren't | ||
124 | * playing, because we own the spinlock in | ||
125 | * wait_queue_head. The "-1" is because we're | ||
126 | * still hoping to get the semaphore. | ||
127 | */ | ||
128 | if (!atomic_add_negative(sleepers - 1, &sem->count)) { | ||
129 | sem->sleepers = 0; | ||
130 | break; | ||
131 | } | ||
132 | sem->sleepers = 1; /* us - see -1 above */ | ||
133 | spin_unlock_irqrestore(&sem->wait.lock, flags); | ||
134 | |||
135 | schedule(); | ||
136 | |||
137 | spin_lock_irqsave(&sem->wait.lock, flags); | ||
138 | tsk->state = TASK_INTERRUPTIBLE; | ||
139 | } | ||
140 | remove_wait_queue_locked(&sem->wait, &wait); | ||
141 | wake_up_locked(&sem->wait); | ||
142 | spin_unlock_irqrestore(&sem->wait.lock, flags); | ||
143 | |||
144 | tsk->state = TASK_RUNNING; | ||
145 | return retval; | ||
146 | } | ||
147 | |||
148 | /* | ||
149 | * Trylock failed - make sure we correct for | ||
150 | * having decremented the count. | ||
151 | * | ||
152 | * We could have done the trylock with a | ||
153 | * single "cmpxchg" without failure cases, | ||
154 | * but then it wouldn't work on a 386. | ||
155 | */ | ||
156 | int __down_trylock(struct semaphore *sem) | ||
157 | { | ||
158 | int sleepers; | ||
159 | unsigned long flags; | ||
160 | |||
161 | spin_lock_irqsave(&sem->wait.lock, flags); | ||
162 | sleepers = sem->sleepers + 1; | ||
163 | sem->sleepers = 0; | ||
164 | |||
165 | /* | ||
166 | * Add "everybody else" and us into it. They aren't | ||
167 | * playing, because we own the spinlock in the | ||
168 | * wait_queue_head. | ||
169 | */ | ||
170 | if (!atomic_add_negative(sleepers, &sem->count)) { | ||
171 | wake_up_locked(&sem->wait); | ||
172 | } | ||
173 | |||
174 | spin_unlock_irqrestore(&sem->wait.lock, flags); | ||
175 | return 1; | ||
176 | } | ||