aboutsummaryrefslogtreecommitdiffstats
path: root/include/asm-blackfin/semaphore.h
diff options
context:
space:
mode:
authorMatthew Wilcox <matthew@wil.cx>2008-03-07 21:55:58 -0500
committerMatthew Wilcox <willy@linux.intel.com>2008-04-17 10:42:34 -0400
commit64ac24e738823161693bf791f87adc802cf529ff (patch)
tree19c0b0cf314d4394ca580c05b86cdf874ce0a167 /include/asm-blackfin/semaphore.h
parente48b3deee475134585eed03e7afebe4bf9e0dba9 (diff)
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>
Diffstat (limited to 'include/asm-blackfin/semaphore.h')
-rw-r--r--include/asm-blackfin/semaphore.h106
1 files changed, 1 insertions, 105 deletions
diff --git a/include/asm-blackfin/semaphore.h b/include/asm-blackfin/semaphore.h
index 533f90fb2e4e..d9b2034ed1d2 100644
--- a/include/asm-blackfin/semaphore.h
+++ b/include/asm-blackfin/semaphore.h
@@ -1,105 +1 @@
1#ifndef _BFIN_SEMAPHORE_H #include <linux/semaphore.h>
2#define _BFIN_SEMAPHORE_H
3
4#ifndef __ASSEMBLY__
5
6#include <linux/linkage.h>
7#include <linux/wait.h>
8#include <linux/spinlock.h>
9#include <linux/rwsem.h>
10#include <asm/atomic.h>
11
12/*
13 * Interrupt-safe semaphores..
14 *
15 * (C) Copyright 1996 Linus Torvalds
16 *
17 * BFIN version by akbar hussain Lineo Inc April 2001
18 *
19 */
20
21struct 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
39static inline void sema_init(struct semaphore *sem, int val)
40{
41 *sem = (struct semaphore)__SEMAPHORE_INITIALIZER(*sem, val);
42}
43
44static inline void init_MUTEX(struct semaphore *sem)
45{
46 sema_init(sem, 1);
47}
48
49static inline void init_MUTEX_LOCKED(struct semaphore *sem)
50{
51 sema_init(sem, 0);
52}
53
54asmlinkage void __down(struct semaphore *sem);
55asmlinkage int __down_interruptible(struct semaphore *sem);
56asmlinkage int __down_trylock(struct semaphore *sem);
57asmlinkage void __up(struct semaphore *sem);
58
59extern 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 */
66static inline void down(struct semaphore *sem)
67{
68 might_sleep();
69 if (atomic_dec_return(&sem->count) < 0)
70 __down(sem);
71}
72
73static 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
83static 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 */
98static 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 */