diff options
author | Matthew Wilcox <matthew@wil.cx> | 2008-03-07 21:55:58 -0500 |
---|---|---|
committer | Matthew Wilcox <willy@linux.intel.com> | 2008-04-17 10:42:34 -0400 |
commit | 64ac24e738823161693bf791f87adc802cf529ff (patch) | |
tree | 19c0b0cf314d4394ca580c05b86cdf874ce0a167 /include/asm-xtensa | |
parent | e48b3deee475134585eed03e7afebe4bf9e0dba9 (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-xtensa')
-rw-r--r-- | include/asm-xtensa/semaphore.h | 100 |
1 files changed, 1 insertions, 99 deletions
diff --git a/include/asm-xtensa/semaphore.h b/include/asm-xtensa/semaphore.h index 3e04167cd9dc..d9b2034ed1d2 100644 --- a/include/asm-xtensa/semaphore.h +++ b/include/asm-xtensa/semaphore.h | |||
@@ -1,99 +1 @@ | |||
1 | /* | #include <linux/semaphore.h> | |
2 | * linux/include/asm-xtensa/semaphore.h | ||
3 | * | ||
4 | * This file is subject to the terms and conditions of the GNU General Public | ||
5 | * License. See the file "COPYING" in the main directory of this archive | ||
6 | * for more details. | ||
7 | * | ||
8 | * Copyright (C) 2001 - 2005 Tensilica Inc. | ||
9 | */ | ||
10 | |||
11 | #ifndef _XTENSA_SEMAPHORE_H | ||
12 | #define _XTENSA_SEMAPHORE_H | ||
13 | |||
14 | #include <asm/atomic.h> | ||
15 | #include <asm/system.h> | ||
16 | #include <linux/wait.h> | ||
17 | #include <linux/rwsem.h> | ||
18 | |||
19 | struct semaphore { | ||
20 | atomic_t count; | ||
21 | int sleepers; | ||
22 | wait_queue_head_t wait; | ||
23 | }; | ||
24 | |||
25 | #define __SEMAPHORE_INITIALIZER(name,n) \ | ||
26 | { \ | ||
27 | .count = ATOMIC_INIT(n), \ | ||
28 | .sleepers = 0, \ | ||
29 | .wait = __WAIT_QUEUE_HEAD_INITIALIZER((name).wait) \ | ||
30 | } | ||
31 | |||
32 | #define __DECLARE_SEMAPHORE_GENERIC(name,count) \ | ||
33 | struct semaphore name = __SEMAPHORE_INITIALIZER(name,count) | ||
34 | |||
35 | #define DECLARE_MUTEX(name) __DECLARE_SEMAPHORE_GENERIC(name,1) | ||
36 | |||
37 | static inline void sema_init (struct semaphore *sem, int val) | ||
38 | { | ||
39 | atomic_set(&sem->count, val); | ||
40 | sem->sleepers = 0; | ||
41 | init_waitqueue_head(&sem->wait); | ||
42 | } | ||
43 | |||
44 | static inline void init_MUTEX (struct semaphore *sem) | ||
45 | { | ||
46 | sema_init(sem, 1); | ||
47 | } | ||
48 | |||
49 | static inline void init_MUTEX_LOCKED (struct semaphore *sem) | ||
50 | { | ||
51 | sema_init(sem, 0); | ||
52 | } | ||
53 | |||
54 | asmlinkage void __down(struct semaphore * sem); | ||
55 | asmlinkage int __down_interruptible(struct semaphore * sem); | ||
56 | asmlinkage int __down_trylock(struct semaphore * sem); | ||
57 | asmlinkage void __up(struct semaphore * sem); | ||
58 | |||
59 | extern spinlock_t semaphore_wake_lock; | ||
60 | |||
61 | static inline void down(struct semaphore * sem) | ||
62 | { | ||
63 | might_sleep(); | ||
64 | |||
65 | if (atomic_sub_return(1, &sem->count) < 0) | ||
66 | __down(sem); | ||
67 | } | ||
68 | |||
69 | static inline int down_interruptible(struct semaphore * sem) | ||
70 | { | ||
71 | int ret = 0; | ||
72 | |||
73 | might_sleep(); | ||
74 | |||
75 | if (atomic_sub_return(1, &sem->count) < 0) | ||
76 | ret = __down_interruptible(sem); | ||
77 | return ret; | ||
78 | } | ||
79 | |||
80 | static inline int down_trylock(struct semaphore * sem) | ||
81 | { | ||
82 | int ret = 0; | ||
83 | |||
84 | if (atomic_sub_return(1, &sem->count) < 0) | ||
85 | ret = __down_trylock(sem); | ||
86 | return ret; | ||
87 | } | ||
88 | |||
89 | /* | ||
90 | * Note! This is subtle. We jump to wake people up only if | ||
91 | * the semaphore was negative (== somebody was waiting on it). | ||
92 | */ | ||
93 | static inline void up(struct semaphore * sem) | ||
94 | { | ||
95 | if (atomic_add_return(1, &sem->count) <= 0) | ||
96 | __up(sem); | ||
97 | } | ||
98 | |||
99 | #endif /* _XTENSA_SEMAPHORE_H */ | ||