Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Generic semaphore implementation

Semaphores are no longer performance-critical, so a generic C
implementation is better for maintainability, debuggability and
extensibility. Thanks to Peter Zijlstra for fixing the lockdep
warning. Thanks to Harvey Harrison for pointing out that the
unlikely() was unnecessary.

Signed-off-by: Matthew Wilcox <willy@linux.intel.com>
Acked-by: Ingo Molnar <mingo@elte.hu>

authored by

Matthew Wilcox and committed by
Matthew Wilcox
64ac24e7 e48b3dee

+314 -7679
+1 -1
arch/alpha/kernel/Makefile
··· 7 7 EXTRA_CFLAGS := -Werror -Wno-sign-compare 8 8 9 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 11 alpha_ksyms.o systbls.o err_common.o io.o 12 12 13 13 obj-$(CONFIG_VGA_HOSE) += console.o
-9
arch/alpha/kernel/alpha_ksyms.c
··· 77 77 EXPORT_SYMBOL(__strncpy_from_user); 78 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 81 * SMP-specific symbols. 91 82 */
-224
arch/alpha/kernel/semaphore.c
··· 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 - }
+1 -1
arch/arm/kernel/Makefile
··· 7 7 # Object file lists. 8 8 9 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 11 sys_arm.o stacktrace.o time.o traps.o 12 12 13 13 obj-$(CONFIG_ISA_DMA_API) += dma.o
-221
arch/arm/kernel/semaphore.c
··· 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);
+1 -1
arch/avr32/kernel/Makefile
··· 6 6 7 7 obj-$(CONFIG_SUBARCH_AVR32B) += entry-avr32b.o 8 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 10 obj-y += signal.o sys_avr32.o process.o time.o 11 11 obj-y += init_task.o switch_to.o cpu.o 12 12 obj-$(CONFIG_MODULES) += module.o avr32_ksyms.o
-148
arch/avr32/kernel/semaphore.c
··· 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);
-4
arch/blackfin/Kconfig
··· 31 31 bool 32 32 default y 33 33 34 - config SEMAPHORE_SLEEPERS 35 - bool 36 - default y 37 - 38 34 config GENERIC_FIND_NEXT_BIT 39 35 bool 40 36 default y
-5
arch/blackfin/kernel/bfin_ksyms.c
··· 42 42 43 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 45 EXPORT_SYMBOL(is_in_rom); 51 46 EXPORT_SYMBOL(bfin_return_from_exception); 52 47
+1 -2
arch/cris/kernel/Makefile
··· 5 5 6 6 extra-y := vmlinux.lds 7 7 8 - obj-y := process.o traps.o irq.o ptrace.o setup.o \ 9 - time.o sys_cris.o semaphore.o 8 + obj-y := process.o traps.o irq.o ptrace.o setup.o time.o sys_cris.o 10 9 11 10 obj-$(CONFIG_MODULES) += crisksyms.o 12 11 obj-$(CONFIG_MODULES) += module.o
-7
arch/cris/kernel/crisksyms.c
··· 9 9 #include <linux/string.h> 10 10 #include <linux/tty.h> 11 11 12 - #include <asm/semaphore.h> 13 12 #include <asm/processor.h> 14 13 #include <asm/uaccess.h> 15 14 #include <asm/checksum.h> ··· 47 48 /* Memory functions */ 48 49 EXPORT_SYMBOL(__ioremap); 49 50 EXPORT_SYMBOL(iounmap); 50 - 51 - /* Semaphore functions */ 52 - EXPORT_SYMBOL(__up); 53 - EXPORT_SYMBOL(__down); 54 - EXPORT_SYMBOL(__down_interruptible); 55 - EXPORT_SYMBOL(__down_trylock); 56 51 57 52 /* Userspace access functions */ 58 53 EXPORT_SYMBOL(__copy_user_zeroing);
-129
arch/cris/kernel/semaphore.c
··· 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 - }
+1 -1
arch/frv/kernel/Makefile
··· 9 9 10 10 obj-y := $(heads-y) entry.o entry-table.o break.o switch_to.o kernel_thread.o \ 11 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 13 debug-stub.o irq.o sleep.o uaccess.o 14 14 15 15 obj-$(CONFIG_GDBSTUB) += gdb-stub.o gdb-io.o
-1
arch/frv/kernel/frv_ksyms.c
··· 12 12 #include <asm/pgalloc.h> 13 13 #include <asm/irq.h> 14 14 #include <asm/io.h> 15 - #include <asm/semaphore.h> 16 15 #include <asm/checksum.h> 17 16 #include <asm/hardirq.h> 18 17 #include <asm/cacheflush.h>
-155
arch/frv/kernel/semaphore.c
··· 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);
+1 -1
arch/h8300/kernel/Makefile
··· 5 5 extra-y := vmlinux.lds 6 6 7 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 9 setup.o gpio.o init_task.o syscalls.o \ 10 10 entry.o 11 11
-1
arch/h8300/kernel/h8300_ksyms.c
··· 12 12 #include <asm/pgalloc.h> 13 13 #include <asm/irq.h> 14 14 #include <asm/io.h> 15 - #include <asm/semaphore.h> 16 15 #include <asm/checksum.h> 17 16 #include <asm/current.h> 18 17 #include <asm/gpio.h>
-132
arch/h8300/kernel/semaphore.c
··· 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 - }
+1 -1
arch/ia64/kernel/Makefile
··· 6 6 7 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 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 10 unwind.o mca.o mca_asm.o topology.o 11 11 12 12 obj-$(CONFIG_IA64_BRL_EMU) += brl_emu.o
-6
arch/ia64/kernel/ia64_ksyms.c
··· 19 19 EXPORT_SYMBOL(ip_fast_csum); /* hand-coded assembly */ 20 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 22 #include <asm/page.h> 29 23 EXPORT_SYMBOL(clear_page); 30 24
-165
arch/ia64/kernel/semaphore.c
··· 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 - }
+1 -1
arch/m32r/kernel/Makefile
··· 5 5 extra-y := head.o init_task.o vmlinux.lds 6 6 7 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 10 obj-$(CONFIG_SMP) += smp.o smpboot.o 11 11 obj-$(CONFIG_MODULES) += module.o
-5
arch/m32r/kernel/m32r_ksyms.c
··· 7 7 #include <linux/interrupt.h> 8 8 #include <linux/string.h> 9 9 10 - #include <asm/semaphore.h> 11 10 #include <asm/processor.h> 12 11 #include <asm/uaccess.h> 13 12 #include <asm/checksum.h> ··· 21 22 EXPORT_SYMBOL(__ioremap); 22 23 EXPORT_SYMBOL(iounmap); 23 24 EXPORT_SYMBOL(kernel_thread); 24 - EXPORT_SYMBOL(__down); 25 - EXPORT_SYMBOL(__down_interruptible); 26 - EXPORT_SYMBOL(__up); 27 - EXPORT_SYMBOL(__down_trylock); 28 25 29 26 /* Networking helper routines. */ 30 27 /* Delay loops */
-185
arch/m32r/kernel/semaphore.c
··· 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 - }
+1 -1
arch/m68k/kernel/Makefile
··· 10 10 extra-y += vmlinux.lds 11 11 12 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 15 devres-y = ../../../kernel/irq/devres.o 16 16
-6
arch/m68k/kernel/m68k_ksyms.c
··· 1 1 #include <linux/module.h> 2 - #include <asm/semaphore.h> 3 2 4 3 asmlinkage long long __ashldi3 (long long, int); 5 4 asmlinkage long long __ashrdi3 (long long, int); ··· 13 14 EXPORT_SYMBOL(__ashrdi3); 14 15 EXPORT_SYMBOL(__lshrdi3); 15 16 EXPORT_SYMBOL(__muldi3); 16 - 17 - EXPORT_SYMBOL(__down_failed); 18 - EXPORT_SYMBOL(__down_failed_interruptible); 19 - EXPORT_SYMBOL(__down_failed_trylock); 20 - EXPORT_SYMBOL(__up_wakeup); 21 17
-132
arch/m68k/kernel/semaphore.c
··· 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 - }
+1 -1
arch/m68k/lib/Makefile
··· 5 5 EXTRA_AFLAGS := -traditional 6 6 7 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
-53
arch/m68k/lib/semaphore.S
··· 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 -
+1 -1
arch/m68knommu/kernel/Makefile
··· 5 5 extra-y := vmlinux.lds 6 6 7 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 10 obj-$(CONFIG_MODULES) += module.o 11 11 obj-$(CONFIG_COMEMPCI) += comempci.o
-6
arch/m68knommu/kernel/m68k_ksyms.c
··· 13 13 #include <asm/pgalloc.h> 14 14 #include <asm/irq.h> 15 15 #include <asm/io.h> 16 - #include <asm/semaphore.h> 17 16 #include <asm/checksum.h> 18 17 #include <asm/current.h> 19 18 ··· 37 38 it's OK to leave it out of version control. */ 38 39 EXPORT_SYMBOL(memcpy); 39 40 EXPORT_SYMBOL(memset); 40 - 41 - EXPORT_SYMBOL(__down_failed); 42 - EXPORT_SYMBOL(__down_failed_interruptible); 43 - EXPORT_SYMBOL(__down_failed_trylock); 44 - EXPORT_SYMBOL(__up_wakeup); 45 41 46 42 /* 47 43 * libgcc functions - functions that are used internally by the
-133
arch/m68knommu/kernel/semaphore.c
··· 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 - }
+1 -1
arch/m68knommu/lib/Makefile
··· 4 4 5 5 lib-y := ashldi3.o ashrdi3.o lshrdi3.o \ 6 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
-66
arch/m68knommu/lib/semaphore.S
··· 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 -
+1 -1
arch/mips/kernel/Makefile
··· 5 5 extra-y := head.o init_task.o vmlinux.lds 6 6 7 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 9 time.o topology.o traps.o unaligned.o 10 10 11 11 obj-$(CONFIG_CEVT_BCM1480) += cevt-bcm1480.o
-168
arch/mips/kernel/semaphore.c
··· 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);
+1 -1
arch/mn10300/kernel/Makefile
··· 3 3 # 4 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 7 ptrace.o setup.o time.o sys_mn10300.o io.o kthread.o \ 8 8 switch_to.o mn10300_ksyms.o kernel_execve.o 9 9
-149
arch/mn10300/kernel/semaphore.c
··· 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);
+1 -1
arch/parisc/kernel/Makefile
··· 9 9 10 10 obj-y := cache.o pacache.o setup.o traps.o time.o irq.o \ 11 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 13 signal.o hpmc.o real2.o parisc_ksyms.o unaligned.o \ 14 14 process.o processor.o pdc_cons.o pdc_chassis.o unwind.o \ 15 15 topology.o
-5
arch/parisc/kernel/parisc_ksyms.c
··· 69 69 EXPORT_SYMBOL(memcpy_fromio); 70 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 72 extern void $$divI(void); 78 73 extern void $$divU(void); 79 74 extern void $$remI(void);
-102
arch/parisc/kernel/semaphore.c
··· 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 - }
+1 -1
arch/powerpc/kernel/Makefile
··· 12 12 CFLAGS_btext.o += -fPIC 13 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 16 irq.o align.o signal_32.o pmc.o vdso.o \ 17 17 init_task.o process.o systbl.o idle.o \ 18 18 signal.o
-1
arch/powerpc/kernel/ppc_ksyms.c
··· 15 15 #include <linux/bitops.h> 16 16 17 17 #include <asm/page.h> 18 - #include <asm/semaphore.h> 19 18 #include <asm/processor.h> 20 19 #include <asm/cacheflush.h> 21 20 #include <asm/uaccess.h>
-135
arch/powerpc/kernel/semaphore.c
··· 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);
-131
arch/ppc/kernel/semaphore.c
··· 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 - }
+1 -1
arch/s390/kernel/Makefile
··· 11 11 12 12 obj-y := bitmap.o traps.o time.o process.o base.o early.o \ 13 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 16 obj-y += $(if $(CONFIG_64BIT),entry64.o,entry.o) 17 17 obj-y += $(if $(CONFIG_64BIT),reipl64.o,reipl.o)
-7
arch/s390/kernel/s390_ksyms.c
··· 27 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 30 * binfmt_elf loader 38 31 */ 39 32 extern int dump_fpu (struct pt_regs * regs, s390_fp_regs *fpregs);
-108
arch/s390/kernel/semaphore.c
··· 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 -
+1 -1
arch/sh/kernel/Makefile_32
··· 5 5 extra-y := head_32.o init_task.o vmlinux.lds 6 6 7 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 9 syscalls_32.o time_32.o topology.o traps.o traps_32.o 10 10 11 11 obj-y += cpu/ timers/
+1 -1
arch/sh/kernel/Makefile_64
··· 1 1 extra-y := head_64.o init_task.o vmlinux.lds 2 2 3 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 5 syscalls_64.o time_64.o topology.o traps.o traps_64.o 6 6 7 7 obj-y += cpu/ timers/
-139
arch/sh/kernel/semaphore.c
··· 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 - }
-7
arch/sh/kernel/sh_ksyms_32.c
··· 9 9 #include <linux/pci.h> 10 10 #include <linux/irq.h> 11 11 #include <asm/sections.h> 12 - #include <asm/semaphore.h> 13 12 #include <asm/processor.h> 14 13 #include <asm/uaccess.h> 15 14 #include <asm/checksum.h> ··· 46 47 #ifdef CONFIG_MMU 47 48 EXPORT_SYMBOL(get_vm_area); 48 49 #endif 49 - 50 - /* semaphore exports */ 51 - EXPORT_SYMBOL(__up); 52 - EXPORT_SYMBOL(__down); 53 - EXPORT_SYMBOL(__down_interruptible); 54 - EXPORT_SYMBOL(__down_trylock); 55 50 56 51 EXPORT_SYMBOL(__udelay); 57 52 EXPORT_SYMBOL(__ndelay);
-4
arch/sh/kernel/sh_ksyms_64.c
··· 16 16 #include <linux/in6.h> 17 17 #include <linux/interrupt.h> 18 18 #include <linux/screen_info.h> 19 - #include <asm/semaphore.h> 20 19 #include <asm/processor.h> 21 20 #include <asm/uaccess.h> 22 21 #include <asm/checksum.h> ··· 36 37 EXPORT_SYMBOL(screen_info); 37 38 #endif 38 39 39 - EXPORT_SYMBOL(__down); 40 - EXPORT_SYMBOL(__down_trylock); 41 - EXPORT_SYMBOL(__up); 42 40 EXPORT_SYMBOL(__put_user_asm_l); 43 41 EXPORT_SYMBOL(__get_user_asm_l); 44 42 EXPORT_SYMBOL(copy_page);
+1 -1
arch/sparc/kernel/Makefile
··· 12 12 sys_sparc.o sunos_asm.o systbls.o \ 13 13 time.o windows.o cpu.o devices.o sclow.o \ 14 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 16 prom.o of_device.o devres.o 17 17 18 18 devres-y = ../../../kernel/irq/devres.o
-155
arch/sparc/kernel/semaphore.c
··· 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 - }
-5
arch/sparc/kernel/sparc_ksyms.c
··· 107 107 EXPORT_SYMBOL(___rw_read_exit); 108 108 EXPORT_SYMBOL(___rw_write_enter); 109 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 111 EXPORT_SYMBOL(sparc_valid_addr_bitmap); 117 112 EXPORT_SYMBOL(phys_base);
+1 -1
arch/sparc64/kernel/Makefile
··· 10 10 obj-y := process.o setup.o cpu.o idprom.o \ 11 11 traps.o auxio.o una_asm.o sysfs.o iommu.o \ 12 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 14 power.o sbus.o sparc64_ksyms.o chmc.o \ 15 15 visemul.o prom.o of_device.o hvapi.o sstate.o mdesc.o 16 16
-254
arch/sparc64/kernel/semaphore.c
··· 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 - }
-6
arch/sparc64/kernel/sparc64_ksyms.c
··· 130 130 131 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 133 /* RW semaphores */ 140 134 EXPORT_SYMBOL(__down_read); 141 135 EXPORT_SYMBOL(__down_read_trylock);
-4
arch/um/Kconfig.i386
··· 19 19 bool 20 20 default n 21 21 22 - config SEMAPHORE_SLEEPERS 23 - bool 24 - default y 25 - 26 22 config 3_LEVEL_PGTABLES 27 23 bool "Three-level pagetables (EXPERIMENTAL)" 28 24 default n
-4
arch/um/Kconfig.x86_64
··· 11 11 bool 12 12 default y 13 13 14 - config SEMAPHORE_SLEEPERS 15 - bool 16 - default y 17 - 18 14 config 3_LEVEL_PGTABLES 19 15 bool 20 16 default y
-12
arch/um/sys-i386/ksyms.c
··· 1 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 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 4 /* Networking helper routines. */ 17 5 EXPORT_SYMBOL(csum_partial);
+2 -6
arch/um/sys-ppc/Makefile
··· 3 3 .S.o: 4 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 7 ptrace_user.o sysrq.o 8 8 9 9 EXTRA_AFLAGS := -DCONFIG_PPC32 -I. -I$(srctree)/arch/ppc/kernel ··· 19 19 20 20 sigcontext.o: sigcontext.c 21 21 $(CC) $(USER_CFLAGS) $(EXTRA_CFLAGS) -c -o $@ $< 22 - 23 - semaphore.c: 24 - rm -f $@ 25 - ln -s $(srctree)/arch/ppc/kernel/$@ $@ 26 22 27 23 checksum.S: 28 24 rm -f $@ ··· 62 66 $(CC) $(EXTRA_AFLAGS) $(KBUILD_AFLAGS) -D__ASSEMBLY__ -D__UM_PPC__ -c $< -o $*.o 63 67 rm -f asm 64 68 65 - clean-files := $(OBJS) ppc_defs.h checksum.S semaphore.c mk_defs.c 69 + clean-files := $(OBJS) ppc_defs.h checksum.S mk_defs.c
+1 -12
arch/um/sys-x86_64/ksyms.c
··· 1 1 #include "linux/module.h" 2 - #include "linux/in6.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); 2 + #include "asm/string.h" 14 3 15 4 /*XXX: we need them because they would be exported by x86_64 */ 16 5 EXPORT_SYMBOL(__memcpy);
+1 -1
arch/v850/kernel/Makefile
··· 11 11 12 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 15 signal.o irq.o mach.o ptrace.o bug.o 16 16 obj-$(CONFIG_MODULES) += module.o v850_ksyms.o 17 17 # chip-specific code
-166
arch/v850/kernel/semaphore.c
··· 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 - }
-7
arch/v850/kernel/v850_ksyms.c
··· 11 11 #include <asm/pgalloc.h> 12 12 #include <asm/irq.h> 13 13 #include <asm/io.h> 14 - #include <asm/semaphore.h> 15 14 #include <asm/checksum.h> 16 15 #include <asm/current.h> 17 16 ··· 32 33 EXPORT_SYMBOL (memset); 33 34 EXPORT_SYMBOL (memcpy); 34 35 EXPORT_SYMBOL (memmove); 35 - 36 - /* semaphores */ 37 - EXPORT_SYMBOL (__down); 38 - EXPORT_SYMBOL (__down_interruptible); 39 - EXPORT_SYMBOL (__down_trylock); 40 - EXPORT_SYMBOL (__up); 41 36 42 37 /* 43 38 * libgcc functions - functions that are used internally by the
-3
arch/x86/Kconfig
··· 53 53 config HAVE_LATENCYTOP_SUPPORT 54 54 def_bool y 55 55 56 - config SEMAPHORE_SLEEPERS 57 - def_bool y 58 - 59 56 config FAST_CMPXCHG_LOCAL 60 57 bool 61 58 default y
-5
arch/x86/kernel/i386_ksyms_32.c
··· 1 1 #include <linux/module.h> 2 - #include <asm/semaphore.h> 3 2 #include <asm/checksum.h> 4 3 #include <asm/desc.h> 5 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 6 /* Networking helper routines. */ 12 7 EXPORT_SYMBOL(csum_partial_copy_generic); 13 8
-6
arch/x86/kernel/x8664_ksyms_64.c
··· 4 4 #include <linux/module.h> 5 5 #include <linux/smp.h> 6 6 7 - #include <asm/semaphore.h> 8 7 #include <asm/processor.h> 9 8 #include <asm/uaccess.h> 10 9 #include <asm/pgtable.h> 11 10 #include <asm/desc.h> 12 11 13 12 EXPORT_SYMBOL(kernel_thread); 14 - 15 - EXPORT_SYMBOL(__down_failed); 16 - EXPORT_SYMBOL(__down_failed_interruptible); 17 - EXPORT_SYMBOL(__down_failed_trylock); 18 - EXPORT_SYMBOL(__up_wakeup); 19 13 20 14 EXPORT_SYMBOL(__get_user_1); 21 15 EXPORT_SYMBOL(__get_user_2);
-83
arch/x86/lib/semaphore_32.S
··· 30 30 * value or just clobbered.. 31 31 */ 32 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 35 * rw spinlock fallbacks
-5
arch/x86/lib/thunk_64.S
··· 41 41 thunk rwsem_downgrade_thunk,rwsem_downgrade_wake 42 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 44 #ifdef CONFIG_TRACE_IRQFLAGS 50 45 thunk trace_hardirqs_on_thunk,trace_hardirqs_on 51 46 thunk trace_hardirqs_off_thunk,trace_hardirqs_off
+1 -1
arch/xtensa/kernel/Makefile
··· 5 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 9 setup.o signal.o syscall.o time.o traps.o vectors.o platform.o \ 10 10 pci-dma.o init_task.o io.o 11 11
-226
arch/xtensa/kernel/semaphore.c
··· 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 - }
-9
arch/xtensa/kernel/xtensa_ksyms.c
··· 26 26 #include <asm/io.h> 27 27 #include <asm/page.h> 28 28 #include <asm/pgalloc.h> 29 - #include <asm/semaphore.h> 30 29 #ifdef CONFIG_BLK_DEV_FD 31 30 #include <asm/floppy.h> 32 31 #endif ··· 69 70 EXPORT_SYMBOL(__umodsi3); 70 71 EXPORT_SYMBOL(__udivdi3); 71 72 EXPORT_SYMBOL(__umoddi3); 72 - 73 - /* 74 - * Semaphore operations 75 - */ 76 - EXPORT_SYMBOL(__down); 77 - EXPORT_SYMBOL(__down_interruptible); 78 - EXPORT_SYMBOL(__down_trylock); 79 - EXPORT_SYMBOL(__up); 80 73 81 74 #ifdef CONFIG_NET 82 75 /*
+1 -149
include/asm-alpha/semaphore.h
··· 1 - #ifndef _ALPHA_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 1 + #include <linux/semaphore.h>
-84
include/asm-arm/semaphore-helper.h
··· 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
+1 -98
include/asm-arm/semaphore.h
··· 1 - /* 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 1 + #include <linux/semaphore.h>
+1 -108
include/asm-avr32/semaphore.h
··· 1 - /* 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 */ 1 + #include <linux/semaphore.h>
-82
include/asm-blackfin/semaphore-helper.h
··· 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 */
+1 -105
include/asm-blackfin/semaphore.h
··· 1 - #ifndef _BFIN_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 */ 1 + #include <linux/semaphore.h>
-78
include/asm-cris/semaphore-helper.h
··· 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 -
+1 -133
include/asm-cris/semaphore.h
··· 1 - /* $Id: semaphore.h,v 1.3 2001/05/08 13:54:09 bjornw Exp $ */ 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 1 + #include <linux/semaphore.h>
+1 -155
include/asm-frv/semaphore.h
··· 1 - /* semaphore.h: semaphores for the FR-V 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 1 + #include <linux/semaphore.h>
-85
include/asm-h8300/semaphore-helper.h
··· 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
+1 -190
include/asm-h8300/semaphore.h
··· 1 - #ifndef _H8300_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 1 + #include <linux/semaphore.h>
+1 -99
include/asm-ia64/semaphore.h
··· 1 - #ifndef _ASM_IA64_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 */ 1 + #include <linux/semaphore.h>
+1 -144
include/asm-m32r/semaphore.h
··· 1 - #ifndef _ASM_M32R_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 */ 1 + #include <linux/semaphore.h>
-142
include/asm-m68k/semaphore-helper.h
··· 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
+1 -163
include/asm-m68k/semaphore.h
··· 1 - #ifndef _M68K_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 1 + #include <linux/semaphore.h>
-82
include/asm-m68knommu/semaphore-helper.h
··· 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
+1 -153
include/asm-m68knommu/semaphore.h
··· 1 - #ifndef _M68K_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 1 + #include <linux/semaphore.h>
+1 -108
include/asm-mips/semaphore.h
··· 1 - /* 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 */ 1 + #include <linux/semaphore.h>
+1 -169
include/asm-mn10300/semaphore.h
··· 1 - /* MN10300 Semaphores 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 1 + #include <linux/semaphore.h>
-89
include/asm-parisc/semaphore-helper.h
··· 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 */
+1 -145
include/asm-parisc/semaphore.h
··· 1 - /* SMP- and interrupt-safe semaphores. 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 */ 1 + #include <linux/semaphore.h>
+1 -94
include/asm-powerpc/semaphore.h
··· 1 - #ifndef _ASM_POWERPC_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 */ 1 + #include <linux/semaphore.h>
+1 -107
include/asm-s390/semaphore.h
··· 1 - /* 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 1 + #include <linux/semaphore.h>
-89
include/asm-sh/semaphore-helper.h
··· 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 */
+1 -115
include/asm-sh/semaphore.h
··· 1 - #ifndef __ASM_SH_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 */ 1 + #include <linux/semaphore.h>
+1 -192
include/asm-sparc/semaphore.h
··· 1 - #ifndef _SPARC_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) */ 1 + #include <linux/semaphore.h>
+1 -53
include/asm-sparc64/semaphore.h
··· 1 - #ifndef _SPARC64_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) */ 1 + #include <linux/semaphore.h>
+1 -6
include/asm-um/semaphore.h
··· 1 - #ifndef __UM_SEMAPHORE_H 2 - #define __UM_SEMAPHORE_H 3 - 4 - #include "asm/arch/semaphore.h" 5 - 6 - #endif 1 + #include <linux/semaphore.h>
+1 -84
include/asm-v850/semaphore.h
··· 1 - #ifndef __V850_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__ */ 1 + #include <linux/semaphore.h>
+1 -5
include/asm-x86/semaphore.h
··· 1 - #ifdef CONFIG_X86_32 2 - # include "semaphore_32.h" 3 - #else 4 - # include "semaphore_64.h" 5 - #endif 1 + #include <linux/semaphore.h>
-175
include/asm-x86/semaphore_32.h
··· 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
-180
include/asm-x86/semaphore_64.h
··· 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
+1 -99
include/asm-xtensa/semaphore.h
··· 1 - /* 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 */ 1 + #include <linux/semaphore.h>
+77
include/linux/semaphore.h
··· 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 + * Counting semaphores allow up to <n> tasks to acquire the semaphore 8 + * simultaneously. 9 + */ 10 + #ifndef __LINUX_SEMAPHORE_H 11 + #define __LINUX_SEMAPHORE_H 12 + 13 + #include <linux/list.h> 14 + #include <linux/spinlock.h> 15 + 16 + /* 17 + * The spinlock controls access to the other members of the semaphore. 18 + * 'count' is decremented by every task which calls down*() and incremented 19 + * by every call to up(). Thus, if it is positive, it indicates how many 20 + * more tasks may acquire the lock. If it is negative, it indicates how 21 + * many tasks are waiting for the lock. Tasks waiting for the lock are 22 + * kept on the wait_list. 23 + */ 24 + struct semaphore { 25 + spinlock_t lock; 26 + int count; 27 + struct list_head wait_list; 28 + }; 29 + 30 + #define __SEMAPHORE_INITIALIZER(name, n) \ 31 + { \ 32 + .lock = __SPIN_LOCK_UNLOCKED((name).lock), \ 33 + .count = n, \ 34 + .wait_list = LIST_HEAD_INIT((name).wait_list), \ 35 + } 36 + 37 + #define __DECLARE_SEMAPHORE_GENERIC(name, count) \ 38 + struct semaphore name = __SEMAPHORE_INITIALIZER(name, count) 39 + 40 + #define DECLARE_MUTEX(name) __DECLARE_SEMAPHORE_GENERIC(name, 1) 41 + 42 + static inline void sema_init(struct semaphore *sem, int val) 43 + { 44 + static struct lock_class_key __key; 45 + *sem = (struct semaphore) __SEMAPHORE_INITIALIZER(*sem, val); 46 + lockdep_init_map(&sem->lock.dep_map, "semaphore->lock", &__key, 0); 47 + } 48 + 49 + #define init_MUTEX(sem) sema_init(sem, 1) 50 + #define init_MUTEX_LOCKED(sem) sema_init(sem, 0) 51 + 52 + /* 53 + * Attempt to acquire the semaphore. If another task is already holding the 54 + * semaphore, sleep until the semaphore is released. 55 + */ 56 + extern void down(struct semaphore *sem); 57 + 58 + /* 59 + * As down(), except the sleep may be interrupted by a signal. If it is, 60 + * this function will return -EINTR. 61 + */ 62 + extern int __must_check down_interruptible(struct semaphore *sem); 63 + 64 + /* 65 + * As down(), except this function will not sleep. It will return 0 if it 66 + * acquired the semaphore and 1 if the semaphore was contended. This 67 + * function may be called from any context, including interrupt and softirq. 68 + */ 69 + extern int __must_check down_trylock(struct semaphore *sem); 70 + 71 + /* 72 + * Release the semaphore. Unlike mutexes, up() may be called from any 73 + * context and even by tasks which have never called down(). 74 + */ 75 + extern void up(struct semaphore *sem); 76 + 77 + #endif /* __LINUX_SEMAPHORE_H */
+1 -1
kernel/Makefile
··· 8 8 signal.o sys.o kmod.o workqueue.o pid.o \ 9 9 rcupdate.o extable.o params.o posix-timers.o \ 10 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 12 notifier.o ksysfs.o pm_qos_params.o 13 13 14 14 obj-$(CONFIG_SYSCTL) += sysctl_check.o
+187
kernel/semaphore.c
··· 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 + 8 + #include <linux/compiler.h> 9 + #include <linux/kernel.h> 10 + #include <linux/module.h> 11 + #include <linux/sched.h> 12 + #include <linux/semaphore.h> 13 + #include <linux/spinlock.h> 14 + 15 + /* 16 + * Some notes on the implementation: 17 + * 18 + * down_trylock() and up() can be called from interrupt context. 19 + * So we have to disable interrupts when taking the lock. 20 + * 21 + * The ->count variable, if positive, defines how many more tasks can 22 + * acquire the semaphore. If negative, it represents how many tasks are 23 + * waiting on the semaphore (*). If zero, no tasks are waiting, and no more 24 + * tasks can acquire the semaphore. 25 + * 26 + * (*) Except for the window between one task calling up() and the task 27 + * sleeping in a __down_common() waking up. In order to avoid a third task 28 + * coming in and stealing the second task's wakeup, we leave the ->count 29 + * negative. If we have a more complex situation, the ->count may become 30 + * zero or negative (eg a semaphore with count = 2, three tasks attempt to 31 + * acquire it, one sleeps, two finish and call up(), the second task to call 32 + * up() notices that the list is empty and just increments count). 33 + */ 34 + 35 + static noinline void __down(struct semaphore *sem); 36 + static noinline int __down_interruptible(struct semaphore *sem); 37 + static noinline void __up(struct semaphore *sem); 38 + 39 + void down(struct semaphore *sem) 40 + { 41 + unsigned long flags; 42 + 43 + spin_lock_irqsave(&sem->lock, flags); 44 + if (unlikely(sem->count-- <= 0)) 45 + __down(sem); 46 + spin_unlock_irqrestore(&sem->lock, flags); 47 + } 48 + EXPORT_SYMBOL(down); 49 + 50 + int down_interruptible(struct semaphore *sem) 51 + { 52 + unsigned long flags; 53 + int result = 0; 54 + 55 + spin_lock_irqsave(&sem->lock, flags); 56 + if (unlikely(sem->count-- <= 0)) 57 + result = __down_interruptible(sem); 58 + spin_unlock_irqrestore(&sem->lock, flags); 59 + 60 + return result; 61 + } 62 + EXPORT_SYMBOL(down_interruptible); 63 + 64 + /** 65 + * down_trylock - try to acquire the semaphore, without waiting 66 + * @sem: the semaphore to be acquired 67 + * 68 + * Try to acquire the semaphore atomically. Returns 0 if the mutex has 69 + * been acquired successfully and 1 if it is contended. 70 + * 71 + * NOTE: This return value is inverted from both spin_trylock and 72 + * mutex_trylock! Be careful about this when converting code. 73 + * 74 + * Unlike mutex_trylock, this function can be used from interrupt context, 75 + * and the semaphore can be released by any task or interrupt. 76 + */ 77 + int down_trylock(struct semaphore *sem) 78 + { 79 + unsigned long flags; 80 + int count; 81 + 82 + spin_lock_irqsave(&sem->lock, flags); 83 + count = sem->count - 1; 84 + if (likely(count >= 0)) 85 + sem->count = count; 86 + spin_unlock_irqrestore(&sem->lock, flags); 87 + 88 + return (count < 0); 89 + } 90 + EXPORT_SYMBOL(down_trylock); 91 + 92 + void up(struct semaphore *sem) 93 + { 94 + unsigned long flags; 95 + 96 + spin_lock_irqsave(&sem->lock, flags); 97 + if (likely(sem->count >= 0)) 98 + sem->count++; 99 + else 100 + __up(sem); 101 + spin_unlock_irqrestore(&sem->lock, flags); 102 + } 103 + EXPORT_SYMBOL(up); 104 + 105 + /* Functions for the contended case */ 106 + 107 + struct semaphore_waiter { 108 + struct list_head list; 109 + struct task_struct *task; 110 + int up; 111 + }; 112 + 113 + /* 114 + * Wake up a process waiting on a semaphore. We need to call this from both 115 + * __up and __down_common as it's possible to race a task into the semaphore 116 + * if it comes in at just the right time between two tasks calling up() and 117 + * a third task waking up. This function assumes the wait_list is already 118 + * checked for being non-empty. 119 + */ 120 + static noinline void __sched __up_down_common(struct semaphore *sem) 121 + { 122 + struct semaphore_waiter *waiter = list_first_entry(&sem->wait_list, 123 + struct semaphore_waiter, list); 124 + list_del(&waiter->list); 125 + waiter->up = 1; 126 + wake_up_process(waiter->task); 127 + } 128 + 129 + /* 130 + * Because this function is inlined, the 'state' parameter will be constant, 131 + * and thus optimised away by the compiler. 132 + */ 133 + static inline int __sched __down_common(struct semaphore *sem, long state) 134 + { 135 + int result = 0; 136 + struct task_struct *task = current; 137 + struct semaphore_waiter waiter; 138 + 139 + list_add_tail(&waiter.list, &sem->wait_list); 140 + waiter.task = task; 141 + waiter.up = 0; 142 + 143 + for (;;) { 144 + if (state == TASK_INTERRUPTIBLE && signal_pending(task)) 145 + goto interrupted; 146 + __set_task_state(task, state); 147 + spin_unlock_irq(&sem->lock); 148 + schedule(); 149 + spin_lock_irq(&sem->lock); 150 + if (waiter.up) 151 + goto woken; 152 + } 153 + 154 + interrupted: 155 + list_del(&waiter.list); 156 + result = -EINTR; 157 + woken: 158 + /* 159 + * Account for the process which woke us up. For the case where 160 + * we're interrupted, we need to increment the count on our own 161 + * behalf. I don't believe we can hit the case where the 162 + * sem->count hits zero, *and* there's a second task sleeping, 163 + * but it doesn't hurt, that's not a commonly exercised path and 164 + * it's not a performance path either. 165 + */ 166 + if (unlikely((++sem->count >= 0) && !list_empty(&sem->wait_list))) 167 + __up_down_common(sem); 168 + return result; 169 + } 170 + 171 + static noinline void __sched __down(struct semaphore *sem) 172 + { 173 + __down_common(sem, TASK_UNINTERRUPTIBLE); 174 + } 175 + 176 + static noinline int __sched __down_interruptible(struct semaphore *sem) 177 + { 178 + return __down_common(sem, TASK_INTERRUPTIBLE); 179 + } 180 + 181 + static noinline void __sched __up(struct semaphore *sem) 182 + { 183 + if (unlikely(list_empty(&sem->wait_list))) 184 + sem->count++; 185 + else 186 + __up_down_common(sem); 187 + }
-1
lib/Makefile
··· 29 29 obj-$(CONFIG_DEBUG_SPINLOCK) += spinlock_debug.o 30 30 lib-$(CONFIG_RWSEM_GENERIC_SPINLOCK) += rwsem-spinlock.o 31 31 lib-$(CONFIG_RWSEM_XCHGADD_ALGORITHM) += rwsem.o 32 - lib-$(CONFIG_SEMAPHORE_SLEEPERS) += semaphore-sleepers.o 33 32 lib-$(CONFIG_GENERIC_FIND_NEXT_BIT) += find_next_bit.o 34 33 obj-$(CONFIG_GENERIC_HWEIGHT) += hweight.o 35 34 obj-$(CONFIG_LOCK_KERNEL) += kernel_lock.o
-176
lib/semaphore-sleepers.c
··· 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 - }