diff options
Diffstat (limited to 'include')
34 files changed, 100 insertions, 3760 deletions
diff --git a/include/asm-alpha/semaphore.h b/include/asm-alpha/semaphore.h index f1e9278a9fe2..d9b2034ed1d2 100644 --- a/include/asm-alpha/semaphore.h +++ b/include/asm-alpha/semaphore.h | |||
@@ -1,149 +1 @@ | |||
1 | #ifndef _ALPHA_SEMAPHORE_H | #include <linux/semaphore.h> | |
2 | #define _ALPHA_SEMAPHORE_H | ||
3 | |||
4 | /* | ||
5 | * SMP- and interrupt-safe semaphores.. | ||
6 | * | ||
7 | * (C) Copyright 1996 Linus Torvalds | ||
8 | * (C) Copyright 1996, 2000 Richard Henderson | ||
9 | */ | ||
10 | |||
11 | #include <asm/current.h> | ||
12 | #include <asm/system.h> | ||
13 | #include <asm/atomic.h> | ||
14 | #include <linux/compiler.h> | ||
15 | #include <linux/wait.h> | ||
16 | #include <linux/rwsem.h> | ||
17 | |||
18 | struct semaphore { | ||
19 | atomic_t count; | ||
20 | wait_queue_head_t wait; | ||
21 | }; | ||
22 | |||
23 | #define __SEMAPHORE_INITIALIZER(name, n) \ | ||
24 | { \ | ||
25 | .count = ATOMIC_INIT(n), \ | ||
26 | .wait = __WAIT_QUEUE_HEAD_INITIALIZER((name).wait), \ | ||
27 | } | ||
28 | |||
29 | #define __DECLARE_SEMAPHORE_GENERIC(name,count) \ | ||
30 | struct semaphore name = __SEMAPHORE_INITIALIZER(name,count) | ||
31 | |||
32 | #define DECLARE_MUTEX(name) __DECLARE_SEMAPHORE_GENERIC(name,1) | ||
33 | |||
34 | static inline void sema_init(struct semaphore *sem, int val) | ||
35 | { | ||
36 | /* | ||
37 | * Logically, | ||
38 | * *sem = (struct semaphore)__SEMAPHORE_INITIALIZER((*sem),val); | ||
39 | * except that gcc produces better initializing by parts yet. | ||
40 | */ | ||
41 | |||
42 | atomic_set(&sem->count, val); | ||
43 | init_waitqueue_head(&sem->wait); | ||
44 | } | ||
45 | |||
46 | static inline void init_MUTEX (struct semaphore *sem) | ||
47 | { | ||
48 | sema_init(sem, 1); | ||
49 | } | ||
50 | |||
51 | static inline void init_MUTEX_LOCKED (struct semaphore *sem) | ||
52 | { | ||
53 | sema_init(sem, 0); | ||
54 | } | ||
55 | |||
56 | extern void down(struct semaphore *); | ||
57 | extern void __down_failed(struct semaphore *); | ||
58 | extern int down_interruptible(struct semaphore *); | ||
59 | extern int __down_failed_interruptible(struct semaphore *); | ||
60 | extern int down_trylock(struct semaphore *); | ||
61 | extern void up(struct semaphore *); | ||
62 | extern void __up_wakeup(struct semaphore *); | ||
63 | |||
64 | /* | ||
65 | * Hidden out of line code is fun, but extremely messy. Rely on newer | ||
66 | * compilers to do a respectable job with this. The contention cases | ||
67 | * are handled out of line in arch/alpha/kernel/semaphore.c. | ||
68 | */ | ||
69 | |||
70 | static inline void __down(struct semaphore *sem) | ||
71 | { | ||
72 | long count; | ||
73 | might_sleep(); | ||
74 | count = atomic_dec_return(&sem->count); | ||
75 | if (unlikely(count < 0)) | ||
76 | __down_failed(sem); | ||
77 | } | ||
78 | |||
79 | static inline int __down_interruptible(struct semaphore *sem) | ||
80 | { | ||
81 | long count; | ||
82 | might_sleep(); | ||
83 | count = atomic_dec_return(&sem->count); | ||
84 | if (unlikely(count < 0)) | ||
85 | return __down_failed_interruptible(sem); | ||
86 | return 0; | ||
87 | } | ||
88 | |||
89 | /* | ||
90 | * down_trylock returns 0 on success, 1 if we failed to get the lock. | ||
91 | */ | ||
92 | |||
93 | static inline int __down_trylock(struct semaphore *sem) | ||
94 | { | ||
95 | long ret; | ||
96 | |||
97 | /* "Equivalent" C: | ||
98 | |||
99 | do { | ||
100 | ret = ldl_l; | ||
101 | --ret; | ||
102 | if (ret < 0) | ||
103 | break; | ||
104 | ret = stl_c = ret; | ||
105 | } while (ret == 0); | ||
106 | */ | ||
107 | __asm__ __volatile__( | ||
108 | "1: ldl_l %0,%1\n" | ||
109 | " subl %0,1,%0\n" | ||
110 | " blt %0,2f\n" | ||
111 | " stl_c %0,%1\n" | ||
112 | " beq %0,3f\n" | ||
113 | " mb\n" | ||
114 | "2:\n" | ||
115 | ".subsection 2\n" | ||
116 | "3: br 1b\n" | ||
117 | ".previous" | ||
118 | : "=&r" (ret), "=m" (sem->count) | ||
119 | : "m" (sem->count)); | ||
120 | |||
121 | return ret < 0; | ||
122 | } | ||
123 | |||
124 | static inline void __up(struct semaphore *sem) | ||
125 | { | ||
126 | if (unlikely(atomic_inc_return(&sem->count) <= 0)) | ||
127 | __up_wakeup(sem); | ||
128 | } | ||
129 | |||
130 | #if !defined(CONFIG_DEBUG_SEMAPHORE) | ||
131 | extern inline void down(struct semaphore *sem) | ||
132 | { | ||
133 | __down(sem); | ||
134 | } | ||
135 | extern inline int down_interruptible(struct semaphore *sem) | ||
136 | { | ||
137 | return __down_interruptible(sem); | ||
138 | } | ||
139 | extern inline int down_trylock(struct semaphore *sem) | ||
140 | { | ||
141 | return __down_trylock(sem); | ||
142 | } | ||
143 | extern inline void up(struct semaphore *sem) | ||
144 | { | ||
145 | __up(sem); | ||
146 | } | ||
147 | #endif | ||
148 | |||
149 | #endif | ||
diff --git a/include/asm-arm/semaphore-helper.h b/include/asm-arm/semaphore-helper.h deleted file mode 100644 index 1d7f1987edb9..000000000000 --- a/include/asm-arm/semaphore-helper.h +++ /dev/null | |||
@@ -1,84 +0,0 @@ | |||
1 | #ifndef ASMARM_SEMAPHORE_HELPER_H | ||
2 | #define ASMARM_SEMAPHORE_HELPER_H | ||
3 | |||
4 | /* | ||
5 | * These two _must_ execute atomically wrt each other. | ||
6 | */ | ||
7 | static inline void wake_one_more(struct semaphore * sem) | ||
8 | { | ||
9 | unsigned long flags; | ||
10 | |||
11 | spin_lock_irqsave(&semaphore_wake_lock, flags); | ||
12 | if (atomic_read(&sem->count) <= 0) | ||
13 | sem->waking++; | ||
14 | spin_unlock_irqrestore(&semaphore_wake_lock, flags); | ||
15 | } | ||
16 | |||
17 | static inline int waking_non_zero(struct semaphore *sem) | ||
18 | { | ||
19 | unsigned long flags; | ||
20 | int ret = 0; | ||
21 | |||
22 | spin_lock_irqsave(&semaphore_wake_lock, flags); | ||
23 | if (sem->waking > 0) { | ||
24 | sem->waking--; | ||
25 | ret = 1; | ||
26 | } | ||
27 | spin_unlock_irqrestore(&semaphore_wake_lock, flags); | ||
28 | return ret; | ||
29 | } | ||
30 | |||
31 | /* | ||
32 | * waking non zero interruptible | ||
33 | * 1 got the lock | ||
34 | * 0 go to sleep | ||
35 | * -EINTR interrupted | ||
36 | * | ||
37 | * We must undo the sem->count down_interruptible() increment while we are | ||
38 | * protected by the spinlock in order to make this atomic_inc() with the | ||
39 | * atomic_read() in wake_one_more(), otherwise we can race. -arca | ||
40 | */ | ||
41 | static inline int waking_non_zero_interruptible(struct semaphore *sem, | ||
42 | struct task_struct *tsk) | ||
43 | { | ||
44 | unsigned long flags; | ||
45 | int ret = 0; | ||
46 | |||
47 | spin_lock_irqsave(&semaphore_wake_lock, flags); | ||
48 | if (sem->waking > 0) { | ||
49 | sem->waking--; | ||
50 | ret = 1; | ||
51 | } else if (signal_pending(tsk)) { | ||
52 | atomic_inc(&sem->count); | ||
53 | ret = -EINTR; | ||
54 | } | ||
55 | spin_unlock_irqrestore(&semaphore_wake_lock, flags); | ||
56 | return ret; | ||
57 | } | ||
58 | |||
59 | /* | ||
60 | * waking_non_zero_try_lock: | ||
61 | * 1 failed to lock | ||
62 | * 0 got the lock | ||
63 | * | ||
64 | * We must undo the sem->count down_interruptible() increment while we are | ||
65 | * protected by the spinlock in order to make this atomic_inc() with the | ||
66 | * atomic_read() in wake_one_more(), otherwise we can race. -arca | ||
67 | */ | ||
68 | static inline int waking_non_zero_trylock(struct semaphore *sem) | ||
69 | { | ||
70 | unsigned long flags; | ||
71 | int ret = 1; | ||
72 | |||
73 | spin_lock_irqsave(&semaphore_wake_lock, flags); | ||
74 | if (sem->waking <= 0) | ||
75 | atomic_inc(&sem->count); | ||
76 | else { | ||
77 | sem->waking--; | ||
78 | ret = 0; | ||
79 | } | ||
80 | spin_unlock_irqrestore(&semaphore_wake_lock, flags); | ||
81 | return ret; | ||
82 | } | ||
83 | |||
84 | #endif | ||
diff --git a/include/asm-arm/semaphore.h b/include/asm-arm/semaphore.h index 1c8b441f89e3..d9b2034ed1d2 100644 --- a/include/asm-arm/semaphore.h +++ b/include/asm-arm/semaphore.h | |||
@@ -1,98 +1 @@ | |||
1 | /* | #include <linux/semaphore.h> | |
2 | * linux/include/asm-arm/semaphore.h | ||
3 | */ | ||
4 | #ifndef __ASM_ARM_SEMAPHORE_H | ||
5 | #define __ASM_ARM_SEMAPHORE_H | ||
6 | |||
7 | #include <linux/linkage.h> | ||
8 | #include <linux/spinlock.h> | ||
9 | #include <linux/wait.h> | ||
10 | #include <linux/rwsem.h> | ||
11 | |||
12 | #include <asm/atomic.h> | ||
13 | #include <asm/locks.h> | ||
14 | |||
15 | struct semaphore { | ||
16 | atomic_t count; | ||
17 | int sleepers; | ||
18 | wait_queue_head_t wait; | ||
19 | }; | ||
20 | |||
21 | #define __SEMAPHORE_INIT(name, cnt) \ | ||
22 | { \ | ||
23 | .count = ATOMIC_INIT(cnt), \ | ||
24 | .wait = __WAIT_QUEUE_HEAD_INITIALIZER((name).wait), \ | ||
25 | } | ||
26 | |||
27 | #define __DECLARE_SEMAPHORE_GENERIC(name,count) \ | ||
28 | struct semaphore name = __SEMAPHORE_INIT(name,count) | ||
29 | |||
30 | #define DECLARE_MUTEX(name) __DECLARE_SEMAPHORE_GENERIC(name,1) | ||
31 | |||
32 | static inline void sema_init(struct semaphore *sem, int val) | ||
33 | { | ||
34 | atomic_set(&sem->count, val); | ||
35 | sem->sleepers = 0; | ||
36 | init_waitqueue_head(&sem->wait); | ||
37 | } | ||
38 | |||
39 | static inline void init_MUTEX(struct semaphore *sem) | ||
40 | { | ||
41 | sema_init(sem, 1); | ||
42 | } | ||
43 | |||
44 | static inline void init_MUTEX_LOCKED(struct semaphore *sem) | ||
45 | { | ||
46 | sema_init(sem, 0); | ||
47 | } | ||
48 | |||
49 | /* | ||
50 | * special register calling convention | ||
51 | */ | ||
52 | asmlinkage void __down_failed(void); | ||
53 | asmlinkage int __down_interruptible_failed(void); | ||
54 | asmlinkage int __down_trylock_failed(void); | ||
55 | asmlinkage void __up_wakeup(void); | ||
56 | |||
57 | extern void __down(struct semaphore * sem); | ||
58 | extern int __down_interruptible(struct semaphore * sem); | ||
59 | extern int __down_trylock(struct semaphore * sem); | ||
60 | extern void __up(struct semaphore * sem); | ||
61 | |||
62 | /* | ||
63 | * This is ugly, but we want the default case to fall through. | ||
64 | * "__down" is the actual routine that waits... | ||
65 | */ | ||
66 | static inline void down(struct semaphore * sem) | ||
67 | { | ||
68 | might_sleep(); | ||
69 | __down_op(sem, __down_failed); | ||
70 | } | ||
71 | |||
72 | /* | ||
73 | * This is ugly, but we want the default case to fall through. | ||
74 | * "__down_interruptible" is the actual routine that waits... | ||
75 | */ | ||
76 | static inline int down_interruptible (struct semaphore * sem) | ||
77 | { | ||
78 | might_sleep(); | ||
79 | return __down_op_ret(sem, __down_interruptible_failed); | ||
80 | } | ||
81 | |||
82 | static inline int down_trylock(struct semaphore *sem) | ||
83 | { | ||
84 | return __down_op_ret(sem, __down_trylock_failed); | ||
85 | } | ||
86 | |||
87 | /* | ||
88 | * Note! This is subtle. We jump to wake people up only if | ||
89 | * the semaphore was negative (== somebody was waiting on it). | ||
90 | * The default case (no contention) will result in NO | ||
91 | * jumps for both down() and up(). | ||
92 | */ | ||
93 | static inline void up(struct semaphore * sem) | ||
94 | { | ||
95 | __up_op(sem, __up_wakeup); | ||
96 | } | ||
97 | |||
98 | #endif | ||
diff --git a/include/asm-avr32/semaphore.h b/include/asm-avr32/semaphore.h index feaf1d453386..d9b2034ed1d2 100644 --- a/include/asm-avr32/semaphore.h +++ b/include/asm-avr32/semaphore.h | |||
@@ -1,108 +1 @@ | |||
1 | /* | #include <linux/semaphore.h> | |
2 | * SMP- and interrupt-safe semaphores. | ||
3 | * | ||
4 | * Copyright (C) 2006 Atmel Corporation | ||
5 | * | ||
6 | * Based on include/asm-i386/semaphore.h | ||
7 | * Copyright (C) 1996 Linus Torvalds | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify | ||
10 | * it under the terms of the GNU General Public License version 2 as | ||
11 | * published by the Free Software Foundation. | ||
12 | */ | ||
13 | #ifndef __ASM_AVR32_SEMAPHORE_H | ||
14 | #define __ASM_AVR32_SEMAPHORE_H | ||
15 | |||
16 | #include <linux/linkage.h> | ||
17 | |||
18 | #include <asm/system.h> | ||
19 | #include <asm/atomic.h> | ||
20 | #include <linux/wait.h> | ||
21 | #include <linux/rwsem.h> | ||
22 | |||
23 | struct semaphore { | ||
24 | atomic_t count; | ||
25 | int sleepers; | ||
26 | wait_queue_head_t wait; | ||
27 | }; | ||
28 | |||
29 | #define __SEMAPHORE_INITIALIZER(name, n) \ | ||
30 | { \ | ||
31 | .count = ATOMIC_INIT(n), \ | ||
32 | .wait = __WAIT_QUEUE_HEAD_INITIALIZER((name).wait) \ | ||
33 | } | ||
34 | |||
35 | #define __DECLARE_SEMAPHORE_GENERIC(name,count) \ | ||
36 | struct semaphore name = __SEMAPHORE_INITIALIZER(name,count) | ||
37 | |||
38 | #define DECLARE_MUTEX(name) __DECLARE_SEMAPHORE_GENERIC(name,1) | ||
39 | |||
40 | static inline void sema_init (struct semaphore *sem, int val) | ||
41 | { | ||
42 | atomic_set(&sem->count, val); | ||
43 | sem->sleepers = 0; | ||
44 | init_waitqueue_head(&sem->wait); | ||
45 | } | ||
46 | |||
47 | static inline void init_MUTEX (struct semaphore *sem) | ||
48 | { | ||
49 | sema_init(sem, 1); | ||
50 | } | ||
51 | |||
52 | static inline void init_MUTEX_LOCKED (struct semaphore *sem) | ||
53 | { | ||
54 | sema_init(sem, 0); | ||
55 | } | ||
56 | |||
57 | void __down(struct semaphore * sem); | ||
58 | int __down_interruptible(struct semaphore * sem); | ||
59 | void __up(struct semaphore * sem); | ||
60 | |||
61 | /* | ||
62 | * This is ugly, but we want the default case to fall through. | ||
63 | * "__down_failed" is a special asm handler that calls the C | ||
64 | * routine that actually waits. See arch/i386/kernel/semaphore.c | ||
65 | */ | ||
66 | static inline void down(struct semaphore * sem) | ||
67 | { | ||
68 | might_sleep(); | ||
69 | if (unlikely(atomic_dec_return (&sem->count) < 0)) | ||
70 | __down (sem); | ||
71 | } | ||
72 | |||
73 | /* | ||
74 | * Interruptible try to acquire a semaphore. If we obtained | ||
75 | * it, return zero. If we were interrupted, returns -EINTR | ||
76 | */ | ||
77 | static inline int down_interruptible(struct semaphore * sem) | ||
78 | { | ||
79 | int ret = 0; | ||
80 | |||
81 | might_sleep(); | ||
82 | if (unlikely(atomic_dec_return (&sem->count) < 0)) | ||
83 | ret = __down_interruptible (sem); | ||
84 | return ret; | ||
85 | } | ||
86 | |||
87 | /* | ||
88 | * Non-blockingly attempt to down() a semaphore. | ||
89 | * Returns zero if we acquired it | ||
90 | */ | ||
91 | static inline int down_trylock(struct semaphore * sem) | ||
92 | { | ||
93 | return atomic_dec_if_positive(&sem->count) < 0; | ||
94 | } | ||
95 | |||
96 | /* | ||
97 | * Note! This is subtle. We jump to wake people up only if | ||
98 | * the semaphore was negative (== somebody was waiting on it). | ||
99 | * The default case (no contention) will result in NO | ||
100 | * jumps for both down() and up(). | ||
101 | */ | ||
102 | static inline void up(struct semaphore * sem) | ||
103 | { | ||
104 | if (unlikely(atomic_inc_return (&sem->count) <= 0)) | ||
105 | __up (sem); | ||
106 | } | ||
107 | |||
108 | #endif /*__ASM_AVR32_SEMAPHORE_H */ | ||
diff --git a/include/asm-blackfin/semaphore-helper.h b/include/asm-blackfin/semaphore-helper.h deleted file mode 100644 index 9082b0dc3eb5..000000000000 --- a/include/asm-blackfin/semaphore-helper.h +++ /dev/null | |||
@@ -1,82 +0,0 @@ | |||
1 | /* Based on M68K version, Lineo Inc. May 2001 */ | ||
2 | |||
3 | #ifndef _BFIN_SEMAPHORE_HELPER_H | ||
4 | #define _BFIN_SEMAPHORE_HELPER_H | ||
5 | |||
6 | /* | ||
7 | * SMP- and interrupt-safe semaphores helper functions. | ||
8 | * | ||
9 | * (C) Copyright 1996 Linus Torvalds | ||
10 | * | ||
11 | */ | ||
12 | |||
13 | #include <asm/errno.h> | ||
14 | |||
15 | /* | ||
16 | * These two _must_ execute atomically wrt each other. | ||
17 | */ | ||
18 | static inline void wake_one_more(struct semaphore *sem) | ||
19 | { | ||
20 | atomic_inc(&sem->waking); | ||
21 | } | ||
22 | |||
23 | static inline int waking_non_zero(struct semaphore *sem) | ||
24 | { | ||
25 | int ret; | ||
26 | unsigned long flags = 0; | ||
27 | |||
28 | spin_lock_irqsave(&semaphore_wake_lock, flags); | ||
29 | ret = 0; | ||
30 | if (atomic_read(&sem->waking) > 0) { | ||
31 | atomic_dec(&sem->waking); | ||
32 | ret = 1; | ||
33 | } | ||
34 | spin_unlock_irqrestore(&semaphore_wake_lock, flags); | ||
35 | return ret; | ||
36 | } | ||
37 | |||
38 | /* | ||
39 | * waking_non_zero_interruptible: | ||
40 | * 1 got the lock | ||
41 | * 0 go to sleep | ||
42 | * -EINTR interrupted | ||
43 | */ | ||
44 | static inline int waking_non_zero_interruptible(struct semaphore *sem, | ||
45 | struct task_struct *tsk) | ||
46 | { | ||
47 | int ret = 0; | ||
48 | unsigned long flags = 0; | ||
49 | |||
50 | spin_lock_irqsave(&semaphore_wake_lock, flags); | ||
51 | if (atomic_read(&sem->waking) > 0) { | ||
52 | atomic_dec(&sem->waking); | ||
53 | ret = 1; | ||
54 | } else if (signal_pending(tsk)) { | ||
55 | atomic_inc(&sem->count); | ||
56 | ret = -EINTR; | ||
57 | } | ||
58 | spin_unlock_irqrestore(&semaphore_wake_lock, flags); | ||
59 | return ret; | ||
60 | } | ||
61 | |||
62 | /* | ||
63 | * waking_non_zero_trylock: | ||
64 | * 1 failed to lock | ||
65 | * 0 got the lock | ||
66 | */ | ||
67 | static inline int waking_non_zero_trylock(struct semaphore *sem) | ||
68 | { | ||
69 | int ret = 1; | ||
70 | unsigned long flags = 0; | ||
71 | |||
72 | spin_lock_irqsave(&semaphore_wake_lock, flags); | ||
73 | if (atomic_read(&sem->waking) > 0) { | ||
74 | atomic_dec(&sem->waking); | ||
75 | ret = 0; | ||
76 | } else | ||
77 | atomic_inc(&sem->count); | ||
78 | spin_unlock_irqrestore(&semaphore_wake_lock, flags); | ||
79 | return ret; | ||
80 | } | ||
81 | |||
82 | #endif /* _BFIN_SEMAPHORE_HELPER_H */ | ||
diff --git a/include/asm-blackfin/semaphore.h b/include/asm-blackfin/semaphore.h index 533f90fb2e4e..d9b2034ed1d2 100644 --- a/include/asm-blackfin/semaphore.h +++ b/include/asm-blackfin/semaphore.h | |||
@@ -1,105 +1 @@ | |||
1 | #ifndef _BFIN_SEMAPHORE_H | #include <linux/semaphore.h> | |
2 | #define _BFIN_SEMAPHORE_H | ||
3 | |||
4 | #ifndef __ASSEMBLY__ | ||
5 | |||
6 | #include <linux/linkage.h> | ||
7 | #include <linux/wait.h> | ||
8 | #include <linux/spinlock.h> | ||
9 | #include <linux/rwsem.h> | ||
10 | #include <asm/atomic.h> | ||
11 | |||
12 | /* | ||
13 | * Interrupt-safe semaphores.. | ||
14 | * | ||
15 | * (C) Copyright 1996 Linus Torvalds | ||
16 | * | ||
17 | * BFIN version by akbar hussain Lineo Inc April 2001 | ||
18 | * | ||
19 | */ | ||
20 | |||
21 | struct semaphore { | ||
22 | atomic_t count; | ||
23 | int sleepers; | ||
24 | wait_queue_head_t wait; | ||
25 | }; | ||
26 | |||
27 | #define __SEMAPHORE_INITIALIZER(name, n) \ | ||
28 | { \ | ||
29 | .count = ATOMIC_INIT(n), \ | ||
30 | .sleepers = 0, \ | ||
31 | .wait = __WAIT_QUEUE_HEAD_INITIALIZER((name).wait) \ | ||
32 | } | ||
33 | |||
34 | #define __DECLARE_SEMAPHORE_GENERIC(name,count) \ | ||
35 | struct semaphore name = __SEMAPHORE_INITIALIZER(name,count) | ||
36 | |||
37 | #define DECLARE_MUTEX(name) __DECLARE_SEMAPHORE_GENERIC(name,1) | ||
38 | |||
39 | static inline void sema_init(struct semaphore *sem, int val) | ||
40 | { | ||
41 | *sem = (struct semaphore)__SEMAPHORE_INITIALIZER(*sem, val); | ||
42 | } | ||
43 | |||
44 | static inline void init_MUTEX(struct semaphore *sem) | ||
45 | { | ||
46 | sema_init(sem, 1); | ||
47 | } | ||
48 | |||
49 | static inline void init_MUTEX_LOCKED(struct semaphore *sem) | ||
50 | { | ||
51 | sema_init(sem, 0); | ||
52 | } | ||
53 | |||
54 | asmlinkage void __down(struct semaphore *sem); | ||
55 | asmlinkage int __down_interruptible(struct semaphore *sem); | ||
56 | asmlinkage int __down_trylock(struct semaphore *sem); | ||
57 | asmlinkage void __up(struct semaphore *sem); | ||
58 | |||
59 | extern spinlock_t semaphore_wake_lock; | ||
60 | |||
61 | /* | ||
62 | * This is ugly, but we want the default case to fall through. | ||
63 | * "down_failed" is a special asm handler that calls the C | ||
64 | * routine that actually waits. | ||
65 | */ | ||
66 | static inline void down(struct semaphore *sem) | ||
67 | { | ||
68 | might_sleep(); | ||
69 | if (atomic_dec_return(&sem->count) < 0) | ||
70 | __down(sem); | ||
71 | } | ||
72 | |||
73 | static inline int down_interruptible(struct semaphore *sem) | ||
74 | { | ||
75 | int ret = 0; | ||
76 | |||
77 | might_sleep(); | ||
78 | if (atomic_dec_return(&sem->count) < 0) | ||
79 | ret = __down_interruptible(sem); | ||
80 | return (ret); | ||
81 | } | ||
82 | |||
83 | static inline int down_trylock(struct semaphore *sem) | ||
84 | { | ||
85 | int ret = 0; | ||
86 | |||
87 | if (atomic_dec_return(&sem->count) < 0) | ||
88 | ret = __down_trylock(sem); | ||
89 | return ret; | ||
90 | } | ||
91 | |||
92 | /* | ||
93 | * Note! This is subtle. We jump to wake people up only if | ||
94 | * the semaphore was negative (== somebody was waiting on it). | ||
95 | * The default case (no contention) will result in NO | ||
96 | * jumps for both down() and up(). | ||
97 | */ | ||
98 | static inline void up(struct semaphore *sem) | ||
99 | { | ||
100 | if (atomic_inc_return(&sem->count) <= 0) | ||
101 | __up(sem); | ||
102 | } | ||
103 | |||
104 | #endif /* __ASSEMBLY__ */ | ||
105 | #endif /* _BFIN_SEMAPHORE_H */ | ||
diff --git a/include/asm-cris/semaphore-helper.h b/include/asm-cris/semaphore-helper.h deleted file mode 100644 index 27bfeca1b981..000000000000 --- a/include/asm-cris/semaphore-helper.h +++ /dev/null | |||
@@ -1,78 +0,0 @@ | |||
1 | /* $Id: semaphore-helper.h,v 1.3 2001/03/26 15:00:33 orjanf Exp $ | ||
2 | * | ||
3 | * SMP- and interrupt-safe semaphores helper functions. Generic versions, no | ||
4 | * optimizations whatsoever... | ||
5 | * | ||
6 | */ | ||
7 | |||
8 | #ifndef _ASM_SEMAPHORE_HELPER_H | ||
9 | #define _ASM_SEMAPHORE_HELPER_H | ||
10 | |||
11 | #include <asm/atomic.h> | ||
12 | #include <linux/errno.h> | ||
13 | |||
14 | #define read(a) ((a)->counter) | ||
15 | #define inc(a) (((a)->counter)++) | ||
16 | #define dec(a) (((a)->counter)--) | ||
17 | |||
18 | #define count_inc(a) ((*(a))++) | ||
19 | |||
20 | /* | ||
21 | * These two _must_ execute atomically wrt each other. | ||
22 | */ | ||
23 | static inline void wake_one_more(struct semaphore * sem) | ||
24 | { | ||
25 | atomic_inc(&sem->waking); | ||
26 | } | ||
27 | |||
28 | static inline int waking_non_zero(struct semaphore *sem) | ||
29 | { | ||
30 | unsigned long flags; | ||
31 | int ret = 0; | ||
32 | |||
33 | local_irq_save(flags); | ||
34 | if (read(&sem->waking) > 0) { | ||
35 | dec(&sem->waking); | ||
36 | ret = 1; | ||
37 | } | ||
38 | local_irq_restore(flags); | ||
39 | return ret; | ||
40 | } | ||
41 | |||
42 | static inline int waking_non_zero_interruptible(struct semaphore *sem, | ||
43 | struct task_struct *tsk) | ||
44 | { | ||
45 | int ret = 0; | ||
46 | unsigned long flags; | ||
47 | |||
48 | local_irq_save(flags); | ||
49 | if (read(&sem->waking) > 0) { | ||
50 | dec(&sem->waking); | ||
51 | ret = 1; | ||
52 | } else if (signal_pending(tsk)) { | ||
53 | inc(&sem->count); | ||
54 | ret = -EINTR; | ||
55 | } | ||
56 | local_irq_restore(flags); | ||
57 | return ret; | ||
58 | } | ||
59 | |||
60 | static inline int waking_non_zero_trylock(struct semaphore *sem) | ||
61 | { | ||
62 | int ret = 1; | ||
63 | unsigned long flags; | ||
64 | |||
65 | local_irq_save(flags); | ||
66 | if (read(&sem->waking) <= 0) | ||
67 | inc(&sem->count); | ||
68 | else { | ||
69 | dec(&sem->waking); | ||
70 | ret = 0; | ||
71 | } | ||
72 | local_irq_restore(flags); | ||
73 | return ret; | ||
74 | } | ||
75 | |||
76 | #endif /* _ASM_SEMAPHORE_HELPER_H */ | ||
77 | |||
78 | |||
diff --git a/include/asm-cris/semaphore.h b/include/asm-cris/semaphore.h index 31a4ac448195..d9b2034ed1d2 100644 --- a/include/asm-cris/semaphore.h +++ b/include/asm-cris/semaphore.h | |||
@@ -1,133 +1 @@ | |||
1 | /* $Id: semaphore.h,v 1.3 2001/05/08 13:54:09 bjornw Exp $ */ | #include <linux/semaphore.h> | |
2 | |||
3 | /* On the i386 these are coded in asm, perhaps we should as well. Later.. */ | ||
4 | |||
5 | #ifndef _CRIS_SEMAPHORE_H | ||
6 | #define _CRIS_SEMAPHORE_H | ||
7 | |||
8 | #define RW_LOCK_BIAS 0x01000000 | ||
9 | |||
10 | #include <linux/wait.h> | ||
11 | #include <linux/spinlock.h> | ||
12 | #include <linux/rwsem.h> | ||
13 | |||
14 | #include <asm/system.h> | ||
15 | #include <asm/atomic.h> | ||
16 | |||
17 | /* | ||
18 | * CRIS semaphores, implemented in C-only so far. | ||
19 | */ | ||
20 | |||
21 | struct semaphore { | ||
22 | atomic_t count; | ||
23 | atomic_t waking; | ||
24 | wait_queue_head_t wait; | ||
25 | }; | ||
26 | |||
27 | #define __SEMAPHORE_INITIALIZER(name, n) \ | ||
28 | { \ | ||
29 | .count = ATOMIC_INIT(n), \ | ||
30 | .waking = ATOMIC_INIT(0), \ | ||
31 | .wait = __WAIT_QUEUE_HEAD_INITIALIZER((name).wait) \ | ||
32 | } | ||
33 | |||
34 | #define __DECLARE_SEMAPHORE_GENERIC(name,count) \ | ||
35 | struct semaphore name = __SEMAPHORE_INITIALIZER(name,count) | ||
36 | |||
37 | #define DECLARE_MUTEX(name) __DECLARE_SEMAPHORE_GENERIC(name,1) | ||
38 | |||
39 | static inline void sema_init(struct semaphore *sem, int val) | ||
40 | { | ||
41 | *sem = (struct semaphore)__SEMAPHORE_INITIALIZER((*sem),val); | ||
42 | } | ||
43 | |||
44 | static inline void init_MUTEX (struct semaphore *sem) | ||
45 | { | ||
46 | sema_init(sem, 1); | ||
47 | } | ||
48 | |||
49 | static inline void init_MUTEX_LOCKED (struct semaphore *sem) | ||
50 | { | ||
51 | sema_init(sem, 0); | ||
52 | } | ||
53 | |||
54 | extern void __down(struct semaphore * sem); | ||
55 | extern int __down_interruptible(struct semaphore * sem); | ||
56 | extern int __down_trylock(struct semaphore * sem); | ||
57 | extern void __up(struct semaphore * sem); | ||
58 | |||
59 | /* notice - we probably can do cli/sti here instead of saving */ | ||
60 | |||
61 | static inline void down(struct semaphore * sem) | ||
62 | { | ||
63 | unsigned long flags; | ||
64 | int failed; | ||
65 | |||
66 | might_sleep(); | ||
67 | |||
68 | /* atomically decrement the semaphores count, and if its negative, we wait */ | ||
69 | cris_atomic_save(sem, flags); | ||
70 | failed = --(sem->count.counter) < 0; | ||
71 | cris_atomic_restore(sem, flags); | ||
72 | if(failed) { | ||
73 | __down(sem); | ||
74 | } | ||
75 | } | ||
76 | |||
77 | /* | ||
78 | * This version waits in interruptible state so that the waiting | ||
79 | * process can be killed. The down_interruptible routine | ||
80 | * returns negative for signalled and zero for semaphore acquired. | ||
81 | */ | ||
82 | |||
83 | static inline int down_interruptible(struct semaphore * sem) | ||
84 | { | ||
85 | unsigned long flags; | ||
86 | int failed; | ||
87 | |||
88 | might_sleep(); | ||
89 | |||
90 | /* atomically decrement the semaphores count, and if its negative, we wait */ | ||
91 | cris_atomic_save(sem, flags); | ||
92 | failed = --(sem->count.counter) < 0; | ||
93 | cris_atomic_restore(sem, flags); | ||
94 | if(failed) | ||
95 | failed = __down_interruptible(sem); | ||
96 | return(failed); | ||
97 | } | ||
98 | |||
99 | static inline int down_trylock(struct semaphore * sem) | ||
100 | { | ||
101 | unsigned long flags; | ||
102 | int failed; | ||
103 | |||
104 | cris_atomic_save(sem, flags); | ||
105 | failed = --(sem->count.counter) < 0; | ||
106 | cris_atomic_restore(sem, flags); | ||
107 | if(failed) | ||
108 | failed = __down_trylock(sem); | ||
109 | return(failed); | ||
110 | |||
111 | } | ||
112 | |||
113 | /* | ||
114 | * Note! This is subtle. We jump to wake people up only if | ||
115 | * the semaphore was negative (== somebody was waiting on it). | ||
116 | * The default case (no contention) will result in NO | ||
117 | * jumps for both down() and up(). | ||
118 | */ | ||
119 | static inline void up(struct semaphore * sem) | ||
120 | { | ||
121 | unsigned long flags; | ||
122 | int wakeup; | ||
123 | |||
124 | /* atomically increment the semaphores count, and if it was negative, we wake people */ | ||
125 | cris_atomic_save(sem, flags); | ||
126 | wakeup = ++(sem->count.counter) <= 0; | ||
127 | cris_atomic_restore(sem, flags); | ||
128 | if(wakeup) { | ||
129 | __up(sem); | ||
130 | } | ||
131 | } | ||
132 | |||
133 | #endif | ||
diff --git a/include/asm-frv/semaphore.h b/include/asm-frv/semaphore.h index d7aaa1911a1a..d9b2034ed1d2 100644 --- a/include/asm-frv/semaphore.h +++ b/include/asm-frv/semaphore.h | |||
@@ -1,155 +1 @@ | |||
1 | /* semaphore.h: semaphores for the FR-V | #include <linux/semaphore.h> | |
2 | * | ||
3 | * Copyright (C) 2003 Red Hat, Inc. All Rights Reserved. | ||
4 | * Written by David Howells (dhowells@redhat.com) | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or | ||
7 | * modify it under the terms of the GNU General Public License | ||
8 | * as published by the Free Software Foundation; either version | ||
9 | * 2 of the License, or (at your option) any later version. | ||
10 | */ | ||
11 | #ifndef _ASM_SEMAPHORE_H | ||
12 | #define _ASM_SEMAPHORE_H | ||
13 | |||
14 | #define RW_LOCK_BIAS 0x01000000 | ||
15 | |||
16 | #ifndef __ASSEMBLY__ | ||
17 | |||
18 | #include <linux/linkage.h> | ||
19 | #include <linux/wait.h> | ||
20 | #include <linux/spinlock.h> | ||
21 | #include <linux/rwsem.h> | ||
22 | |||
23 | /* | ||
24 | * the semaphore definition | ||
25 | * - if counter is >0 then there are tokens available on the semaphore for down to collect | ||
26 | * - if counter is <=0 then there are no spare tokens, and anyone that wants one must wait | ||
27 | * - if wait_list is not empty, then there are processes waiting for the semaphore | ||
28 | */ | ||
29 | struct semaphore { | ||
30 | unsigned counter; | ||
31 | spinlock_t wait_lock; | ||
32 | struct list_head wait_list; | ||
33 | #ifdef CONFIG_DEBUG_SEMAPHORE | ||
34 | unsigned __magic; | ||
35 | #endif | ||
36 | }; | ||
37 | |||
38 | #ifdef CONFIG_DEBUG_SEMAPHORE | ||
39 | # define __SEM_DEBUG_INIT(name) , (long)&(name).__magic | ||
40 | #else | ||
41 | # define __SEM_DEBUG_INIT(name) | ||
42 | #endif | ||
43 | |||
44 | |||
45 | #define __SEMAPHORE_INITIALIZER(name,count) \ | ||
46 | { count, SPIN_LOCK_UNLOCKED, LIST_HEAD_INIT((name).wait_list) __SEM_DEBUG_INIT(name) } | ||
47 | |||
48 | #define __DECLARE_SEMAPHORE_GENERIC(name,count) \ | ||
49 | struct semaphore name = __SEMAPHORE_INITIALIZER(name,count) | ||
50 | |||
51 | #define DECLARE_MUTEX(name) __DECLARE_SEMAPHORE_GENERIC(name,1) | ||
52 | |||
53 | static inline void sema_init (struct semaphore *sem, int val) | ||
54 | { | ||
55 | *sem = (struct semaphore) __SEMAPHORE_INITIALIZER(*sem, val); | ||
56 | } | ||
57 | |||
58 | static inline void init_MUTEX (struct semaphore *sem) | ||
59 | { | ||
60 | sema_init(sem, 1); | ||
61 | } | ||
62 | |||
63 | static inline void init_MUTEX_LOCKED (struct semaphore *sem) | ||
64 | { | ||
65 | sema_init(sem, 0); | ||
66 | } | ||
67 | |||
68 | extern void __down(struct semaphore *sem, unsigned long flags); | ||
69 | extern int __down_interruptible(struct semaphore *sem, unsigned long flags); | ||
70 | extern void __up(struct semaphore *sem); | ||
71 | |||
72 | static inline void down(struct semaphore *sem) | ||
73 | { | ||
74 | unsigned long flags; | ||
75 | |||
76 | #ifdef CONFIG_DEBUG_SEMAPHORE | ||
77 | CHECK_MAGIC(sem->__magic); | ||
78 | #endif | ||
79 | |||
80 | spin_lock_irqsave(&sem->wait_lock, flags); | ||
81 | if (likely(sem->counter > 0)) { | ||
82 | sem->counter--; | ||
83 | spin_unlock_irqrestore(&sem->wait_lock, flags); | ||
84 | } | ||
85 | else { | ||
86 | __down(sem, flags); | ||
87 | } | ||
88 | } | ||
89 | |||
90 | static inline int down_interruptible(struct semaphore *sem) | ||
91 | { | ||
92 | unsigned long flags; | ||
93 | int ret = 0; | ||
94 | |||
95 | #ifdef CONFIG_DEBUG_SEMAPHORE | ||
96 | CHECK_MAGIC(sem->__magic); | ||
97 | #endif | ||
98 | |||
99 | spin_lock_irqsave(&sem->wait_lock, flags); | ||
100 | if (likely(sem->counter > 0)) { | ||
101 | sem->counter--; | ||
102 | spin_unlock_irqrestore(&sem->wait_lock, flags); | ||
103 | } | ||
104 | else { | ||
105 | ret = __down_interruptible(sem, flags); | ||
106 | } | ||
107 | return ret; | ||
108 | } | ||
109 | |||
110 | /* | ||
111 | * non-blockingly attempt to down() a semaphore. | ||
112 | * - returns zero if we acquired it | ||
113 | */ | ||
114 | static inline int down_trylock(struct semaphore *sem) | ||
115 | { | ||
116 | unsigned long flags; | ||
117 | int success = 0; | ||
118 | |||
119 | #ifdef CONFIG_DEBUG_SEMAPHORE | ||
120 | CHECK_MAGIC(sem->__magic); | ||
121 | #endif | ||
122 | |||
123 | spin_lock_irqsave(&sem->wait_lock, flags); | ||
124 | if (sem->counter > 0) { | ||
125 | sem->counter--; | ||
126 | success = 1; | ||
127 | } | ||
128 | spin_unlock_irqrestore(&sem->wait_lock, flags); | ||
129 | return !success; | ||
130 | } | ||
131 | |||
132 | static inline void up(struct semaphore *sem) | ||
133 | { | ||
134 | unsigned long flags; | ||
135 | |||
136 | #ifdef CONFIG_DEBUG_SEMAPHORE | ||
137 | CHECK_MAGIC(sem->__magic); | ||
138 | #endif | ||
139 | |||
140 | spin_lock_irqsave(&sem->wait_lock, flags); | ||
141 | if (!list_empty(&sem->wait_list)) | ||
142 | __up(sem); | ||
143 | else | ||
144 | sem->counter++; | ||
145 | spin_unlock_irqrestore(&sem->wait_lock, flags); | ||
146 | } | ||
147 | |||
148 | static inline int sem_getcount(struct semaphore *sem) | ||
149 | { | ||
150 | return sem->counter; | ||
151 | } | ||
152 | |||
153 | #endif /* __ASSEMBLY__ */ | ||
154 | |||
155 | #endif | ||
diff --git a/include/asm-h8300/semaphore-helper.h b/include/asm-h8300/semaphore-helper.h deleted file mode 100644 index 4fea36be5fd8..000000000000 --- a/include/asm-h8300/semaphore-helper.h +++ /dev/null | |||
@@ -1,85 +0,0 @@ | |||
1 | #ifndef _H8300_SEMAPHORE_HELPER_H | ||
2 | #define _H8300_SEMAPHORE_HELPER_H | ||
3 | |||
4 | /* | ||
5 | * SMP- and interrupt-safe semaphores helper functions. | ||
6 | * | ||
7 | * (C) Copyright 1996 Linus Torvalds | ||
8 | * | ||
9 | * based on | ||
10 | * m68k version by Andreas Schwab | ||
11 | */ | ||
12 | |||
13 | #include <linux/errno.h> | ||
14 | |||
15 | /* | ||
16 | * These two _must_ execute atomically wrt each other. | ||
17 | */ | ||
18 | static inline void wake_one_more(struct semaphore * sem) | ||
19 | { | ||
20 | atomic_inc((atomic_t *)&sem->sleepers); | ||
21 | } | ||
22 | |||
23 | static inline int waking_non_zero(struct semaphore *sem) | ||
24 | { | ||
25 | int ret; | ||
26 | unsigned long flags; | ||
27 | |||
28 | spin_lock_irqsave(&semaphore_wake_lock, flags); | ||
29 | ret = 0; | ||
30 | if (sem->sleepers > 0) { | ||
31 | sem->sleepers--; | ||
32 | ret = 1; | ||
33 | } | ||
34 | spin_unlock_irqrestore(&semaphore_wake_lock, flags); | ||
35 | return ret; | ||
36 | } | ||
37 | |||
38 | /* | ||
39 | * waking_non_zero_interruptible: | ||
40 | * 1 got the lock | ||
41 | * 0 go to sleep | ||
42 | * -EINTR interrupted | ||
43 | */ | ||
44 | static inline int waking_non_zero_interruptible(struct semaphore *sem, | ||
45 | struct task_struct *tsk) | ||
46 | { | ||
47 | int ret; | ||
48 | unsigned long flags; | ||
49 | |||
50 | spin_lock_irqsave(&semaphore_wake_lock, flags); | ||
51 | ret = 0; | ||
52 | if (sem->sleepers > 0) { | ||
53 | sem->sleepers--; | ||
54 | ret = 1; | ||
55 | } else if (signal_pending(tsk)) { | ||
56 | atomic_inc(&sem->count); | ||
57 | ret = -EINTR; | ||
58 | } | ||
59 | spin_unlock_irqrestore(&semaphore_wake_lock, flags); | ||
60 | return ret; | ||
61 | } | ||
62 | |||
63 | /* | ||
64 | * waking_non_zero_trylock: | ||
65 | * 1 failed to lock | ||
66 | * 0 got the lock | ||
67 | */ | ||
68 | static inline int waking_non_zero_trylock(struct semaphore *sem) | ||
69 | { | ||
70 | int ret; | ||
71 | unsigned long flags; | ||
72 | |||
73 | spin_lock_irqsave(&semaphore_wake_lock, flags); | ||
74 | ret = 1; | ||
75 | if (sem->sleepers <= 0) | ||
76 | atomic_inc(&sem->count); | ||
77 | else { | ||
78 | sem->sleepers--; | ||
79 | ret = 0; | ||
80 | } | ||
81 | spin_unlock_irqrestore(&semaphore_wake_lock, flags); | ||
82 | return ret; | ||
83 | } | ||
84 | |||
85 | #endif | ||
diff --git a/include/asm-h8300/semaphore.h b/include/asm-h8300/semaphore.h index f3ffff83ff09..d9b2034ed1d2 100644 --- a/include/asm-h8300/semaphore.h +++ b/include/asm-h8300/semaphore.h | |||
@@ -1,190 +1 @@ | |||
1 | #ifndef _H8300_SEMAPHORE_H | #include <linux/semaphore.h> | |
2 | #define _H8300_SEMAPHORE_H | ||
3 | |||
4 | #define RW_LOCK_BIAS 0x01000000 | ||
5 | |||
6 | #ifndef __ASSEMBLY__ | ||
7 | |||
8 | #include <linux/linkage.h> | ||
9 | #include <linux/wait.h> | ||
10 | #include <linux/spinlock.h> | ||
11 | #include <linux/rwsem.h> | ||
12 | |||
13 | #include <asm/system.h> | ||
14 | #include <asm/atomic.h> | ||
15 | |||
16 | /* | ||
17 | * Interrupt-safe semaphores.. | ||
18 | * | ||
19 | * (C) Copyright 1996 Linus Torvalds | ||
20 | * | ||
21 | * H8/300 version by Yoshinori Sato | ||
22 | */ | ||
23 | |||
24 | |||
25 | struct semaphore { | ||
26 | atomic_t count; | ||
27 | int sleepers; | ||
28 | wait_queue_head_t wait; | ||
29 | }; | ||
30 | |||
31 | #define __SEMAPHORE_INITIALIZER(name, n) \ | ||
32 | { \ | ||
33 | .count = ATOMIC_INIT(n), \ | ||
34 | .sleepers = 0, \ | ||
35 | .wait = __WAIT_QUEUE_HEAD_INITIALIZER((name).wait) \ | ||
36 | } | ||
37 | |||
38 | #define __DECLARE_SEMAPHORE_GENERIC(name,count) \ | ||
39 | struct semaphore name = __SEMAPHORE_INITIALIZER(name,count) | ||
40 | |||
41 | #define DECLARE_MUTEX(name) __DECLARE_SEMAPHORE_GENERIC(name,1) | ||
42 | |||
43 | static inline void sema_init (struct semaphore *sem, int val) | ||
44 | { | ||
45 | *sem = (struct semaphore)__SEMAPHORE_INITIALIZER(*sem, val); | ||
46 | } | ||
47 | |||
48 | static inline void init_MUTEX (struct semaphore *sem) | ||
49 | { | ||
50 | sema_init(sem, 1); | ||
51 | } | ||
52 | |||
53 | static inline void init_MUTEX_LOCKED (struct semaphore *sem) | ||
54 | { | ||
55 | sema_init(sem, 0); | ||
56 | } | ||
57 | |||
58 | asmlinkage void __down_failed(void /* special register calling convention */); | ||
59 | asmlinkage int __down_failed_interruptible(void /* params in registers */); | ||
60 | asmlinkage int __down_failed_trylock(void /* params in registers */); | ||
61 | asmlinkage void __up_wakeup(void /* special register calling convention */); | ||
62 | |||
63 | asmlinkage void __down(struct semaphore * sem); | ||
64 | asmlinkage int __down_interruptible(struct semaphore * sem); | ||
65 | asmlinkage int __down_trylock(struct semaphore * sem); | ||
66 | asmlinkage void __up(struct semaphore * sem); | ||
67 | |||
68 | extern spinlock_t semaphore_wake_lock; | ||
69 | |||
70 | /* | ||
71 | * This is ugly, but we want the default case to fall through. | ||
72 | * "down_failed" is a special asm handler that calls the C | ||
73 | * routine that actually waits. See arch/m68k/lib/semaphore.S | ||
74 | */ | ||
75 | static inline void down(struct semaphore * sem) | ||
76 | { | ||
77 | register atomic_t *count asm("er0"); | ||
78 | |||
79 | might_sleep(); | ||
80 | |||
81 | count = &(sem->count); | ||
82 | __asm__ __volatile__( | ||
83 | "stc ccr,r3l\n\t" | ||
84 | "orc #0x80,ccr\n\t" | ||
85 | "mov.l %2, er1\n\t" | ||
86 | "dec.l #1,er1\n\t" | ||
87 | "mov.l er1,%0\n\t" | ||
88 | "bpl 1f\n\t" | ||
89 | "ldc r3l,ccr\n\t" | ||
90 | "mov.l %1,er0\n\t" | ||
91 | "jsr @___down\n\t" | ||
92 | "bra 2f\n" | ||
93 | "1:\n\t" | ||
94 | "ldc r3l,ccr\n" | ||
95 | "2:" | ||
96 | : "=m"(*count) | ||
97 | : "g"(sem),"m"(*count) | ||
98 | : "cc", "er1", "er2", "er3"); | ||
99 | } | ||
100 | |||
101 | static inline int down_interruptible(struct semaphore * sem) | ||
102 | { | ||
103 | register atomic_t *count asm("er0"); | ||
104 | |||
105 | might_sleep(); | ||
106 | |||
107 | count = &(sem->count); | ||
108 | __asm__ __volatile__( | ||
109 | "stc ccr,r1l\n\t" | ||
110 | "orc #0x80,ccr\n\t" | ||
111 | "mov.l %3, er2\n\t" | ||
112 | "dec.l #1,er2\n\t" | ||
113 | "mov.l er2,%1\n\t" | ||
114 | "bpl 1f\n\t" | ||
115 | "ldc r1l,ccr\n\t" | ||
116 | "mov.l %2,er0\n\t" | ||
117 | "jsr @___down_interruptible\n\t" | ||
118 | "bra 2f\n" | ||
119 | "1:\n\t" | ||
120 | "ldc r1l,ccr\n\t" | ||
121 | "sub.l %0,%0\n\t" | ||
122 | "2:\n\t" | ||
123 | : "=r" (count),"=m" (*count) | ||
124 | : "g"(sem),"m"(*count) | ||
125 | : "cc", "er1", "er2", "er3"); | ||
126 | return (int)count; | ||
127 | } | ||
128 | |||
129 | static inline int down_trylock(struct semaphore * sem) | ||
130 | { | ||
131 | register atomic_t *count asm("er0"); | ||
132 | |||
133 | count = &(sem->count); | ||
134 | __asm__ __volatile__( | ||
135 | "stc ccr,r3l\n\t" | ||
136 | "orc #0x80,ccr\n\t" | ||
137 | "mov.l %3,er2\n\t" | ||
138 | "dec.l #1,er2\n\t" | ||
139 | "mov.l er2,%0\n\t" | ||
140 | "bpl 1f\n\t" | ||
141 | "ldc r3l,ccr\n\t" | ||
142 | "jmp @3f\n\t" | ||
143 | LOCK_SECTION_START(".align 2\n\t") | ||
144 | "3:\n\t" | ||
145 | "mov.l %2,er0\n\t" | ||
146 | "jsr @___down_trylock\n\t" | ||
147 | "jmp @2f\n\t" | ||
148 | LOCK_SECTION_END | ||
149 | "1:\n\t" | ||
150 | "ldc r3l,ccr\n\t" | ||
151 | "sub.l %1,%1\n" | ||
152 | "2:" | ||
153 | : "=m" (*count),"=r"(count) | ||
154 | : "g"(sem),"m"(*count) | ||
155 | : "cc", "er1","er2", "er3"); | ||
156 | return (int)count; | ||
157 | } | ||
158 | |||
159 | /* | ||
160 | * Note! This is subtle. We jump to wake people up only if | ||
161 | * the semaphore was negative (== somebody was waiting on it). | ||
162 | * The default case (no contention) will result in NO | ||
163 | * jumps for both down() and up(). | ||
164 | */ | ||
165 | static inline void up(struct semaphore * sem) | ||
166 | { | ||
167 | register atomic_t *count asm("er0"); | ||
168 | |||
169 | count = &(sem->count); | ||
170 | __asm__ __volatile__( | ||
171 | "stc ccr,r3l\n\t" | ||
172 | "orc #0x80,ccr\n\t" | ||
173 | "mov.l %2,er1\n\t" | ||
174 | "inc.l #1,er1\n\t" | ||
175 | "mov.l er1,%0\n\t" | ||
176 | "ldc r3l,ccr\n\t" | ||
177 | "sub.l er2,er2\n\t" | ||
178 | "cmp.l er2,er1\n\t" | ||
179 | "bgt 1f\n\t" | ||
180 | "mov.l %1,er0\n\t" | ||
181 | "jsr @___up\n" | ||
182 | "1:" | ||
183 | : "=m"(*count) | ||
184 | : "g"(sem),"m"(*count) | ||
185 | : "cc", "er1", "er2", "er3"); | ||
186 | } | ||
187 | |||
188 | #endif /* __ASSEMBLY__ */ | ||
189 | |||
190 | #endif | ||
diff --git a/include/asm-ia64/semaphore.h b/include/asm-ia64/semaphore.h index d8393d11288d..d9b2034ed1d2 100644 --- a/include/asm-ia64/semaphore.h +++ b/include/asm-ia64/semaphore.h | |||
@@ -1,99 +1 @@ | |||
1 | #ifndef _ASM_IA64_SEMAPHORE_H | #include <linux/semaphore.h> | |
2 | #define _ASM_IA64_SEMAPHORE_H | ||
3 | |||
4 | /* | ||
5 | * Copyright (C) 1998-2000 Hewlett-Packard Co | ||
6 | * Copyright (C) 1998-2000 David Mosberger-Tang <davidm@hpl.hp.com> | ||
7 | */ | ||
8 | |||
9 | #include <linux/wait.h> | ||
10 | #include <linux/rwsem.h> | ||
11 | |||
12 | #include <asm/atomic.h> | ||
13 | |||
14 | struct semaphore { | ||
15 | atomic_t count; | ||
16 | int sleepers; | ||
17 | wait_queue_head_t wait; | ||
18 | }; | ||
19 | |||
20 | #define __SEMAPHORE_INITIALIZER(name, n) \ | ||
21 | { \ | ||
22 | .count = ATOMIC_INIT(n), \ | ||
23 | .sleepers = 0, \ | ||
24 | .wait = __WAIT_QUEUE_HEAD_INITIALIZER((name).wait) \ | ||
25 | } | ||
26 | |||
27 | #define __DECLARE_SEMAPHORE_GENERIC(name,count) \ | ||
28 | struct semaphore name = __SEMAPHORE_INITIALIZER(name, count) | ||
29 | |||
30 | #define DECLARE_MUTEX(name) __DECLARE_SEMAPHORE_GENERIC(name, 1) | ||
31 | |||
32 | static inline void | ||
33 | sema_init (struct semaphore *sem, int val) | ||
34 | { | ||
35 | *sem = (struct semaphore) __SEMAPHORE_INITIALIZER(*sem, val); | ||
36 | } | ||
37 | |||
38 | static inline void | ||
39 | init_MUTEX (struct semaphore *sem) | ||
40 | { | ||
41 | sema_init(sem, 1); | ||
42 | } | ||
43 | |||
44 | static inline void | ||
45 | init_MUTEX_LOCKED (struct semaphore *sem) | ||
46 | { | ||
47 | sema_init(sem, 0); | ||
48 | } | ||
49 | |||
50 | extern void __down (struct semaphore * sem); | ||
51 | extern int __down_interruptible (struct semaphore * sem); | ||
52 | extern int __down_trylock (struct semaphore * sem); | ||
53 | extern void __up (struct semaphore * sem); | ||
54 | |||
55 | /* | ||
56 | * Atomically decrement the semaphore's count. If it goes negative, | ||
57 | * block the calling thread in the TASK_UNINTERRUPTIBLE state. | ||
58 | */ | ||
59 | static inline void | ||
60 | down (struct semaphore *sem) | ||
61 | { | ||
62 | might_sleep(); | ||
63 | if (ia64_fetchadd(-1, &sem->count.counter, acq) < 1) | ||
64 | __down(sem); | ||
65 | } | ||
66 | |||
67 | /* | ||
68 | * Atomically decrement the semaphore's count. If it goes negative, | ||
69 | * block the calling thread in the TASK_INTERRUPTIBLE state. | ||
70 | */ | ||
71 | static inline int | ||
72 | down_interruptible (struct semaphore * sem) | ||
73 | { | ||
74 | int ret = 0; | ||
75 | |||
76 | might_sleep(); | ||
77 | if (ia64_fetchadd(-1, &sem->count.counter, acq) < 1) | ||
78 | ret = __down_interruptible(sem); | ||
79 | return ret; | ||
80 | } | ||
81 | |||
82 | static inline int | ||
83 | down_trylock (struct semaphore *sem) | ||
84 | { | ||
85 | int ret = 0; | ||
86 | |||
87 | if (ia64_fetchadd(-1, &sem->count.counter, acq) < 1) | ||
88 | ret = __down_trylock(sem); | ||
89 | return ret; | ||
90 | } | ||
91 | |||
92 | static inline void | ||
93 | up (struct semaphore * sem) | ||
94 | { | ||
95 | if (ia64_fetchadd(1, &sem->count.counter, rel) <= -1) | ||
96 | __up(sem); | ||
97 | } | ||
98 | |||
99 | #endif /* _ASM_IA64_SEMAPHORE_H */ | ||
diff --git a/include/asm-m32r/semaphore.h b/include/asm-m32r/semaphore.h index b5bf95a6f2b4..d9b2034ed1d2 100644 --- a/include/asm-m32r/semaphore.h +++ b/include/asm-m32r/semaphore.h | |||
@@ -1,144 +1 @@ | |||
1 | #ifndef _ASM_M32R_SEMAPHORE_H | #include <linux/semaphore.h> | |
2 | #define _ASM_M32R_SEMAPHORE_H | ||
3 | |||
4 | #include <linux/linkage.h> | ||
5 | |||
6 | #ifdef __KERNEL__ | ||
7 | |||
8 | /* | ||
9 | * SMP- and interrupt-safe semaphores.. | ||
10 | * | ||
11 | * Copyright (C) 1996 Linus Torvalds | ||
12 | * Copyright (C) 2004, 2006 Hirokazu Takata <takata at linux-m32r.org> | ||
13 | */ | ||
14 | |||
15 | #include <linux/wait.h> | ||
16 | #include <linux/rwsem.h> | ||
17 | #include <asm/assembler.h> | ||
18 | #include <asm/system.h> | ||
19 | #include <asm/atomic.h> | ||
20 | |||
21 | struct semaphore { | ||
22 | atomic_t count; | ||
23 | int sleepers; | ||
24 | wait_queue_head_t wait; | ||
25 | }; | ||
26 | |||
27 | #define __SEMAPHORE_INITIALIZER(name, n) \ | ||
28 | { \ | ||
29 | .count = ATOMIC_INIT(n), \ | ||
30 | .sleepers = 0, \ | ||
31 | .wait = __WAIT_QUEUE_HEAD_INITIALIZER((name).wait) \ | ||
32 | } | ||
33 | |||
34 | #define __DECLARE_SEMAPHORE_GENERIC(name,count) \ | ||
35 | struct semaphore name = __SEMAPHORE_INITIALIZER(name,count) | ||
36 | |||
37 | #define DECLARE_MUTEX(name) __DECLARE_SEMAPHORE_GENERIC(name,1) | ||
38 | |||
39 | static inline void sema_init (struct semaphore *sem, int val) | ||
40 | { | ||
41 | /* | ||
42 | * *sem = (struct semaphore)__SEMAPHORE_INITIALIZER((*sem),val); | ||
43 | * | ||
44 | * i'd rather use the more flexible initialization above, but sadly | ||
45 | * GCC 2.7.2.3 emits a bogus warning. EGCS doesnt. Oh well. | ||
46 | */ | ||
47 | atomic_set(&sem->count, val); | ||
48 | sem->sleepers = 0; | ||
49 | init_waitqueue_head(&sem->wait); | ||
50 | } | ||
51 | |||
52 | static inline void init_MUTEX (struct semaphore *sem) | ||
53 | { | ||
54 | sema_init(sem, 1); | ||
55 | } | ||
56 | |||
57 | static inline void init_MUTEX_LOCKED (struct semaphore *sem) | ||
58 | { | ||
59 | sema_init(sem, 0); | ||
60 | } | ||
61 | |||
62 | asmlinkage void __down_failed(void /* special register calling convention */); | ||
63 | asmlinkage int __down_failed_interruptible(void /* params in registers */); | ||
64 | asmlinkage int __down_failed_trylock(void /* params in registers */); | ||
65 | asmlinkage void __up_wakeup(void /* special register calling convention */); | ||
66 | |||
67 | asmlinkage void __down(struct semaphore * sem); | ||
68 | asmlinkage int __down_interruptible(struct semaphore * sem); | ||
69 | asmlinkage int __down_trylock(struct semaphore * sem); | ||
70 | asmlinkage void __up(struct semaphore * sem); | ||
71 | |||
72 | /* | ||
73 | * Atomically decrement the semaphore's count. If it goes negative, | ||
74 | * block the calling thread in the TASK_UNINTERRUPTIBLE state. | ||
75 | */ | ||
76 | static inline void down(struct semaphore * sem) | ||
77 | { | ||
78 | might_sleep(); | ||
79 | if (unlikely(atomic_dec_return(&sem->count) < 0)) | ||
80 | __down(sem); | ||
81 | } | ||
82 | |||
83 | /* | ||
84 | * Interruptible try to acquire a semaphore. If we obtained | ||
85 | * it, return zero. If we were interrupted, returns -EINTR | ||
86 | */ | ||
87 | static inline int down_interruptible(struct semaphore * sem) | ||
88 | { | ||
89 | int result = 0; | ||
90 | |||
91 | might_sleep(); | ||
92 | if (unlikely(atomic_dec_return(&sem->count) < 0)) | ||
93 | result = __down_interruptible(sem); | ||
94 | |||
95 | return result; | ||
96 | } | ||
97 | |||
98 | /* | ||
99 | * Non-blockingly attempt to down() a semaphore. | ||
100 | * Returns zero if we acquired it | ||
101 | */ | ||
102 | static inline int down_trylock(struct semaphore * sem) | ||
103 | { | ||
104 | unsigned long flags; | ||
105 | long count; | ||
106 | int result = 0; | ||
107 | |||
108 | local_irq_save(flags); | ||
109 | __asm__ __volatile__ ( | ||
110 | "# down_trylock \n\t" | ||
111 | DCACHE_CLEAR("%0", "r4", "%1") | ||
112 | M32R_LOCK" %0, @%1; \n\t" | ||
113 | "addi %0, #-1; \n\t" | ||
114 | M32R_UNLOCK" %0, @%1; \n\t" | ||
115 | : "=&r" (count) | ||
116 | : "r" (&sem->count) | ||
117 | : "memory" | ||
118 | #ifdef CONFIG_CHIP_M32700_TS1 | ||
119 | , "r4" | ||
120 | #endif /* CONFIG_CHIP_M32700_TS1 */ | ||
121 | ); | ||
122 | local_irq_restore(flags); | ||
123 | |||
124 | if (unlikely(count < 0)) | ||
125 | result = __down_trylock(sem); | ||
126 | |||
127 | return result; | ||
128 | } | ||
129 | |||
130 | /* | ||
131 | * Note! This is subtle. We jump to wake people up only if | ||
132 | * the semaphore was negative (== somebody was waiting on it). | ||
133 | * The default case (no contention) will result in NO | ||
134 | * jumps for both down() and up(). | ||
135 | */ | ||
136 | static inline void up(struct semaphore * sem) | ||
137 | { | ||
138 | if (unlikely(atomic_inc_return(&sem->count) <= 0)) | ||
139 | __up(sem); | ||
140 | } | ||
141 | |||
142 | #endif /* __KERNEL__ */ | ||
143 | |||
144 | #endif /* _ASM_M32R_SEMAPHORE_H */ | ||
diff --git a/include/asm-m68k/semaphore-helper.h b/include/asm-m68k/semaphore-helper.h deleted file mode 100644 index eef30ba0b499..000000000000 --- a/include/asm-m68k/semaphore-helper.h +++ /dev/null | |||
@@ -1,142 +0,0 @@ | |||
1 | #ifndef _M68K_SEMAPHORE_HELPER_H | ||
2 | #define _M68K_SEMAPHORE_HELPER_H | ||
3 | |||
4 | /* | ||
5 | * SMP- and interrupt-safe semaphores helper functions. | ||
6 | * | ||
7 | * (C) Copyright 1996 Linus Torvalds | ||
8 | * | ||
9 | * m68k version by Andreas Schwab | ||
10 | */ | ||
11 | |||
12 | #include <linux/errno.h> | ||
13 | |||
14 | /* | ||
15 | * These two _must_ execute atomically wrt each other. | ||
16 | */ | ||
17 | static inline void wake_one_more(struct semaphore * sem) | ||
18 | { | ||
19 | atomic_inc(&sem->waking); | ||
20 | } | ||
21 | |||
22 | #ifndef CONFIG_RMW_INSNS | ||
23 | extern spinlock_t semaphore_wake_lock; | ||
24 | #endif | ||
25 | |||
26 | static inline int waking_non_zero(struct semaphore *sem) | ||
27 | { | ||
28 | int ret; | ||
29 | #ifndef CONFIG_RMW_INSNS | ||
30 | unsigned long flags; | ||
31 | |||
32 | spin_lock_irqsave(&semaphore_wake_lock, flags); | ||
33 | ret = 0; | ||
34 | if (atomic_read(&sem->waking) > 0) { | ||
35 | atomic_dec(&sem->waking); | ||
36 | ret = 1; | ||
37 | } | ||
38 | spin_unlock_irqrestore(&semaphore_wake_lock, flags); | ||
39 | #else | ||
40 | int tmp1, tmp2; | ||
41 | |||
42 | __asm__ __volatile__ | ||
43 | ("1: movel %1,%2\n" | ||
44 | " jle 2f\n" | ||
45 | " subql #1,%2\n" | ||
46 | " casl %1,%2,%3\n" | ||
47 | " jne 1b\n" | ||
48 | " moveq #1,%0\n" | ||
49 | "2:" | ||
50 | : "=d" (ret), "=d" (tmp1), "=d" (tmp2) | ||
51 | : "m" (sem->waking), "0" (0), "1" (sem->waking)); | ||
52 | #endif | ||
53 | |||
54 | return ret; | ||
55 | } | ||
56 | |||
57 | /* | ||
58 | * waking_non_zero_interruptible: | ||
59 | * 1 got the lock | ||
60 | * 0 go to sleep | ||
61 | * -EINTR interrupted | ||
62 | */ | ||
63 | static inline int waking_non_zero_interruptible(struct semaphore *sem, | ||
64 | struct task_struct *tsk) | ||
65 | { | ||
66 | int ret; | ||
67 | #ifndef CONFIG_RMW_INSNS | ||
68 | unsigned long flags; | ||
69 | |||
70 | spin_lock_irqsave(&semaphore_wake_lock, flags); | ||
71 | ret = 0; | ||
72 | if (atomic_read(&sem->waking) > 0) { | ||
73 | atomic_dec(&sem->waking); | ||
74 | ret = 1; | ||
75 | } else if (signal_pending(tsk)) { | ||
76 | atomic_inc(&sem->count); | ||
77 | ret = -EINTR; | ||
78 | } | ||
79 | spin_unlock_irqrestore(&semaphore_wake_lock, flags); | ||
80 | #else | ||
81 | int tmp1, tmp2; | ||
82 | |||
83 | __asm__ __volatile__ | ||
84 | ("1: movel %1,%2\n" | ||
85 | " jle 2f\n" | ||
86 | " subql #1,%2\n" | ||
87 | " casl %1,%2,%3\n" | ||
88 | " jne 1b\n" | ||
89 | " moveq #1,%0\n" | ||
90 | " jra %a4\n" | ||
91 | "2:" | ||
92 | : "=d" (ret), "=d" (tmp1), "=d" (tmp2) | ||
93 | : "m" (sem->waking), "i" (&&next), "0" (0), "1" (sem->waking)); | ||
94 | if (signal_pending(tsk)) { | ||
95 | atomic_inc(&sem->count); | ||
96 | ret = -EINTR; | ||
97 | } | ||
98 | next: | ||
99 | #endif | ||
100 | |||
101 | return ret; | ||
102 | } | ||
103 | |||
104 | /* | ||
105 | * waking_non_zero_trylock: | ||
106 | * 1 failed to lock | ||
107 | * 0 got the lock | ||
108 | */ | ||
109 | static inline int waking_non_zero_trylock(struct semaphore *sem) | ||
110 | { | ||
111 | int ret; | ||
112 | #ifndef CONFIG_RMW_INSNS | ||
113 | unsigned long flags; | ||
114 | |||
115 | spin_lock_irqsave(&semaphore_wake_lock, flags); | ||
116 | ret = 1; | ||
117 | if (atomic_read(&sem->waking) > 0) { | ||
118 | atomic_dec(&sem->waking); | ||
119 | ret = 0; | ||
120 | } else | ||
121 | atomic_inc(&sem->count); | ||
122 | spin_unlock_irqrestore(&semaphore_wake_lock, flags); | ||
123 | #else | ||
124 | int tmp1, tmp2; | ||
125 | |||
126 | __asm__ __volatile__ | ||
127 | ("1: movel %1,%2\n" | ||
128 | " jle 2f\n" | ||
129 | " subql #1,%2\n" | ||
130 | " casl %1,%2,%3\n" | ||
131 | " jne 1b\n" | ||
132 | " moveq #0,%0\n" | ||
133 | "2:" | ||
134 | : "=d" (ret), "=d" (tmp1), "=d" (tmp2) | ||
135 | : "m" (sem->waking), "0" (1), "1" (sem->waking)); | ||
136 | if (ret) | ||
137 | atomic_inc(&sem->count); | ||
138 | #endif | ||
139 | return ret; | ||
140 | } | ||
141 | |||
142 | #endif | ||
diff --git a/include/asm-m68k/semaphore.h b/include/asm-m68k/semaphore.h index 64d6b119bb0a..d9b2034ed1d2 100644 --- a/include/asm-m68k/semaphore.h +++ b/include/asm-m68k/semaphore.h | |||
@@ -1,163 +1 @@ | |||
1 | #ifndef _M68K_SEMAPHORE_H | #include <linux/semaphore.h> | |
2 | #define _M68K_SEMAPHORE_H | ||
3 | |||
4 | #define RW_LOCK_BIAS 0x01000000 | ||
5 | |||
6 | #ifndef __ASSEMBLY__ | ||
7 | |||
8 | #include <linux/linkage.h> | ||
9 | #include <linux/wait.h> | ||
10 | #include <linux/spinlock.h> | ||
11 | #include <linux/rwsem.h> | ||
12 | #include <linux/stringify.h> | ||
13 | |||
14 | #include <asm/system.h> | ||
15 | #include <asm/atomic.h> | ||
16 | |||
17 | /* | ||
18 | * Interrupt-safe semaphores.. | ||
19 | * | ||
20 | * (C) Copyright 1996 Linus Torvalds | ||
21 | * | ||
22 | * m68k version by Andreas Schwab | ||
23 | */ | ||
24 | |||
25 | |||
26 | struct semaphore { | ||
27 | atomic_t count; | ||
28 | atomic_t waking; | ||
29 | wait_queue_head_t wait; | ||
30 | }; | ||
31 | |||
32 | #define __SEMAPHORE_INITIALIZER(name, n) \ | ||
33 | { \ | ||
34 | .count = ATOMIC_INIT(n), \ | ||
35 | .waking = ATOMIC_INIT(0), \ | ||
36 | .wait = __WAIT_QUEUE_HEAD_INITIALIZER((name).wait) \ | ||
37 | } | ||
38 | |||
39 | #define __DECLARE_SEMAPHORE_GENERIC(name,count) \ | ||
40 | struct semaphore name = __SEMAPHORE_INITIALIZER(name,count) | ||
41 | |||
42 | #define DECLARE_MUTEX(name) __DECLARE_SEMAPHORE_GENERIC(name,1) | ||
43 | |||
44 | static inline void sema_init(struct semaphore *sem, int val) | ||
45 | { | ||
46 | *sem = (struct semaphore)__SEMAPHORE_INITIALIZER(*sem, val); | ||
47 | } | ||
48 | |||
49 | static inline void init_MUTEX (struct semaphore *sem) | ||
50 | { | ||
51 | sema_init(sem, 1); | ||
52 | } | ||
53 | |||
54 | static inline void init_MUTEX_LOCKED (struct semaphore *sem) | ||
55 | { | ||
56 | sema_init(sem, 0); | ||
57 | } | ||
58 | |||
59 | asmlinkage void __down_failed(void /* special register calling convention */); | ||
60 | asmlinkage int __down_failed_interruptible(void /* params in registers */); | ||
61 | asmlinkage int __down_failed_trylock(void /* params in registers */); | ||
62 | asmlinkage void __up_wakeup(void /* special register calling convention */); | ||
63 | |||
64 | asmlinkage void __down(struct semaphore * sem); | ||
65 | asmlinkage int __down_interruptible(struct semaphore * sem); | ||
66 | asmlinkage int __down_trylock(struct semaphore * sem); | ||
67 | asmlinkage void __up(struct semaphore * sem); | ||
68 | |||
69 | /* | ||
70 | * This is ugly, but we want the default case to fall through. | ||
71 | * "down_failed" is a special asm handler that calls the C | ||
72 | * routine that actually waits. See arch/m68k/lib/semaphore.S | ||
73 | */ | ||
74 | static inline void down(struct semaphore *sem) | ||
75 | { | ||
76 | register struct semaphore *sem1 __asm__ ("%a1") = sem; | ||
77 | |||
78 | might_sleep(); | ||
79 | __asm__ __volatile__( | ||
80 | "| atomic down operation\n\t" | ||
81 | "subql #1,%0@\n\t" | ||
82 | "jmi 2f\n\t" | ||
83 | "1:\n" | ||
84 | LOCK_SECTION_START(".even\n\t") | ||
85 | "2:\tpea 1b\n\t" | ||
86 | "jbra __down_failed\n" | ||
87 | LOCK_SECTION_END | ||
88 | : /* no outputs */ | ||
89 | : "a" (sem1) | ||
90 | : "memory"); | ||
91 | } | ||
92 | |||
93 | static inline int down_interruptible(struct semaphore *sem) | ||
94 | { | ||
95 | register struct semaphore *sem1 __asm__ ("%a1") = sem; | ||
96 | register int result __asm__ ("%d0"); | ||
97 | |||
98 | might_sleep(); | ||
99 | __asm__ __volatile__( | ||
100 | "| atomic interruptible down operation\n\t" | ||
101 | "subql #1,%1@\n\t" | ||
102 | "jmi 2f\n\t" | ||
103 | "clrl %0\n" | ||
104 | "1:\n" | ||
105 | LOCK_SECTION_START(".even\n\t") | ||
106 | "2:\tpea 1b\n\t" | ||
107 | "jbra __down_failed_interruptible\n" | ||
108 | LOCK_SECTION_END | ||
109 | : "=d" (result) | ||
110 | : "a" (sem1) | ||
111 | : "memory"); | ||
112 | return result; | ||
113 | } | ||
114 | |||
115 | static inline int down_trylock(struct semaphore *sem) | ||
116 | { | ||
117 | register struct semaphore *sem1 __asm__ ("%a1") = sem; | ||
118 | register int result __asm__ ("%d0"); | ||
119 | |||
120 | __asm__ __volatile__( | ||
121 | "| atomic down trylock operation\n\t" | ||
122 | "subql #1,%1@\n\t" | ||
123 | "jmi 2f\n\t" | ||
124 | "clrl %0\n" | ||
125 | "1:\n" | ||
126 | LOCK_SECTION_START(".even\n\t") | ||
127 | "2:\tpea 1b\n\t" | ||
128 | "jbra __down_failed_trylock\n" | ||
129 | LOCK_SECTION_END | ||
130 | : "=d" (result) | ||
131 | : "a" (sem1) | ||
132 | : "memory"); | ||
133 | return result; | ||
134 | } | ||
135 | |||
136 | /* | ||
137 | * Note! This is subtle. We jump to wake people up only if | ||
138 | * the semaphore was negative (== somebody was waiting on it). | ||
139 | * The default case (no contention) will result in NO | ||
140 | * jumps for both down() and up(). | ||
141 | */ | ||
142 | static inline void up(struct semaphore *sem) | ||
143 | { | ||
144 | register struct semaphore *sem1 __asm__ ("%a1") = sem; | ||
145 | |||
146 | __asm__ __volatile__( | ||
147 | "| atomic up operation\n\t" | ||
148 | "addql #1,%0@\n\t" | ||
149 | "jle 2f\n" | ||
150 | "1:\n" | ||
151 | LOCK_SECTION_START(".even\n\t") | ||
152 | "2:\t" | ||
153 | "pea 1b\n\t" | ||
154 | "jbra __up_wakeup\n" | ||
155 | LOCK_SECTION_END | ||
156 | : /* no outputs */ | ||
157 | : "a" (sem1) | ||
158 | : "memory"); | ||
159 | } | ||
160 | |||
161 | #endif /* __ASSEMBLY__ */ | ||
162 | |||
163 | #endif | ||
diff --git a/include/asm-m68knommu/semaphore-helper.h b/include/asm-m68knommu/semaphore-helper.h deleted file mode 100644 index 43da7bc483c7..000000000000 --- a/include/asm-m68knommu/semaphore-helper.h +++ /dev/null | |||
@@ -1,82 +0,0 @@ | |||
1 | #ifndef _M68K_SEMAPHORE_HELPER_H | ||
2 | #define _M68K_SEMAPHORE_HELPER_H | ||
3 | |||
4 | /* | ||
5 | * SMP- and interrupt-safe semaphores helper functions. | ||
6 | * | ||
7 | * (C) Copyright 1996 Linus Torvalds | ||
8 | * | ||
9 | * m68k version by Andreas Schwab | ||
10 | */ | ||
11 | |||
12 | |||
13 | /* | ||
14 | * These two _must_ execute atomically wrt each other. | ||
15 | */ | ||
16 | static inline void wake_one_more(struct semaphore * sem) | ||
17 | { | ||
18 | atomic_inc(&sem->waking); | ||
19 | } | ||
20 | |||
21 | static inline int waking_non_zero(struct semaphore *sem) | ||
22 | { | ||
23 | int ret; | ||
24 | unsigned long flags; | ||
25 | |||
26 | spin_lock_irqsave(&semaphore_wake_lock, flags); | ||
27 | ret = 0; | ||
28 | if (atomic_read(&sem->waking) > 0) { | ||
29 | atomic_dec(&sem->waking); | ||
30 | ret = 1; | ||
31 | } | ||
32 | spin_unlock_irqrestore(&semaphore_wake_lock, flags); | ||
33 | return ret; | ||
34 | } | ||
35 | |||
36 | /* | ||
37 | * waking_non_zero_interruptible: | ||
38 | * 1 got the lock | ||
39 | * 0 go to sleep | ||
40 | * -EINTR interrupted | ||
41 | */ | ||
42 | static inline int waking_non_zero_interruptible(struct semaphore *sem, | ||
43 | struct task_struct *tsk) | ||
44 | { | ||
45 | int ret; | ||
46 | unsigned long flags; | ||
47 | |||
48 | spin_lock_irqsave(&semaphore_wake_lock, flags); | ||
49 | ret = 0; | ||
50 | if (atomic_read(&sem->waking) > 0) { | ||
51 | atomic_dec(&sem->waking); | ||
52 | ret = 1; | ||
53 | } else if (signal_pending(tsk)) { | ||
54 | atomic_inc(&sem->count); | ||
55 | ret = -EINTR; | ||
56 | } | ||
57 | spin_unlock_irqrestore(&semaphore_wake_lock, flags); | ||
58 | return ret; | ||
59 | } | ||
60 | |||
61 | /* | ||
62 | * waking_non_zero_trylock: | ||
63 | * 1 failed to lock | ||
64 | * 0 got the lock | ||
65 | */ | ||
66 | static inline int waking_non_zero_trylock(struct semaphore *sem) | ||
67 | { | ||
68 | int ret; | ||
69 | unsigned long flags; | ||
70 | |||
71 | spin_lock_irqsave(&semaphore_wake_lock, flags); | ||
72 | ret = 1; | ||
73 | if (atomic_read(&sem->waking) > 0) { | ||
74 | atomic_dec(&sem->waking); | ||
75 | ret = 0; | ||
76 | } else | ||
77 | atomic_inc(&sem->count); | ||
78 | spin_unlock_irqrestore(&semaphore_wake_lock, flags); | ||
79 | return ret; | ||
80 | } | ||
81 | |||
82 | #endif | ||
diff --git a/include/asm-m68knommu/semaphore.h b/include/asm-m68knommu/semaphore.h index 5779eb6c0689..d9b2034ed1d2 100644 --- a/include/asm-m68knommu/semaphore.h +++ b/include/asm-m68knommu/semaphore.h | |||
@@ -1,153 +1 @@ | |||
1 | #ifndef _M68K_SEMAPHORE_H | #include <linux/semaphore.h> | |
2 | #define _M68K_SEMAPHORE_H | ||
3 | |||
4 | #define RW_LOCK_BIAS 0x01000000 | ||
5 | |||
6 | #ifndef __ASSEMBLY__ | ||
7 | |||
8 | #include <linux/linkage.h> | ||
9 | #include <linux/wait.h> | ||
10 | #include <linux/spinlock.h> | ||
11 | #include <linux/rwsem.h> | ||
12 | |||
13 | #include <asm/system.h> | ||
14 | #include <asm/atomic.h> | ||
15 | |||
16 | /* | ||
17 | * Interrupt-safe semaphores.. | ||
18 | * | ||
19 | * (C) Copyright 1996 Linus Torvalds | ||
20 | * | ||
21 | * m68k version by Andreas Schwab | ||
22 | */ | ||
23 | |||
24 | |||
25 | struct semaphore { | ||
26 | atomic_t count; | ||
27 | atomic_t waking; | ||
28 | wait_queue_head_t wait; | ||
29 | }; | ||
30 | |||
31 | #define __SEMAPHORE_INITIALIZER(name, n) \ | ||
32 | { \ | ||
33 | .count = ATOMIC_INIT(n), \ | ||
34 | .waking = ATOMIC_INIT(0), \ | ||
35 | .wait = __WAIT_QUEUE_HEAD_INITIALIZER((name).wait) \ | ||
36 | } | ||
37 | |||
38 | #define __DECLARE_SEMAPHORE_GENERIC(name,count) \ | ||
39 | struct semaphore name = __SEMAPHORE_INITIALIZER(name,count) | ||
40 | |||
41 | #define DECLARE_MUTEX(name) __DECLARE_SEMAPHORE_GENERIC(name,1) | ||
42 | |||
43 | static inline void sema_init (struct semaphore *sem, int val) | ||
44 | { | ||
45 | *sem = (struct semaphore)__SEMAPHORE_INITIALIZER(*sem, val); | ||
46 | } | ||
47 | |||
48 | static inline void init_MUTEX (struct semaphore *sem) | ||
49 | { | ||
50 | sema_init(sem, 1); | ||
51 | } | ||
52 | |||
53 | static inline void init_MUTEX_LOCKED (struct semaphore *sem) | ||
54 | { | ||
55 | sema_init(sem, 0); | ||
56 | } | ||
57 | |||
58 | asmlinkage void __down_failed(void /* special register calling convention */); | ||
59 | asmlinkage int __down_failed_interruptible(void /* params in registers */); | ||
60 | asmlinkage int __down_failed_trylock(void /* params in registers */); | ||
61 | asmlinkage void __up_wakeup(void /* special register calling convention */); | ||
62 | |||
63 | asmlinkage void __down(struct semaphore * sem); | ||
64 | asmlinkage int __down_interruptible(struct semaphore * sem); | ||
65 | asmlinkage int __down_trylock(struct semaphore * sem); | ||
66 | asmlinkage void __up(struct semaphore * sem); | ||
67 | |||
68 | extern spinlock_t semaphore_wake_lock; | ||
69 | |||
70 | /* | ||
71 | * This is ugly, but we want the default case to fall through. | ||
72 | * "down_failed" is a special asm handler that calls the C | ||
73 | * routine that actually waits. See arch/m68k/lib/semaphore.S | ||
74 | */ | ||
75 | static inline void down(struct semaphore * sem) | ||
76 | { | ||
77 | might_sleep(); | ||
78 | __asm__ __volatile__( | ||
79 | "| atomic down operation\n\t" | ||
80 | "movel %0, %%a1\n\t" | ||
81 | "lea %%pc@(1f), %%a0\n\t" | ||
82 | "subql #1, %%a1@\n\t" | ||
83 | "jmi __down_failed\n" | ||
84 | "1:" | ||
85 | : /* no outputs */ | ||
86 | : "g" (sem) | ||
87 | : "cc", "%a0", "%a1", "memory"); | ||
88 | } | ||
89 | |||
90 | static inline int down_interruptible(struct semaphore * sem) | ||
91 | { | ||
92 | int ret; | ||
93 | |||
94 | might_sleep(); | ||
95 | __asm__ __volatile__( | ||
96 | "| atomic down operation\n\t" | ||
97 | "movel %1, %%a1\n\t" | ||
98 | "lea %%pc@(1f), %%a0\n\t" | ||
99 | "subql #1, %%a1@\n\t" | ||
100 | "jmi __down_failed_interruptible\n\t" | ||
101 | "clrl %%d0\n" | ||
102 | "1: movel %%d0, %0\n" | ||
103 | : "=d" (ret) | ||
104 | : "g" (sem) | ||
105 | : "cc", "%d0", "%a0", "%a1", "memory"); | ||
106 | return(ret); | ||
107 | } | ||
108 | |||
109 | static inline int down_trylock(struct semaphore * sem) | ||
110 | { | ||
111 | register struct semaphore *sem1 __asm__ ("%a1") = sem; | ||
112 | register int result __asm__ ("%d0"); | ||
113 | |||
114 | __asm__ __volatile__( | ||
115 | "| atomic down trylock operation\n\t" | ||
116 | "subql #1,%1@\n\t" | ||
117 | "jmi 2f\n\t" | ||
118 | "clrl %0\n" | ||
119 | "1:\n" | ||
120 | ".section .text.lock,\"ax\"\n" | ||
121 | ".even\n" | ||
122 | "2:\tpea 1b\n\t" | ||
123 | "jbra __down_failed_trylock\n" | ||
124 | ".previous" | ||
125 | : "=d" (result) | ||
126 | : "a" (sem1) | ||
127 | : "memory"); | ||
128 | return result; | ||
129 | } | ||
130 | |||
131 | /* | ||
132 | * Note! This is subtle. We jump to wake people up only if | ||
133 | * the semaphore was negative (== somebody was waiting on it). | ||
134 | * The default case (no contention) will result in NO | ||
135 | * jumps for both down() and up(). | ||
136 | */ | ||
137 | static inline void up(struct semaphore * sem) | ||
138 | { | ||
139 | __asm__ __volatile__( | ||
140 | "| atomic up operation\n\t" | ||
141 | "movel %0, %%a1\n\t" | ||
142 | "lea %%pc@(1f), %%a0\n\t" | ||
143 | "addql #1, %%a1@\n\t" | ||
144 | "jle __up_wakeup\n" | ||
145 | "1:" | ||
146 | : /* no outputs */ | ||
147 | : "g" (sem) | ||
148 | : "cc", "%a0", "%a1", "memory"); | ||
149 | } | ||
150 | |||
151 | #endif /* __ASSEMBLY__ */ | ||
152 | |||
153 | #endif | ||
diff --git a/include/asm-mips/semaphore.h b/include/asm-mips/semaphore.h index fdf8042b784b..d9b2034ed1d2 100644 --- a/include/asm-mips/semaphore.h +++ b/include/asm-mips/semaphore.h | |||
@@ -1,108 +1 @@ | |||
1 | /* | #include <linux/semaphore.h> | |
2 | * This file is subject to the terms and conditions of the GNU General Public | ||
3 | * License. See the file "COPYING" in the main directory of this archive | ||
4 | * for more details. | ||
5 | * | ||
6 | * Copyright (C) 1996 Linus Torvalds | ||
7 | * Copyright (C) 1998, 99, 2000, 01, 04 Ralf Baechle | ||
8 | * Copyright (C) 1999, 2000, 01 Silicon Graphics, Inc. | ||
9 | * Copyright (C) 2000, 01 MIPS Technologies, Inc. | ||
10 | * | ||
11 | * In all honesty, little of the old MIPS code left - the PPC64 variant was | ||
12 | * just looking nice and portable so I ripped it. Credits to whoever wrote | ||
13 | * it. | ||
14 | */ | ||
15 | #ifndef __ASM_SEMAPHORE_H | ||
16 | #define __ASM_SEMAPHORE_H | ||
17 | |||
18 | /* | ||
19 | * Remove spinlock-based RW semaphores; RW semaphore definitions are | ||
20 | * now in rwsem.h and we use the generic lib/rwsem.c implementation. | ||
21 | * Rework semaphores to use atomic_dec_if_positive. | ||
22 | * -- Paul Mackerras (paulus@samba.org) | ||
23 | */ | ||
24 | |||
25 | #ifdef __KERNEL__ | ||
26 | |||
27 | #include <asm/atomic.h> | ||
28 | #include <asm/system.h> | ||
29 | #include <linux/wait.h> | ||
30 | #include <linux/rwsem.h> | ||
31 | |||
32 | struct semaphore { | ||
33 | /* | ||
34 | * Note that any negative value of count is equivalent to 0, | ||
35 | * but additionally indicates that some process(es) might be | ||
36 | * sleeping on `wait'. | ||
37 | */ | ||
38 | atomic_t count; | ||
39 | wait_queue_head_t wait; | ||
40 | }; | ||
41 | |||
42 | #define __SEMAPHORE_INITIALIZER(name, n) \ | ||
43 | { \ | ||
44 | .count = ATOMIC_INIT(n), \ | ||
45 | .wait = __WAIT_QUEUE_HEAD_INITIALIZER((name).wait) \ | ||
46 | } | ||
47 | |||
48 | #define __DECLARE_SEMAPHORE_GENERIC(name, count) \ | ||
49 | struct semaphore name = __SEMAPHORE_INITIALIZER(name, count) | ||
50 | |||
51 | #define DECLARE_MUTEX(name) __DECLARE_SEMAPHORE_GENERIC(name, 1) | ||
52 | |||
53 | static inline void sema_init(struct semaphore *sem, int val) | ||
54 | { | ||
55 | atomic_set(&sem->count, val); | ||
56 | init_waitqueue_head(&sem->wait); | ||
57 | } | ||
58 | |||
59 | static inline void init_MUTEX(struct semaphore *sem) | ||
60 | { | ||
61 | sema_init(sem, 1); | ||
62 | } | ||
63 | |||
64 | static inline void init_MUTEX_LOCKED(struct semaphore *sem) | ||
65 | { | ||
66 | sema_init(sem, 0); | ||
67 | } | ||
68 | |||
69 | extern void __down(struct semaphore * sem); | ||
70 | extern int __down_interruptible(struct semaphore * sem); | ||
71 | extern void __up(struct semaphore * sem); | ||
72 | |||
73 | static inline void down(struct semaphore * sem) | ||
74 | { | ||
75 | might_sleep(); | ||
76 | |||
77 | /* | ||
78 | * Try to get the semaphore, take the slow path if we fail. | ||
79 | */ | ||
80 | if (unlikely(atomic_dec_return(&sem->count) < 0)) | ||
81 | __down(sem); | ||
82 | } | ||
83 | |||
84 | static inline int down_interruptible(struct semaphore * sem) | ||
85 | { | ||
86 | int ret = 0; | ||
87 | |||
88 | might_sleep(); | ||
89 | |||
90 | if (unlikely(atomic_dec_return(&sem->count) < 0)) | ||
91 | ret = __down_interruptible(sem); | ||
92 | return ret; | ||
93 | } | ||
94 | |||
95 | static inline int down_trylock(struct semaphore * sem) | ||
96 | { | ||
97 | return atomic_dec_if_positive(&sem->count) < 0; | ||
98 | } | ||
99 | |||
100 | static inline void up(struct semaphore * sem) | ||
101 | { | ||
102 | if (unlikely(atomic_inc_return(&sem->count) <= 0)) | ||
103 | __up(sem); | ||
104 | } | ||
105 | |||
106 | #endif /* __KERNEL__ */ | ||
107 | |||
108 | #endif /* __ASM_SEMAPHORE_H */ | ||
diff --git a/include/asm-mn10300/semaphore.h b/include/asm-mn10300/semaphore.h index 5a9e1ad0b253..d9b2034ed1d2 100644 --- a/include/asm-mn10300/semaphore.h +++ b/include/asm-mn10300/semaphore.h | |||
@@ -1,169 +1 @@ | |||
1 | /* MN10300 Semaphores | #include <linux/semaphore.h> | |
2 | * | ||
3 | * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved. | ||
4 | * Written by David Howells (dhowells@redhat.com) | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or | ||
7 | * modify it under the terms of the GNU General Public Licence | ||
8 | * as published by the Free Software Foundation; either version | ||
9 | * 2 of the Licence, or (at your option) any later version. | ||
10 | */ | ||
11 | #ifndef _ASM_SEMAPHORE_H | ||
12 | #define _ASM_SEMAPHORE_H | ||
13 | |||
14 | #ifndef __ASSEMBLY__ | ||
15 | |||
16 | #include <linux/linkage.h> | ||
17 | #include <linux/wait.h> | ||
18 | #include <linux/spinlock.h> | ||
19 | #include <linux/rwsem.h> | ||
20 | |||
21 | #define SEMAPHORE_DEBUG 0 | ||
22 | |||
23 | /* | ||
24 | * the semaphore definition | ||
25 | * - if count is >0 then there are tokens available on the semaphore for down | ||
26 | * to collect | ||
27 | * - if count is <=0 then there are no spare tokens, and anyone that wants one | ||
28 | * must wait | ||
29 | * - if wait_list is not empty, then there are processes waiting for the | ||
30 | * semaphore | ||
31 | */ | ||
32 | struct semaphore { | ||
33 | atomic_t count; /* it's not really atomic, it's | ||
34 | * just that certain modules | ||
35 | * expect to be able to access | ||
36 | * it directly */ | ||
37 | spinlock_t wait_lock; | ||
38 | struct list_head wait_list; | ||
39 | #if SEMAPHORE_DEBUG | ||
40 | unsigned __magic; | ||
41 | #endif | ||
42 | }; | ||
43 | |||
44 | #if SEMAPHORE_DEBUG | ||
45 | # define __SEM_DEBUG_INIT(name) , (long)&(name).__magic | ||
46 | #else | ||
47 | # define __SEM_DEBUG_INIT(name) | ||
48 | #endif | ||
49 | |||
50 | |||
51 | #define __SEMAPHORE_INITIALIZER(name, init_count) \ | ||
52 | { \ | ||
53 | .count = ATOMIC_INIT(init_count), \ | ||
54 | .wait_lock = __SPIN_LOCK_UNLOCKED((name).wait_lock), \ | ||
55 | .wait_list = LIST_HEAD_INIT((name).wait_list) \ | ||
56 | __SEM_DEBUG_INIT(name) \ | ||
57 | } | ||
58 | |||
59 | #define __DECLARE_SEMAPHORE_GENERIC(name,count) \ | ||
60 | struct semaphore name = __SEMAPHORE_INITIALIZER(name, count) | ||
61 | |||
62 | #define DECLARE_MUTEX(name) __DECLARE_SEMAPHORE_GENERIC(name, 1) | ||
63 | #define DECLARE_MUTEX_LOCKED(name) __DECLARE_SEMAPHORE_GENERIC(name, 0) | ||
64 | |||
65 | static inline void sema_init(struct semaphore *sem, int val) | ||
66 | { | ||
67 | *sem = (struct semaphore) __SEMAPHORE_INITIALIZER(*sem, val); | ||
68 | } | ||
69 | |||
70 | static inline void init_MUTEX(struct semaphore *sem) | ||
71 | { | ||
72 | sema_init(sem, 1); | ||
73 | } | ||
74 | |||
75 | static inline void init_MUTEX_LOCKED(struct semaphore *sem) | ||
76 | { | ||
77 | sema_init(sem, 0); | ||
78 | } | ||
79 | |||
80 | extern void __down(struct semaphore *sem, unsigned long flags); | ||
81 | extern int __down_interruptible(struct semaphore *sem, unsigned long flags); | ||
82 | extern void __up(struct semaphore *sem); | ||
83 | |||
84 | static inline void down(struct semaphore *sem) | ||
85 | { | ||
86 | unsigned long flags; | ||
87 | int count; | ||
88 | |||
89 | #if SEMAPHORE_DEBUG | ||
90 | CHECK_MAGIC(sem->__magic); | ||
91 | #endif | ||
92 | |||
93 | spin_lock_irqsave(&sem->wait_lock, flags); | ||
94 | count = atomic_read(&sem->count); | ||
95 | if (likely(count > 0)) { | ||
96 | atomic_set(&sem->count, count - 1); | ||
97 | spin_unlock_irqrestore(&sem->wait_lock, flags); | ||
98 | } else { | ||
99 | __down(sem, flags); | ||
100 | } | ||
101 | } | ||
102 | |||
103 | static inline int down_interruptible(struct semaphore *sem) | ||
104 | { | ||
105 | unsigned long flags; | ||
106 | int count, ret = 0; | ||
107 | |||
108 | #if SEMAPHORE_DEBUG | ||
109 | CHECK_MAGIC(sem->__magic); | ||
110 | #endif | ||
111 | |||
112 | spin_lock_irqsave(&sem->wait_lock, flags); | ||
113 | count = atomic_read(&sem->count); | ||
114 | if (likely(count > 0)) { | ||
115 | atomic_set(&sem->count, count - 1); | ||
116 | spin_unlock_irqrestore(&sem->wait_lock, flags); | ||
117 | } else { | ||
118 | ret = __down_interruptible(sem, flags); | ||
119 | } | ||
120 | return ret; | ||
121 | } | ||
122 | |||
123 | /* | ||
124 | * non-blockingly attempt to down() a semaphore. | ||
125 | * - returns zero if we acquired it | ||
126 | */ | ||
127 | static inline int down_trylock(struct semaphore *sem) | ||
128 | { | ||
129 | unsigned long flags; | ||
130 | int count, success = 0; | ||
131 | |||
132 | #if SEMAPHORE_DEBUG | ||
133 | CHECK_MAGIC(sem->__magic); | ||
134 | #endif | ||
135 | |||
136 | spin_lock_irqsave(&sem->wait_lock, flags); | ||
137 | count = atomic_read(&sem->count); | ||
138 | if (likely(count > 0)) { | ||
139 | atomic_set(&sem->count, count - 1); | ||
140 | success = 1; | ||
141 | } | ||
142 | spin_unlock_irqrestore(&sem->wait_lock, flags); | ||
143 | return !success; | ||
144 | } | ||
145 | |||
146 | static inline void up(struct semaphore *sem) | ||
147 | { | ||
148 | unsigned long flags; | ||
149 | |||
150 | #if SEMAPHORE_DEBUG | ||
151 | CHECK_MAGIC(sem->__magic); | ||
152 | #endif | ||
153 | |||
154 | spin_lock_irqsave(&sem->wait_lock, flags); | ||
155 | if (!list_empty(&sem->wait_list)) | ||
156 | __up(sem); | ||
157 | else | ||
158 | atomic_set(&sem->count, atomic_read(&sem->count) + 1); | ||
159 | spin_unlock_irqrestore(&sem->wait_lock, flags); | ||
160 | } | ||
161 | |||
162 | static inline int sem_getcount(struct semaphore *sem) | ||
163 | { | ||
164 | return atomic_read(&sem->count); | ||
165 | } | ||
166 | |||
167 | #endif /* __ASSEMBLY__ */ | ||
168 | |||
169 | #endif | ||
diff --git a/include/asm-parisc/semaphore-helper.h b/include/asm-parisc/semaphore-helper.h deleted file mode 100644 index 387f7c1277a2..000000000000 --- a/include/asm-parisc/semaphore-helper.h +++ /dev/null | |||
@@ -1,89 +0,0 @@ | |||
1 | #ifndef _ASM_PARISC_SEMAPHORE_HELPER_H | ||
2 | #define _ASM_PARISC_SEMAPHORE_HELPER_H | ||
3 | |||
4 | /* | ||
5 | * SMP- and interrupt-safe semaphores helper functions. | ||
6 | * | ||
7 | * (C) Copyright 1996 Linus Torvalds | ||
8 | * (C) Copyright 1999 Andrea Arcangeli | ||
9 | */ | ||
10 | |||
11 | /* | ||
12 | * These two _must_ execute atomically wrt each other. | ||
13 | * | ||
14 | * This is trivially done with load_locked/store_cond, | ||
15 | * which we have. Let the rest of the losers suck eggs. | ||
16 | */ | ||
17 | static __inline__ void wake_one_more(struct semaphore * sem) | ||
18 | { | ||
19 | atomic_inc((atomic_t *)&sem->waking); | ||
20 | } | ||
21 | |||
22 | static __inline__ int waking_non_zero(struct semaphore *sem) | ||
23 | { | ||
24 | unsigned long flags; | ||
25 | int ret = 0; | ||
26 | |||
27 | spin_lock_irqsave(&semaphore_wake_lock, flags); | ||
28 | if (sem->waking > 0) { | ||
29 | sem->waking--; | ||
30 | ret = 1; | ||
31 | } | ||
32 | spin_unlock_irqrestore(&semaphore_wake_lock, flags); | ||
33 | return ret; | ||
34 | } | ||
35 | |||
36 | /* | ||
37 | * waking_non_zero_interruptible: | ||
38 | * 1 got the lock | ||
39 | * 0 go to sleep | ||
40 | * -EINTR interrupted | ||
41 | * | ||
42 | * We must undo the sem->count down_interruptible() increment while we are | ||
43 | * protected by the spinlock in order to make atomic this atomic_inc() with the | ||
44 | * atomic_read() in wake_one_more(), otherwise we can race. -arca | ||
45 | */ | ||
46 | static __inline__ int waking_non_zero_interruptible(struct semaphore *sem, | ||
47 | struct task_struct *tsk) | ||
48 | { | ||
49 | unsigned long flags; | ||
50 | int ret = 0; | ||
51 | |||
52 | spin_lock_irqsave(&semaphore_wake_lock, flags); | ||
53 | if (sem->waking > 0) { | ||
54 | sem->waking--; | ||
55 | ret = 1; | ||
56 | } else if (signal_pending(tsk)) { | ||
57 | atomic_inc(&sem->count); | ||
58 | ret = -EINTR; | ||
59 | } | ||
60 | spin_unlock_irqrestore(&semaphore_wake_lock, flags); | ||
61 | return ret; | ||
62 | } | ||
63 | |||
64 | /* | ||
65 | * waking_non_zero_trylock: | ||
66 | * 1 failed to lock | ||
67 | * 0 got the lock | ||
68 | * | ||
69 | * We must undo the sem->count down_trylock() increment while we are | ||
70 | * protected by the spinlock in order to make atomic this atomic_inc() with the | ||
71 | * atomic_read() in wake_one_more(), otherwise we can race. -arca | ||
72 | */ | ||
73 | static __inline__ int waking_non_zero_trylock(struct semaphore *sem) | ||
74 | { | ||
75 | unsigned long flags; | ||
76 | int ret = 1; | ||
77 | |||
78 | spin_lock_irqsave(&semaphore_wake_lock, flags); | ||
79 | if (sem->waking <= 0) | ||
80 | atomic_inc(&sem->count); | ||
81 | else { | ||
82 | sem->waking--; | ||
83 | ret = 0; | ||
84 | } | ||
85 | spin_unlock_irqrestore(&semaphore_wake_lock, flags); | ||
86 | return ret; | ||
87 | } | ||
88 | |||
89 | #endif /* _ASM_PARISC_SEMAPHORE_HELPER_H */ | ||
diff --git a/include/asm-parisc/semaphore.h b/include/asm-parisc/semaphore.h index a16271cdc748..d9b2034ed1d2 100644 --- a/include/asm-parisc/semaphore.h +++ b/include/asm-parisc/semaphore.h | |||
@@ -1,145 +1 @@ | |||
1 | /* SMP- and interrupt-safe semaphores. | #include <linux/semaphore.h> | |
2 | * PA-RISC version by Matthew Wilcox | ||
3 | * | ||
4 | * Linux/PA-RISC Project (http://www.parisc-linux.org/) | ||
5 | * Copyright (C) 1996 Linus Torvalds | ||
6 | * Copyright (C) 1999-2001 Matthew Wilcox < willy at debian d0T org > | ||
7 | * Copyright (C) 2000 Grant Grundler < grundler a debian org > | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify | ||
10 | * it under the terms of the GNU General Public License as published by | ||
11 | * the Free Software Foundation; either version 2 of the License, or | ||
12 | * (at your option) any later version. | ||
13 | * | ||
14 | * This program is distributed in the hope that it will be useful, | ||
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
17 | * GNU General Public License for more details. | ||
18 | * | ||
19 | * You should have received a copy of the GNU General Public License | ||
20 | * along with this program; if not, write to the Free Software | ||
21 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
22 | */ | ||
23 | |||
24 | #ifndef _ASM_PARISC_SEMAPHORE_H | ||
25 | #define _ASM_PARISC_SEMAPHORE_H | ||
26 | |||
27 | #include <linux/spinlock.h> | ||
28 | #include <linux/wait.h> | ||
29 | #include <linux/rwsem.h> | ||
30 | |||
31 | #include <asm/system.h> | ||
32 | |||
33 | /* | ||
34 | * The `count' is initialised to the number of people who are allowed to | ||
35 | * take the lock. (Normally we want a mutex, so this is `1'). if | ||
36 | * `count' is positive, the lock can be taken. if it's 0, no-one is | ||
37 | * waiting on it. if it's -1, at least one task is waiting. | ||
38 | */ | ||
39 | struct semaphore { | ||
40 | spinlock_t sentry; | ||
41 | int count; | ||
42 | wait_queue_head_t wait; | ||
43 | }; | ||
44 | |||
45 | #define __SEMAPHORE_INITIALIZER(name, n) \ | ||
46 | { \ | ||
47 | .sentry = SPIN_LOCK_UNLOCKED, \ | ||
48 | .count = n, \ | ||
49 | .wait = __WAIT_QUEUE_HEAD_INITIALIZER((name).wait) \ | ||
50 | } | ||
51 | |||
52 | #define __DECLARE_SEMAPHORE_GENERIC(name,count) \ | ||
53 | struct semaphore name = __SEMAPHORE_INITIALIZER(name,count) | ||
54 | |||
55 | #define DECLARE_MUTEX(name) __DECLARE_SEMAPHORE_GENERIC(name,1) | ||
56 | |||
57 | static inline void sema_init (struct semaphore *sem, int val) | ||
58 | { | ||
59 | *sem = (struct semaphore)__SEMAPHORE_INITIALIZER((*sem),val); | ||
60 | } | ||
61 | |||
62 | static inline void init_MUTEX (struct semaphore *sem) | ||
63 | { | ||
64 | sema_init(sem, 1); | ||
65 | } | ||
66 | |||
67 | static inline void init_MUTEX_LOCKED (struct semaphore *sem) | ||
68 | { | ||
69 | sema_init(sem, 0); | ||
70 | } | ||
71 | |||
72 | static inline int sem_getcount(struct semaphore *sem) | ||
73 | { | ||
74 | return sem->count; | ||
75 | } | ||
76 | |||
77 | asmlinkage void __down(struct semaphore * sem); | ||
78 | asmlinkage int __down_interruptible(struct semaphore * sem); | ||
79 | asmlinkage void __up(struct semaphore * sem); | ||
80 | |||
81 | /* Semaphores can be `tried' from irq context. So we have to disable | ||
82 | * interrupts while we're messing with the semaphore. Sorry. | ||
83 | */ | ||
84 | |||
85 | static inline void down(struct semaphore * sem) | ||
86 | { | ||
87 | might_sleep(); | ||
88 | spin_lock_irq(&sem->sentry); | ||
89 | if (sem->count > 0) { | ||
90 | sem->count--; | ||
91 | } else { | ||
92 | __down(sem); | ||
93 | } | ||
94 | spin_unlock_irq(&sem->sentry); | ||
95 | } | ||
96 | |||
97 | static inline int down_interruptible(struct semaphore * sem) | ||
98 | { | ||
99 | int ret = 0; | ||
100 | might_sleep(); | ||
101 | spin_lock_irq(&sem->sentry); | ||
102 | if (sem->count > 0) { | ||
103 | sem->count--; | ||
104 | } else { | ||
105 | ret = __down_interruptible(sem); | ||
106 | } | ||
107 | spin_unlock_irq(&sem->sentry); | ||
108 | return ret; | ||
109 | } | ||
110 | |||
111 | /* | ||
112 | * down_trylock returns 0 on success, 1 if we failed to get the lock. | ||
113 | * May not sleep, but must preserve irq state | ||
114 | */ | ||
115 | static inline int down_trylock(struct semaphore * sem) | ||
116 | { | ||
117 | unsigned long flags; | ||
118 | int count; | ||
119 | |||
120 | spin_lock_irqsave(&sem->sentry, flags); | ||
121 | count = sem->count - 1; | ||
122 | if (count >= 0) | ||
123 | sem->count = count; | ||
124 | spin_unlock_irqrestore(&sem->sentry, flags); | ||
125 | return (count < 0); | ||
126 | } | ||
127 | |||
128 | /* | ||
129 | * Note! This is subtle. We jump to wake people up only if | ||
130 | * the semaphore was negative (== somebody was waiting on it). | ||
131 | */ | ||
132 | static inline void up(struct semaphore * sem) | ||
133 | { | ||
134 | unsigned long flags; | ||
135 | |||
136 | spin_lock_irqsave(&sem->sentry, flags); | ||
137 | if (sem->count < 0) { | ||
138 | __up(sem); | ||
139 | } else { | ||
140 | sem->count++; | ||
141 | } | ||
142 | spin_unlock_irqrestore(&sem->sentry, flags); | ||
143 | } | ||
144 | |||
145 | #endif /* _ASM_PARISC_SEMAPHORE_H */ | ||
diff --git a/include/asm-powerpc/semaphore.h b/include/asm-powerpc/semaphore.h index 48dd32e07749..d9b2034ed1d2 100644 --- a/include/asm-powerpc/semaphore.h +++ b/include/asm-powerpc/semaphore.h | |||
@@ -1,94 +1 @@ | |||
1 | #ifndef _ASM_POWERPC_SEMAPHORE_H | #include <linux/semaphore.h> | |
2 | #define _ASM_POWERPC_SEMAPHORE_H | ||
3 | |||
4 | /* | ||
5 | * Remove spinlock-based RW semaphores; RW semaphore definitions are | ||
6 | * now in rwsem.h and we use the generic lib/rwsem.c implementation. | ||
7 | * Rework semaphores to use atomic_dec_if_positive. | ||
8 | * -- Paul Mackerras (paulus@samba.org) | ||
9 | */ | ||
10 | |||
11 | #ifdef __KERNEL__ | ||
12 | |||
13 | #include <asm/atomic.h> | ||
14 | #include <asm/system.h> | ||
15 | #include <linux/wait.h> | ||
16 | #include <linux/rwsem.h> | ||
17 | |||
18 | struct semaphore { | ||
19 | /* | ||
20 | * Note that any negative value of count is equivalent to 0, | ||
21 | * but additionally indicates that some process(es) might be | ||
22 | * sleeping on `wait'. | ||
23 | */ | ||
24 | atomic_t count; | ||
25 | wait_queue_head_t wait; | ||
26 | }; | ||
27 | |||
28 | #define __SEMAPHORE_INITIALIZER(name, n) \ | ||
29 | { \ | ||
30 | .count = ATOMIC_INIT(n), \ | ||
31 | .wait = __WAIT_QUEUE_HEAD_INITIALIZER((name).wait) \ | ||
32 | } | ||
33 | |||
34 | #define __DECLARE_SEMAPHORE_GENERIC(name, count) \ | ||
35 | struct semaphore name = __SEMAPHORE_INITIALIZER(name,count) | ||
36 | |||
37 | #define DECLARE_MUTEX(name) __DECLARE_SEMAPHORE_GENERIC(name, 1) | ||
38 | |||
39 | static inline void sema_init (struct semaphore *sem, int val) | ||
40 | { | ||
41 | atomic_set(&sem->count, val); | ||
42 | init_waitqueue_head(&sem->wait); | ||
43 | } | ||
44 | |||
45 | static inline void init_MUTEX (struct semaphore *sem) | ||
46 | { | ||
47 | sema_init(sem, 1); | ||
48 | } | ||
49 | |||
50 | static inline void init_MUTEX_LOCKED (struct semaphore *sem) | ||
51 | { | ||
52 | sema_init(sem, 0); | ||
53 | } | ||
54 | |||
55 | extern void __down(struct semaphore * sem); | ||
56 | extern int __down_interruptible(struct semaphore * sem); | ||
57 | extern void __up(struct semaphore * sem); | ||
58 | |||
59 | static inline void down(struct semaphore * sem) | ||
60 | { | ||
61 | might_sleep(); | ||
62 | |||
63 | /* | ||
64 | * Try to get the semaphore, take the slow path if we fail. | ||
65 | */ | ||
66 | if (unlikely(atomic_dec_return(&sem->count) < 0)) | ||
67 | __down(sem); | ||
68 | } | ||
69 | |||
70 | static inline int down_interruptible(struct semaphore * sem) | ||
71 | { | ||
72 | int ret = 0; | ||
73 | |||
74 | might_sleep(); | ||
75 | |||
76 | if (unlikely(atomic_dec_return(&sem->count) < 0)) | ||
77 | ret = __down_interruptible(sem); | ||
78 | return ret; | ||
79 | } | ||
80 | |||
81 | static inline int down_trylock(struct semaphore * sem) | ||
82 | { | ||
83 | return atomic_dec_if_positive(&sem->count) < 0; | ||
84 | } | ||
85 | |||
86 | static inline void up(struct semaphore * sem) | ||
87 | { | ||
88 | if (unlikely(atomic_inc_return(&sem->count) <= 0)) | ||
89 | __up(sem); | ||
90 | } | ||
91 | |||
92 | #endif /* __KERNEL__ */ | ||
93 | |||
94 | #endif /* _ASM_POWERPC_SEMAPHORE_H */ | ||
diff --git a/include/asm-s390/semaphore.h b/include/asm-s390/semaphore.h index 0e7001ad8392..d9b2034ed1d2 100644 --- a/include/asm-s390/semaphore.h +++ b/include/asm-s390/semaphore.h | |||
@@ -1,107 +1 @@ | |||
1 | /* | #include <linux/semaphore.h> | |
2 | * include/asm-s390/semaphore.h | ||
3 | * | ||
4 | * S390 version | ||
5 | * Copyright (C) 1999 IBM Deutschland Entwicklung GmbH, IBM Corporation | ||
6 | * | ||
7 | * Derived from "include/asm-i386/semaphore.h" | ||
8 | * (C) Copyright 1996 Linus Torvalds | ||
9 | */ | ||
10 | |||
11 | #ifndef _S390_SEMAPHORE_H | ||
12 | #define _S390_SEMAPHORE_H | ||
13 | |||
14 | #include <asm/system.h> | ||
15 | #include <asm/atomic.h> | ||
16 | #include <linux/wait.h> | ||
17 | #include <linux/rwsem.h> | ||
18 | |||
19 | struct semaphore { | ||
20 | /* | ||
21 | * Note that any negative value of count is equivalent to 0, | ||
22 | * but additionally indicates that some process(es) might be | ||
23 | * sleeping on `wait'. | ||
24 | */ | ||
25 | atomic_t count; | ||
26 | wait_queue_head_t wait; | ||
27 | }; | ||
28 | |||
29 | #define __SEMAPHORE_INITIALIZER(name,count) \ | ||
30 | { ATOMIC_INIT(count), __WAIT_QUEUE_HEAD_INITIALIZER((name).wait) } | ||
31 | |||
32 | #define __DECLARE_SEMAPHORE_GENERIC(name,count) \ | ||
33 | struct semaphore name = __SEMAPHORE_INITIALIZER(name,count) | ||
34 | |||
35 | #define DECLARE_MUTEX(name) __DECLARE_SEMAPHORE_GENERIC(name,1) | ||
36 | |||
37 | static inline void sema_init (struct semaphore *sem, int val) | ||
38 | { | ||
39 | atomic_set(&sem->count, val); | ||
40 | init_waitqueue_head(&sem->wait); | ||
41 | } | ||
42 | |||
43 | static inline void init_MUTEX (struct semaphore *sem) | ||
44 | { | ||
45 | sema_init(sem, 1); | ||
46 | } | ||
47 | |||
48 | static inline void init_MUTEX_LOCKED (struct semaphore *sem) | ||
49 | { | ||
50 | sema_init(sem, 0); | ||
51 | } | ||
52 | |||
53 | asmlinkage void __down(struct semaphore * sem); | ||
54 | asmlinkage int __down_interruptible(struct semaphore * sem); | ||
55 | asmlinkage int __down_trylock(struct semaphore * sem); | ||
56 | asmlinkage void __up(struct semaphore * sem); | ||
57 | |||
58 | static inline void down(struct semaphore * sem) | ||
59 | { | ||
60 | might_sleep(); | ||
61 | if (atomic_dec_return(&sem->count) < 0) | ||
62 | __down(sem); | ||
63 | } | ||
64 | |||
65 | static inline int down_interruptible(struct semaphore * sem) | ||
66 | { | ||
67 | int ret = 0; | ||
68 | |||
69 | might_sleep(); | ||
70 | if (atomic_dec_return(&sem->count) < 0) | ||
71 | ret = __down_interruptible(sem); | ||
72 | return ret; | ||
73 | } | ||
74 | |||
75 | static inline int down_trylock(struct semaphore * sem) | ||
76 | { | ||
77 | int old_val, new_val; | ||
78 | |||
79 | /* | ||
80 | * This inline assembly atomically implements the equivalent | ||
81 | * to the following C code: | ||
82 | * old_val = sem->count.counter; | ||
83 | * if ((new_val = old_val) > 0) | ||
84 | * sem->count.counter = --new_val; | ||
85 | * In the ppc code this is called atomic_dec_if_positive. | ||
86 | */ | ||
87 | asm volatile( | ||
88 | " l %0,0(%3)\n" | ||
89 | "0: ltr %1,%0\n" | ||
90 | " jle 1f\n" | ||
91 | " ahi %1,-1\n" | ||
92 | " cs %0,%1,0(%3)\n" | ||
93 | " jl 0b\n" | ||
94 | "1:" | ||
95 | : "=&d" (old_val), "=&d" (new_val), "=m" (sem->count.counter) | ||
96 | : "a" (&sem->count.counter), "m" (sem->count.counter) | ||
97 | : "cc", "memory"); | ||
98 | return old_val <= 0; | ||
99 | } | ||
100 | |||
101 | static inline void up(struct semaphore * sem) | ||
102 | { | ||
103 | if (atomic_inc_return(&sem->count) <= 0) | ||
104 | __up(sem); | ||
105 | } | ||
106 | |||
107 | #endif | ||
diff --git a/include/asm-sh/semaphore-helper.h b/include/asm-sh/semaphore-helper.h deleted file mode 100644 index bd8230c369ca..000000000000 --- a/include/asm-sh/semaphore-helper.h +++ /dev/null | |||
@@ -1,89 +0,0 @@ | |||
1 | #ifndef __ASM_SH_SEMAPHORE_HELPER_H | ||
2 | #define __ASM_SH_SEMAPHORE_HELPER_H | ||
3 | |||
4 | /* | ||
5 | * SMP- and interrupt-safe semaphores helper functions. | ||
6 | * | ||
7 | * (C) Copyright 1996 Linus Torvalds | ||
8 | * (C) Copyright 1999 Andrea Arcangeli | ||
9 | */ | ||
10 | |||
11 | /* | ||
12 | * These two _must_ execute atomically wrt each other. | ||
13 | * | ||
14 | * This is trivially done with load_locked/store_cond, | ||
15 | * which we have. Let the rest of the losers suck eggs. | ||
16 | */ | ||
17 | static __inline__ void wake_one_more(struct semaphore * sem) | ||
18 | { | ||
19 | atomic_inc((atomic_t *)&sem->sleepers); | ||
20 | } | ||
21 | |||
22 | static __inline__ int waking_non_zero(struct semaphore *sem) | ||
23 | { | ||
24 | unsigned long flags; | ||
25 | int ret = 0; | ||
26 | |||
27 | spin_lock_irqsave(&semaphore_wake_lock, flags); | ||
28 | if (sem->sleepers > 0) { | ||
29 | sem->sleepers--; | ||
30 | ret = 1; | ||
31 | } | ||
32 | spin_unlock_irqrestore(&semaphore_wake_lock, flags); | ||
33 | return ret; | ||
34 | } | ||
35 | |||
36 | /* | ||
37 | * waking_non_zero_interruptible: | ||
38 | * 1 got the lock | ||
39 | * 0 go to sleep | ||
40 | * -EINTR interrupted | ||
41 | * | ||
42 | * We must undo the sem->count down_interruptible() increment while we are | ||
43 | * protected by the spinlock in order to make atomic this atomic_inc() with the | ||
44 | * atomic_read() in wake_one_more(), otherwise we can race. -arca | ||
45 | */ | ||
46 | static __inline__ int waking_non_zero_interruptible(struct semaphore *sem, | ||
47 | struct task_struct *tsk) | ||
48 | { | ||
49 | unsigned long flags; | ||
50 | int ret = 0; | ||
51 | |||
52 | spin_lock_irqsave(&semaphore_wake_lock, flags); | ||
53 | if (sem->sleepers > 0) { | ||
54 | sem->sleepers--; | ||
55 | ret = 1; | ||
56 | } else if (signal_pending(tsk)) { | ||
57 | atomic_inc(&sem->count); | ||
58 | ret = -EINTR; | ||
59 | } | ||
60 | spin_unlock_irqrestore(&semaphore_wake_lock, flags); | ||
61 | return ret; | ||
62 | } | ||
63 | |||
64 | /* | ||
65 | * waking_non_zero_trylock: | ||
66 | * 1 failed to lock | ||
67 | * 0 got the lock | ||
68 | * | ||
69 | * We must undo the sem->count down_trylock() increment while we are | ||
70 | * protected by the spinlock in order to make atomic this atomic_inc() with the | ||
71 | * atomic_read() in wake_one_more(), otherwise we can race. -arca | ||
72 | */ | ||
73 | static __inline__ int waking_non_zero_trylock(struct semaphore *sem) | ||
74 | { | ||
75 | unsigned long flags; | ||
76 | int ret = 1; | ||
77 | |||
78 | spin_lock_irqsave(&semaphore_wake_lock, flags); | ||
79 | if (sem->sleepers <= 0) | ||
80 | atomic_inc(&sem->count); | ||
81 | else { | ||
82 | sem->sleepers--; | ||
83 | ret = 0; | ||
84 | } | ||
85 | spin_unlock_irqrestore(&semaphore_wake_lock, flags); | ||
86 | return ret; | ||
87 | } | ||
88 | |||
89 | #endif /* __ASM_SH_SEMAPHORE_HELPER_H */ | ||
diff --git a/include/asm-sh/semaphore.h b/include/asm-sh/semaphore.h index 9e5a37c4dce2..d9b2034ed1d2 100644 --- a/include/asm-sh/semaphore.h +++ b/include/asm-sh/semaphore.h | |||
@@ -1,115 +1 @@ | |||
1 | #ifndef __ASM_SH_SEMAPHORE_H | #include <linux/semaphore.h> | |
2 | #define __ASM_SH_SEMAPHORE_H | ||
3 | |||
4 | #include <linux/linkage.h> | ||
5 | |||
6 | #ifdef __KERNEL__ | ||
7 | /* | ||
8 | * SMP- and interrupt-safe semaphores. | ||
9 | * | ||
10 | * (C) Copyright 1996 Linus Torvalds | ||
11 | * | ||
12 | * SuperH verison by Niibe Yutaka | ||
13 | * (Currently no asm implementation but generic C code...) | ||
14 | */ | ||
15 | |||
16 | #include <linux/spinlock.h> | ||
17 | #include <linux/rwsem.h> | ||
18 | #include <linux/wait.h> | ||
19 | |||
20 | #include <asm/system.h> | ||
21 | #include <asm/atomic.h> | ||
22 | |||
23 | struct semaphore { | ||
24 | atomic_t count; | ||
25 | int sleepers; | ||
26 | wait_queue_head_t wait; | ||
27 | }; | ||
28 | |||
29 | #define __SEMAPHORE_INITIALIZER(name, n) \ | ||
30 | { \ | ||
31 | .count = ATOMIC_INIT(n), \ | ||
32 | .sleepers = 0, \ | ||
33 | .wait = __WAIT_QUEUE_HEAD_INITIALIZER((name).wait) \ | ||
34 | } | ||
35 | |||
36 | #define __DECLARE_SEMAPHORE_GENERIC(name,count) \ | ||
37 | struct semaphore name = __SEMAPHORE_INITIALIZER(name,count) | ||
38 | |||
39 | #define DECLARE_MUTEX(name) __DECLARE_SEMAPHORE_GENERIC(name,1) | ||
40 | |||
41 | static inline void sema_init (struct semaphore *sem, int val) | ||
42 | { | ||
43 | /* | ||
44 | * *sem = (struct semaphore)__SEMAPHORE_INITIALIZER((*sem),val); | ||
45 | * | ||
46 | * i'd rather use the more flexible initialization above, but sadly | ||
47 | * GCC 2.7.2.3 emits a bogus warning. EGCS doesn't. Oh well. | ||
48 | */ | ||
49 | atomic_set(&sem->count, val); | ||
50 | sem->sleepers = 0; | ||
51 | init_waitqueue_head(&sem->wait); | ||
52 | } | ||
53 | |||
54 | static inline void init_MUTEX (struct semaphore *sem) | ||
55 | { | ||
56 | sema_init(sem, 1); | ||
57 | } | ||
58 | |||
59 | static inline void init_MUTEX_LOCKED (struct semaphore *sem) | ||
60 | { | ||
61 | sema_init(sem, 0); | ||
62 | } | ||
63 | |||
64 | #if 0 | ||
65 | asmlinkage void __down_failed(void /* special register calling convention */); | ||
66 | asmlinkage int __down_failed_interruptible(void /* params in registers */); | ||
67 | asmlinkage int __down_failed_trylock(void /* params in registers */); | ||
68 | asmlinkage void __up_wakeup(void /* special register calling convention */); | ||
69 | #endif | ||
70 | |||
71 | asmlinkage void __down(struct semaphore * sem); | ||
72 | asmlinkage int __down_interruptible(struct semaphore * sem); | ||
73 | asmlinkage int __down_trylock(struct semaphore * sem); | ||
74 | asmlinkage void __up(struct semaphore * sem); | ||
75 | |||
76 | extern spinlock_t semaphore_wake_lock; | ||
77 | |||
78 | static inline void down(struct semaphore * sem) | ||
79 | { | ||
80 | might_sleep(); | ||
81 | if (atomic_dec_return(&sem->count) < 0) | ||
82 | __down(sem); | ||
83 | } | ||
84 | |||
85 | static inline int down_interruptible(struct semaphore * sem) | ||
86 | { | ||
87 | int ret = 0; | ||
88 | |||
89 | might_sleep(); | ||
90 | if (atomic_dec_return(&sem->count) < 0) | ||
91 | ret = __down_interruptible(sem); | ||
92 | return ret; | ||
93 | } | ||
94 | |||
95 | static inline int down_trylock(struct semaphore * sem) | ||
96 | { | ||
97 | int ret = 0; | ||
98 | |||
99 | if (atomic_dec_return(&sem->count) < 0) | ||
100 | ret = __down_trylock(sem); | ||
101 | return ret; | ||
102 | } | ||
103 | |||
104 | /* | ||
105 | * Note! This is subtle. We jump to wake people up only if | ||
106 | * the semaphore was negative (== somebody was waiting on it). | ||
107 | */ | ||
108 | static inline void up(struct semaphore * sem) | ||
109 | { | ||
110 | if (atomic_inc_return(&sem->count) <= 0) | ||
111 | __up(sem); | ||
112 | } | ||
113 | |||
114 | #endif | ||
115 | #endif /* __ASM_SH_SEMAPHORE_H */ | ||
diff --git a/include/asm-sparc/semaphore.h b/include/asm-sparc/semaphore.h index 8018f9f4d497..d9b2034ed1d2 100644 --- a/include/asm-sparc/semaphore.h +++ b/include/asm-sparc/semaphore.h | |||
@@ -1,192 +1 @@ | |||
1 | #ifndef _SPARC_SEMAPHORE_H | #include <linux/semaphore.h> | |
2 | #define _SPARC_SEMAPHORE_H | ||
3 | |||
4 | /* Dinky, good for nothing, just barely irq safe, Sparc semaphores. */ | ||
5 | |||
6 | #ifdef __KERNEL__ | ||
7 | |||
8 | #include <asm/atomic.h> | ||
9 | #include <linux/wait.h> | ||
10 | #include <linux/rwsem.h> | ||
11 | |||
12 | struct semaphore { | ||
13 | atomic24_t count; | ||
14 | int sleepers; | ||
15 | wait_queue_head_t wait; | ||
16 | }; | ||
17 | |||
18 | #define __SEMAPHORE_INITIALIZER(name, n) \ | ||
19 | { \ | ||
20 | .count = ATOMIC24_INIT(n), \ | ||
21 | .sleepers = 0, \ | ||
22 | .wait = __WAIT_QUEUE_HEAD_INITIALIZER((name).wait) \ | ||
23 | } | ||
24 | |||
25 | #define __DECLARE_SEMAPHORE_GENERIC(name,count) \ | ||
26 | struct semaphore name = __SEMAPHORE_INITIALIZER(name,count) | ||
27 | |||
28 | #define DECLARE_MUTEX(name) __DECLARE_SEMAPHORE_GENERIC(name,1) | ||
29 | |||
30 | static inline void sema_init (struct semaphore *sem, int val) | ||
31 | { | ||
32 | atomic24_set(&sem->count, val); | ||
33 | sem->sleepers = 0; | ||
34 | init_waitqueue_head(&sem->wait); | ||
35 | } | ||
36 | |||
37 | static inline void init_MUTEX (struct semaphore *sem) | ||
38 | { | ||
39 | sema_init(sem, 1); | ||
40 | } | ||
41 | |||
42 | static inline void init_MUTEX_LOCKED (struct semaphore *sem) | ||
43 | { | ||
44 | sema_init(sem, 0); | ||
45 | } | ||
46 | |||
47 | extern void __down(struct semaphore * sem); | ||
48 | extern int __down_interruptible(struct semaphore * sem); | ||
49 | extern int __down_trylock(struct semaphore * sem); | ||
50 | extern void __up(struct semaphore * sem); | ||
51 | |||
52 | static inline void down(struct semaphore * sem) | ||
53 | { | ||
54 | register volatile int *ptr asm("g1"); | ||
55 | register int increment asm("g2"); | ||
56 | |||
57 | might_sleep(); | ||
58 | |||
59 | ptr = &(sem->count.counter); | ||
60 | increment = 1; | ||
61 | |||
62 | __asm__ __volatile__( | ||
63 | "mov %%o7, %%g4\n\t" | ||
64 | "call ___atomic24_sub\n\t" | ||
65 | " add %%o7, 8, %%o7\n\t" | ||
66 | "tst %%g2\n\t" | ||
67 | "bl 2f\n\t" | ||
68 | " nop\n" | ||
69 | "1:\n\t" | ||
70 | ".subsection 2\n" | ||
71 | "2:\n\t" | ||
72 | "save %%sp, -64, %%sp\n\t" | ||
73 | "mov %%g1, %%l1\n\t" | ||
74 | "mov %%g5, %%l5\n\t" | ||
75 | "call %3\n\t" | ||
76 | " mov %%g1, %%o0\n\t" | ||
77 | "mov %%l1, %%g1\n\t" | ||
78 | "ba 1b\n\t" | ||
79 | " restore %%l5, %%g0, %%g5\n\t" | ||
80 | ".previous\n" | ||
81 | : "=&r" (increment) | ||
82 | : "0" (increment), "r" (ptr), "i" (__down) | ||
83 | : "g3", "g4", "g7", "memory", "cc"); | ||
84 | } | ||
85 | |||
86 | static inline int down_interruptible(struct semaphore * sem) | ||
87 | { | ||
88 | register volatile int *ptr asm("g1"); | ||
89 | register int increment asm("g2"); | ||
90 | |||
91 | might_sleep(); | ||
92 | |||
93 | ptr = &(sem->count.counter); | ||
94 | increment = 1; | ||
95 | |||
96 | __asm__ __volatile__( | ||
97 | "mov %%o7, %%g4\n\t" | ||
98 | "call ___atomic24_sub\n\t" | ||
99 | " add %%o7, 8, %%o7\n\t" | ||
100 | "tst %%g2\n\t" | ||
101 | "bl 2f\n\t" | ||
102 | " clr %%g2\n" | ||
103 | "1:\n\t" | ||
104 | ".subsection 2\n" | ||
105 | "2:\n\t" | ||
106 | "save %%sp, -64, %%sp\n\t" | ||
107 | "mov %%g1, %%l1\n\t" | ||
108 | "mov %%g5, %%l5\n\t" | ||
109 | "call %3\n\t" | ||
110 | " mov %%g1, %%o0\n\t" | ||
111 | "mov %%l1, %%g1\n\t" | ||
112 | "mov %%l5, %%g5\n\t" | ||
113 | "ba 1b\n\t" | ||
114 | " restore %%o0, %%g0, %%g2\n\t" | ||
115 | ".previous\n" | ||
116 | : "=&r" (increment) | ||
117 | : "0" (increment), "r" (ptr), "i" (__down_interruptible) | ||
118 | : "g3", "g4", "g7", "memory", "cc"); | ||
119 | |||
120 | return increment; | ||
121 | } | ||
122 | |||
123 | static inline int down_trylock(struct semaphore * sem) | ||
124 | { | ||
125 | register volatile int *ptr asm("g1"); | ||
126 | register int increment asm("g2"); | ||
127 | |||
128 | ptr = &(sem->count.counter); | ||
129 | increment = 1; | ||
130 | |||
131 | __asm__ __volatile__( | ||
132 | "mov %%o7, %%g4\n\t" | ||
133 | "call ___atomic24_sub\n\t" | ||
134 | " add %%o7, 8, %%o7\n\t" | ||
135 | "tst %%g2\n\t" | ||
136 | "bl 2f\n\t" | ||
137 | " clr %%g2\n" | ||
138 | "1:\n\t" | ||
139 | ".subsection 2\n" | ||
140 | "2:\n\t" | ||
141 | "save %%sp, -64, %%sp\n\t" | ||
142 | "mov %%g1, %%l1\n\t" | ||
143 | "mov %%g5, %%l5\n\t" | ||
144 | "call %3\n\t" | ||
145 | " mov %%g1, %%o0\n\t" | ||
146 | "mov %%l1, %%g1\n\t" | ||
147 | "mov %%l5, %%g5\n\t" | ||
148 | "ba 1b\n\t" | ||
149 | " restore %%o0, %%g0, %%g2\n\t" | ||
150 | ".previous\n" | ||
151 | : "=&r" (increment) | ||
152 | : "0" (increment), "r" (ptr), "i" (__down_trylock) | ||
153 | : "g3", "g4", "g7", "memory", "cc"); | ||
154 | |||
155 | return increment; | ||
156 | } | ||
157 | |||
158 | static inline void up(struct semaphore * sem) | ||
159 | { | ||
160 | register volatile int *ptr asm("g1"); | ||
161 | register int increment asm("g2"); | ||
162 | |||
163 | ptr = &(sem->count.counter); | ||
164 | increment = 1; | ||
165 | |||
166 | __asm__ __volatile__( | ||
167 | "mov %%o7, %%g4\n\t" | ||
168 | "call ___atomic24_add\n\t" | ||
169 | " add %%o7, 8, %%o7\n\t" | ||
170 | "tst %%g2\n\t" | ||
171 | "ble 2f\n\t" | ||
172 | " nop\n" | ||
173 | "1:\n\t" | ||
174 | ".subsection 2\n" | ||
175 | "2:\n\t" | ||
176 | "save %%sp, -64, %%sp\n\t" | ||
177 | "mov %%g1, %%l1\n\t" | ||
178 | "mov %%g5, %%l5\n\t" | ||
179 | "call %3\n\t" | ||
180 | " mov %%g1, %%o0\n\t" | ||
181 | "mov %%l1, %%g1\n\t" | ||
182 | "ba 1b\n\t" | ||
183 | " restore %%l5, %%g0, %%g5\n\t" | ||
184 | ".previous\n" | ||
185 | : "=&r" (increment) | ||
186 | : "0" (increment), "r" (ptr), "i" (__up) | ||
187 | : "g3", "g4", "g7", "memory", "cc"); | ||
188 | } | ||
189 | |||
190 | #endif /* __KERNEL__ */ | ||
191 | |||
192 | #endif /* !(_SPARC_SEMAPHORE_H) */ | ||
diff --git a/include/asm-sparc64/semaphore.h b/include/asm-sparc64/semaphore.h index 7f7c0c4e024f..d9b2034ed1d2 100644 --- a/include/asm-sparc64/semaphore.h +++ b/include/asm-sparc64/semaphore.h | |||
@@ -1,53 +1 @@ | |||
1 | #ifndef _SPARC64_SEMAPHORE_H | #include <linux/semaphore.h> | |
2 | #define _SPARC64_SEMAPHORE_H | ||
3 | |||
4 | /* These are actually reasonable on the V9. | ||
5 | * | ||
6 | * See asm-ppc/semaphore.h for implementation commentary, | ||
7 | * only sparc64 specific issues are commented here. | ||
8 | */ | ||
9 | #ifdef __KERNEL__ | ||
10 | |||
11 | #include <asm/atomic.h> | ||
12 | #include <asm/system.h> | ||
13 | #include <linux/wait.h> | ||
14 | #include <linux/rwsem.h> | ||
15 | |||
16 | struct semaphore { | ||
17 | atomic_t count; | ||
18 | wait_queue_head_t wait; | ||
19 | }; | ||
20 | |||
21 | #define __SEMAPHORE_INITIALIZER(name, count) \ | ||
22 | { ATOMIC_INIT(count), \ | ||
23 | __WAIT_QUEUE_HEAD_INITIALIZER((name).wait) } | ||
24 | |||
25 | #define __DECLARE_SEMAPHORE_GENERIC(name, count) \ | ||
26 | struct semaphore name = __SEMAPHORE_INITIALIZER(name,count) | ||
27 | |||
28 | #define DECLARE_MUTEX(name) __DECLARE_SEMAPHORE_GENERIC(name, 1) | ||
29 | |||
30 | static inline void sema_init (struct semaphore *sem, int val) | ||
31 | { | ||
32 | atomic_set(&sem->count, val); | ||
33 | init_waitqueue_head(&sem->wait); | ||
34 | } | ||
35 | |||
36 | static inline void init_MUTEX (struct semaphore *sem) | ||
37 | { | ||
38 | sema_init(sem, 1); | ||
39 | } | ||
40 | |||
41 | static inline void init_MUTEX_LOCKED (struct semaphore *sem) | ||
42 | { | ||
43 | sema_init(sem, 0); | ||
44 | } | ||
45 | |||
46 | extern void up(struct semaphore *sem); | ||
47 | extern void down(struct semaphore *sem); | ||
48 | extern int down_trylock(struct semaphore *sem); | ||
49 | extern int down_interruptible(struct semaphore *sem); | ||
50 | |||
51 | #endif /* __KERNEL__ */ | ||
52 | |||
53 | #endif /* !(_SPARC64_SEMAPHORE_H) */ | ||
diff --git a/include/asm-um/semaphore.h b/include/asm-um/semaphore.h index ff13c34de421..d9b2034ed1d2 100644 --- a/include/asm-um/semaphore.h +++ b/include/asm-um/semaphore.h | |||
@@ -1,6 +1 @@ | |||
1 | #ifndef __UM_SEMAPHORE_H | #include <linux/semaphore.h> | |
2 | #define __UM_SEMAPHORE_H | ||
3 | |||
4 | #include "asm/arch/semaphore.h" | ||
5 | |||
6 | #endif | ||
diff --git a/include/asm-v850/semaphore.h b/include/asm-v850/semaphore.h index 10ed0ccf37df..d9b2034ed1d2 100644 --- a/include/asm-v850/semaphore.h +++ b/include/asm-v850/semaphore.h | |||
@@ -1,84 +1 @@ | |||
1 | #ifndef __V850_SEMAPHORE_H__ | #include <linux/semaphore.h> | |
2 | #define __V850_SEMAPHORE_H__ | ||
3 | |||
4 | #include <linux/linkage.h> | ||
5 | #include <linux/spinlock.h> | ||
6 | #include <linux/wait.h> | ||
7 | #include <linux/rwsem.h> | ||
8 | |||
9 | #include <asm/atomic.h> | ||
10 | |||
11 | struct semaphore { | ||
12 | atomic_t count; | ||
13 | int sleepers; | ||
14 | wait_queue_head_t wait; | ||
15 | }; | ||
16 | |||
17 | #define __SEMAPHORE_INITIALIZER(name,count) \ | ||
18 | { ATOMIC_INIT (count), 0, \ | ||
19 | __WAIT_QUEUE_HEAD_INITIALIZER ((name).wait) } | ||
20 | |||
21 | #define __DECLARE_SEMAPHORE_GENERIC(name,count) \ | ||
22 | struct semaphore name = __SEMAPHORE_INITIALIZER (name,count) | ||
23 | |||
24 | #define DECLARE_MUTEX(name) __DECLARE_SEMAPHORE_GENERIC (name,1) | ||
25 | |||
26 | static inline void sema_init (struct semaphore *sem, int val) | ||
27 | { | ||
28 | *sem = (struct semaphore)__SEMAPHORE_INITIALIZER((*sem),val); | ||
29 | } | ||
30 | |||
31 | static inline void init_MUTEX (struct semaphore *sem) | ||
32 | { | ||
33 | sema_init (sem, 1); | ||
34 | } | ||
35 | |||
36 | static inline void init_MUTEX_LOCKED (struct semaphore *sem) | ||
37 | { | ||
38 | sema_init (sem, 0); | ||
39 | } | ||
40 | |||
41 | /* | ||
42 | * special register calling convention | ||
43 | */ | ||
44 | asmlinkage void __down_failed (void); | ||
45 | asmlinkage int __down_interruptible_failed (void); | ||
46 | asmlinkage int __down_trylock_failed (void); | ||
47 | asmlinkage void __up_wakeup (void); | ||
48 | |||
49 | extern void __down (struct semaphore * sem); | ||
50 | extern int __down_interruptible (struct semaphore * sem); | ||
51 | extern int __down_trylock (struct semaphore * sem); | ||
52 | extern void __up (struct semaphore * sem); | ||
53 | |||
54 | static inline void down (struct semaphore * sem) | ||
55 | { | ||
56 | might_sleep(); | ||
57 | if (atomic_dec_return (&sem->count) < 0) | ||
58 | __down (sem); | ||
59 | } | ||
60 | |||
61 | static inline int down_interruptible (struct semaphore * sem) | ||
62 | { | ||
63 | int ret = 0; | ||
64 | might_sleep(); | ||
65 | if (atomic_dec_return (&sem->count) < 0) | ||
66 | ret = __down_interruptible (sem); | ||
67 | return ret; | ||
68 | } | ||
69 | |||
70 | static inline int down_trylock (struct semaphore *sem) | ||
71 | { | ||
72 | int ret = 0; | ||
73 | if (atomic_dec_return (&sem->count) < 0) | ||
74 | ret = __down_trylock (sem); | ||
75 | return ret; | ||
76 | } | ||
77 | |||
78 | static inline void up (struct semaphore * sem) | ||
79 | { | ||
80 | if (atomic_inc_return (&sem->count) <= 0) | ||
81 | __up (sem); | ||
82 | } | ||
83 | |||
84 | #endif /* __V850_SEMAPHORE_H__ */ | ||
diff --git a/include/asm-x86/semaphore.h b/include/asm-x86/semaphore.h index 572c0b67a6b0..d9b2034ed1d2 100644 --- a/include/asm-x86/semaphore.h +++ b/include/asm-x86/semaphore.h | |||
@@ -1,5 +1 @@ | |||
1 | #ifdef CONFIG_X86_32 | #include <linux/semaphore.h> | |
2 | # include "semaphore_32.h" | ||
3 | #else | ||
4 | # include "semaphore_64.h" | ||
5 | #endif | ||
diff --git a/include/asm-x86/semaphore_32.h b/include/asm-x86/semaphore_32.h deleted file mode 100644 index ac96d3804d0c..000000000000 --- a/include/asm-x86/semaphore_32.h +++ /dev/null | |||
@@ -1,175 +0,0 @@ | |||
1 | #ifndef _I386_SEMAPHORE_H | ||
2 | #define _I386_SEMAPHORE_H | ||
3 | |||
4 | #include <linux/linkage.h> | ||
5 | |||
6 | #ifdef __KERNEL__ | ||
7 | |||
8 | /* | ||
9 | * SMP- and interrupt-safe semaphores.. | ||
10 | * | ||
11 | * (C) Copyright 1996 Linus Torvalds | ||
12 | * | ||
13 | * Modified 1996-12-23 by Dave Grothe <dave@gcom.com> to fix bugs in | ||
14 | * the original code and to make semaphore waits | ||
15 | * interruptible so that processes waiting on | ||
16 | * semaphores can be killed. | ||
17 | * Modified 1999-02-14 by Andrea Arcangeli, split the sched.c helper | ||
18 | * functions in asm/sempahore-helper.h while fixing a | ||
19 | * potential and subtle race discovered by Ulrich Schmid | ||
20 | * in down_interruptible(). Since I started to play here I | ||
21 | * also implemented the `trylock' semaphore operation. | ||
22 | * 1999-07-02 Artur Skawina <skawina@geocities.com> | ||
23 | * Optimized "0(ecx)" -> "(ecx)" (the assembler does not | ||
24 | * do this). Changed calling sequences from push/jmp to | ||
25 | * traditional call/ret. | ||
26 | * Modified 2001-01-01 Andreas Franck <afranck@gmx.de> | ||
27 | * Some hacks to ensure compatibility with recent | ||
28 | * GCC snapshots, to avoid stack corruption when compiling | ||
29 | * with -fomit-frame-pointer. It's not sure if this will | ||
30 | * be fixed in GCC, as our previous implementation was a | ||
31 | * bit dubious. | ||
32 | * | ||
33 | * If you would like to see an analysis of this implementation, please | ||
34 | * ftp to gcom.com and download the file | ||
35 | * /pub/linux/src/semaphore/semaphore-2.0.24.tar.gz. | ||
36 | * | ||
37 | */ | ||
38 | |||
39 | #include <asm/system.h> | ||
40 | #include <asm/atomic.h> | ||
41 | #include <linux/wait.h> | ||
42 | #include <linux/rwsem.h> | ||
43 | |||
44 | struct semaphore { | ||
45 | atomic_t count; | ||
46 | int sleepers; | ||
47 | wait_queue_head_t wait; | ||
48 | }; | ||
49 | |||
50 | |||
51 | #define __SEMAPHORE_INITIALIZER(name, n) \ | ||
52 | { \ | ||
53 | .count = ATOMIC_INIT(n), \ | ||
54 | .sleepers = 0, \ | ||
55 | .wait = __WAIT_QUEUE_HEAD_INITIALIZER((name).wait) \ | ||
56 | } | ||
57 | |||
58 | #define __DECLARE_SEMAPHORE_GENERIC(name,count) \ | ||
59 | struct semaphore name = __SEMAPHORE_INITIALIZER(name,count) | ||
60 | |||
61 | #define DECLARE_MUTEX(name) __DECLARE_SEMAPHORE_GENERIC(name,1) | ||
62 | |||
63 | static inline void sema_init (struct semaphore *sem, int val) | ||
64 | { | ||
65 | /* | ||
66 | * *sem = (struct semaphore)__SEMAPHORE_INITIALIZER((*sem),val); | ||
67 | * | ||
68 | * i'd rather use the more flexible initialization above, but sadly | ||
69 | * GCC 2.7.2.3 emits a bogus warning. EGCS doesn't. Oh well. | ||
70 | */ | ||
71 | atomic_set(&sem->count, val); | ||
72 | sem->sleepers = 0; | ||
73 | init_waitqueue_head(&sem->wait); | ||
74 | } | ||
75 | |||
76 | static inline void init_MUTEX (struct semaphore *sem) | ||
77 | { | ||
78 | sema_init(sem, 1); | ||
79 | } | ||
80 | |||
81 | static inline void init_MUTEX_LOCKED (struct semaphore *sem) | ||
82 | { | ||
83 | sema_init(sem, 0); | ||
84 | } | ||
85 | |||
86 | extern asmregparm void __down_failed(atomic_t *count_ptr); | ||
87 | extern asmregparm int __down_failed_interruptible(atomic_t *count_ptr); | ||
88 | extern asmregparm int __down_failed_trylock(atomic_t *count_ptr); | ||
89 | extern asmregparm void __up_wakeup(atomic_t *count_ptr); | ||
90 | |||
91 | /* | ||
92 | * This is ugly, but we want the default case to fall through. | ||
93 | * "__down_failed" is a special asm handler that calls the C | ||
94 | * routine that actually waits. See arch/i386/kernel/semaphore.c | ||
95 | */ | ||
96 | static inline void down(struct semaphore * sem) | ||
97 | { | ||
98 | might_sleep(); | ||
99 | __asm__ __volatile__( | ||
100 | "# atomic down operation\n\t" | ||
101 | LOCK_PREFIX "decl %0\n\t" /* --sem->count */ | ||
102 | "jns 2f\n" | ||
103 | "\tlea %0,%%eax\n\t" | ||
104 | "call __down_failed\n" | ||
105 | "2:" | ||
106 | :"+m" (sem->count) | ||
107 | : | ||
108 | :"memory","ax"); | ||
109 | } | ||
110 | |||
111 | /* | ||
112 | * Interruptible try to acquire a semaphore. If we obtained | ||
113 | * it, return zero. If we were interrupted, returns -EINTR | ||
114 | */ | ||
115 | static inline int down_interruptible(struct semaphore * sem) | ||
116 | { | ||
117 | int result; | ||
118 | |||
119 | might_sleep(); | ||
120 | __asm__ __volatile__( | ||
121 | "# atomic interruptible down operation\n\t" | ||
122 | "xorl %0,%0\n\t" | ||
123 | LOCK_PREFIX "decl %1\n\t" /* --sem->count */ | ||
124 | "jns 2f\n\t" | ||
125 | "lea %1,%%eax\n\t" | ||
126 | "call __down_failed_interruptible\n" | ||
127 | "2:" | ||
128 | :"=&a" (result), "+m" (sem->count) | ||
129 | : | ||
130 | :"memory"); | ||
131 | return result; | ||
132 | } | ||
133 | |||
134 | /* | ||
135 | * Non-blockingly attempt to down() a semaphore. | ||
136 | * Returns zero if we acquired it | ||
137 | */ | ||
138 | static inline int down_trylock(struct semaphore * sem) | ||
139 | { | ||
140 | int result; | ||
141 | |||
142 | __asm__ __volatile__( | ||
143 | "# atomic interruptible down operation\n\t" | ||
144 | "xorl %0,%0\n\t" | ||
145 | LOCK_PREFIX "decl %1\n\t" /* --sem->count */ | ||
146 | "jns 2f\n\t" | ||
147 | "lea %1,%%eax\n\t" | ||
148 | "call __down_failed_trylock\n\t" | ||
149 | "2:\n" | ||
150 | :"=&a" (result), "+m" (sem->count) | ||
151 | : | ||
152 | :"memory"); | ||
153 | return result; | ||
154 | } | ||
155 | |||
156 | /* | ||
157 | * Note! This is subtle. We jump to wake people up only if | ||
158 | * the semaphore was negative (== somebody was waiting on it). | ||
159 | */ | ||
160 | static inline void up(struct semaphore * sem) | ||
161 | { | ||
162 | __asm__ __volatile__( | ||
163 | "# atomic up operation\n\t" | ||
164 | LOCK_PREFIX "incl %0\n\t" /* ++sem->count */ | ||
165 | "jg 1f\n\t" | ||
166 | "lea %0,%%eax\n\t" | ||
167 | "call __up_wakeup\n" | ||
168 | "1:" | ||
169 | :"+m" (sem->count) | ||
170 | : | ||
171 | :"memory","ax"); | ||
172 | } | ||
173 | |||
174 | #endif | ||
175 | #endif | ||
diff --git a/include/asm-x86/semaphore_64.h b/include/asm-x86/semaphore_64.h deleted file mode 100644 index 79694306bf7d..000000000000 --- a/include/asm-x86/semaphore_64.h +++ /dev/null | |||
@@ -1,180 +0,0 @@ | |||
1 | #ifndef _X86_64_SEMAPHORE_H | ||
2 | #define _X86_64_SEMAPHORE_H | ||
3 | |||
4 | #include <linux/linkage.h> | ||
5 | |||
6 | #ifdef __KERNEL__ | ||
7 | |||
8 | /* | ||
9 | * SMP- and interrupt-safe semaphores.. | ||
10 | * | ||
11 | * (C) Copyright 1996 Linus Torvalds | ||
12 | * | ||
13 | * Modified 1996-12-23 by Dave Grothe <dave@gcom.com> to fix bugs in | ||
14 | * the original code and to make semaphore waits | ||
15 | * interruptible so that processes waiting on | ||
16 | * semaphores can be killed. | ||
17 | * Modified 1999-02-14 by Andrea Arcangeli, split the sched.c helper | ||
18 | * functions in asm/sempahore-helper.h while fixing a | ||
19 | * potential and subtle race discovered by Ulrich Schmid | ||
20 | * in down_interruptible(). Since I started to play here I | ||
21 | * also implemented the `trylock' semaphore operation. | ||
22 | * 1999-07-02 Artur Skawina <skawina@geocities.com> | ||
23 | * Optimized "0(ecx)" -> "(ecx)" (the assembler does not | ||
24 | * do this). Changed calling sequences from push/jmp to | ||
25 | * traditional call/ret. | ||
26 | * Modified 2001-01-01 Andreas Franck <afranck@gmx.de> | ||
27 | * Some hacks to ensure compatibility with recent | ||
28 | * GCC snapshots, to avoid stack corruption when compiling | ||
29 | * with -fomit-frame-pointer. It's not sure if this will | ||
30 | * be fixed in GCC, as our previous implementation was a | ||
31 | * bit dubious. | ||
32 | * | ||
33 | * If you would like to see an analysis of this implementation, please | ||
34 | * ftp to gcom.com and download the file | ||
35 | * /pub/linux/src/semaphore/semaphore-2.0.24.tar.gz. | ||
36 | * | ||
37 | */ | ||
38 | |||
39 | #include <asm/system.h> | ||
40 | #include <asm/atomic.h> | ||
41 | #include <asm/rwlock.h> | ||
42 | #include <linux/wait.h> | ||
43 | #include <linux/rwsem.h> | ||
44 | #include <linux/stringify.h> | ||
45 | |||
46 | struct semaphore { | ||
47 | atomic_t count; | ||
48 | int sleepers; | ||
49 | wait_queue_head_t wait; | ||
50 | }; | ||
51 | |||
52 | #define __SEMAPHORE_INITIALIZER(name, n) \ | ||
53 | { \ | ||
54 | .count = ATOMIC_INIT(n), \ | ||
55 | .sleepers = 0, \ | ||
56 | .wait = __WAIT_QUEUE_HEAD_INITIALIZER((name).wait) \ | ||
57 | } | ||
58 | |||
59 | #define __DECLARE_SEMAPHORE_GENERIC(name,count) \ | ||
60 | struct semaphore name = __SEMAPHORE_INITIALIZER(name,count) | ||
61 | |||
62 | #define DECLARE_MUTEX(name) __DECLARE_SEMAPHORE_GENERIC(name,1) | ||
63 | |||
64 | static inline void sema_init (struct semaphore *sem, int val) | ||
65 | { | ||
66 | /* | ||
67 | * *sem = (struct semaphore)__SEMAPHORE_INITIALIZER((*sem),val); | ||
68 | * | ||
69 | * i'd rather use the more flexible initialization above, but sadly | ||
70 | * GCC 2.7.2.3 emits a bogus warning. EGCS doesn't. Oh well. | ||
71 | */ | ||
72 | atomic_set(&sem->count, val); | ||
73 | sem->sleepers = 0; | ||
74 | init_waitqueue_head(&sem->wait); | ||
75 | } | ||
76 | |||
77 | static inline void init_MUTEX (struct semaphore *sem) | ||
78 | { | ||
79 | sema_init(sem, 1); | ||
80 | } | ||
81 | |||
82 | static inline void init_MUTEX_LOCKED (struct semaphore *sem) | ||
83 | { | ||
84 | sema_init(sem, 0); | ||
85 | } | ||
86 | |||
87 | asmlinkage void __down_failed(void /* special register calling convention */); | ||
88 | asmlinkage int __down_failed_interruptible(void /* params in registers */); | ||
89 | asmlinkage int __down_failed_trylock(void /* params in registers */); | ||
90 | asmlinkage void __up_wakeup(void /* special register calling convention */); | ||
91 | |||
92 | asmlinkage void __down(struct semaphore * sem); | ||
93 | asmlinkage int __down_interruptible(struct semaphore * sem); | ||
94 | asmlinkage int __down_trylock(struct semaphore * sem); | ||
95 | asmlinkage void __up(struct semaphore * sem); | ||
96 | |||
97 | /* | ||
98 | * This is ugly, but we want the default case to fall through. | ||
99 | * "__down_failed" is a special asm handler that calls the C | ||
100 | * routine that actually waits. See arch/x86_64/kernel/semaphore.c | ||
101 | */ | ||
102 | static inline void down(struct semaphore * sem) | ||
103 | { | ||
104 | might_sleep(); | ||
105 | |||
106 | __asm__ __volatile__( | ||
107 | "# atomic down operation\n\t" | ||
108 | LOCK_PREFIX "decl %0\n\t" /* --sem->count */ | ||
109 | "jns 1f\n\t" | ||
110 | "call __down_failed\n" | ||
111 | "1:" | ||
112 | :"=m" (sem->count) | ||
113 | :"D" (sem) | ||
114 | :"memory"); | ||
115 | } | ||
116 | |||
117 | /* | ||
118 | * Interruptible try to acquire a semaphore. If we obtained | ||
119 | * it, return zero. If we were interrupted, returns -EINTR | ||
120 | */ | ||
121 | static inline int down_interruptible(struct semaphore * sem) | ||
122 | { | ||
123 | int result; | ||
124 | |||
125 | might_sleep(); | ||
126 | |||
127 | __asm__ __volatile__( | ||
128 | "# atomic interruptible down operation\n\t" | ||
129 | "xorl %0,%0\n\t" | ||
130 | LOCK_PREFIX "decl %1\n\t" /* --sem->count */ | ||
131 | "jns 2f\n\t" | ||
132 | "call __down_failed_interruptible\n" | ||
133 | "2:\n" | ||
134 | :"=&a" (result), "=m" (sem->count) | ||
135 | :"D" (sem) | ||
136 | :"memory"); | ||
137 | return result; | ||
138 | } | ||
139 | |||
140 | /* | ||
141 | * Non-blockingly attempt to down() a semaphore. | ||
142 | * Returns zero if we acquired it | ||
143 | */ | ||
144 | static inline int down_trylock(struct semaphore * sem) | ||
145 | { | ||
146 | int result; | ||
147 | |||
148 | __asm__ __volatile__( | ||
149 | "# atomic interruptible down operation\n\t" | ||
150 | "xorl %0,%0\n\t" | ||
151 | LOCK_PREFIX "decl %1\n\t" /* --sem->count */ | ||
152 | "jns 2f\n\t" | ||
153 | "call __down_failed_trylock\n\t" | ||
154 | "2:\n" | ||
155 | :"=&a" (result), "=m" (sem->count) | ||
156 | :"D" (sem) | ||
157 | :"memory","cc"); | ||
158 | return result; | ||
159 | } | ||
160 | |||
161 | /* | ||
162 | * Note! This is subtle. We jump to wake people up only if | ||
163 | * the semaphore was negative (== somebody was waiting on it). | ||
164 | * The default case (no contention) will result in NO | ||
165 | * jumps for both down() and up(). | ||
166 | */ | ||
167 | static inline void up(struct semaphore * sem) | ||
168 | { | ||
169 | __asm__ __volatile__( | ||
170 | "# atomic up operation\n\t" | ||
171 | LOCK_PREFIX "incl %0\n\t" /* ++sem->count */ | ||
172 | "jg 1f\n\t" | ||
173 | "call __up_wakeup\n" | ||
174 | "1:" | ||
175 | :"=m" (sem->count) | ||
176 | :"D" (sem) | ||
177 | :"memory"); | ||
178 | } | ||
179 | #endif /* __KERNEL__ */ | ||
180 | #endif | ||
diff --git a/include/asm-xtensa/semaphore.h b/include/asm-xtensa/semaphore.h index 3e04167cd9dc..d9b2034ed1d2 100644 --- a/include/asm-xtensa/semaphore.h +++ b/include/asm-xtensa/semaphore.h | |||
@@ -1,99 +1 @@ | |||
1 | /* | #include <linux/semaphore.h> | |
2 | * linux/include/asm-xtensa/semaphore.h | ||
3 | * | ||
4 | * This file is subject to the terms and conditions of the GNU General Public | ||
5 | * License. See the file "COPYING" in the main directory of this archive | ||
6 | * for more details. | ||
7 | * | ||
8 | * Copyright (C) 2001 - 2005 Tensilica Inc. | ||
9 | */ | ||
10 | |||
11 | #ifndef _XTENSA_SEMAPHORE_H | ||
12 | #define _XTENSA_SEMAPHORE_H | ||
13 | |||
14 | #include <asm/atomic.h> | ||
15 | #include <asm/system.h> | ||
16 | #include <linux/wait.h> | ||
17 | #include <linux/rwsem.h> | ||
18 | |||
19 | struct semaphore { | ||
20 | atomic_t count; | ||
21 | int sleepers; | ||
22 | wait_queue_head_t wait; | ||
23 | }; | ||
24 | |||
25 | #define __SEMAPHORE_INITIALIZER(name,n) \ | ||
26 | { \ | ||
27 | .count = ATOMIC_INIT(n), \ | ||
28 | .sleepers = 0, \ | ||
29 | .wait = __WAIT_QUEUE_HEAD_INITIALIZER((name).wait) \ | ||
30 | } | ||
31 | |||
32 | #define __DECLARE_SEMAPHORE_GENERIC(name,count) \ | ||
33 | struct semaphore name = __SEMAPHORE_INITIALIZER(name,count) | ||
34 | |||
35 | #define DECLARE_MUTEX(name) __DECLARE_SEMAPHORE_GENERIC(name,1) | ||
36 | |||
37 | static inline void sema_init (struct semaphore *sem, int val) | ||
38 | { | ||
39 | atomic_set(&sem->count, val); | ||
40 | sem->sleepers = 0; | ||
41 | init_waitqueue_head(&sem->wait); | ||
42 | } | ||
43 | |||
44 | static inline void init_MUTEX (struct semaphore *sem) | ||
45 | { | ||
46 | sema_init(sem, 1); | ||
47 | } | ||
48 | |||
49 | static inline void init_MUTEX_LOCKED (struct semaphore *sem) | ||
50 | { | ||
51 | sema_init(sem, 0); | ||
52 | } | ||
53 | |||
54 | asmlinkage void __down(struct semaphore * sem); | ||
55 | asmlinkage int __down_interruptible(struct semaphore * sem); | ||
56 | asmlinkage int __down_trylock(struct semaphore * sem); | ||
57 | asmlinkage void __up(struct semaphore * sem); | ||
58 | |||
59 | extern spinlock_t semaphore_wake_lock; | ||
60 | |||
61 | static inline void down(struct semaphore * sem) | ||
62 | { | ||
63 | might_sleep(); | ||
64 | |||
65 | if (atomic_sub_return(1, &sem->count) < 0) | ||
66 | __down(sem); | ||
67 | } | ||
68 | |||
69 | static inline int down_interruptible(struct semaphore * sem) | ||
70 | { | ||
71 | int ret = 0; | ||
72 | |||
73 | might_sleep(); | ||
74 | |||
75 | if (atomic_sub_return(1, &sem->count) < 0) | ||
76 | ret = __down_interruptible(sem); | ||
77 | return ret; | ||
78 | } | ||
79 | |||
80 | static inline int down_trylock(struct semaphore * sem) | ||
81 | { | ||
82 | int ret = 0; | ||
83 | |||
84 | if (atomic_sub_return(1, &sem->count) < 0) | ||
85 | ret = __down_trylock(sem); | ||
86 | return ret; | ||
87 | } | ||
88 | |||
89 | /* | ||
90 | * Note! This is subtle. We jump to wake people up only if | ||
91 | * the semaphore was negative (== somebody was waiting on it). | ||
92 | */ | ||
93 | static inline void up(struct semaphore * sem) | ||
94 | { | ||
95 | if (atomic_add_return(1, &sem->count) <= 0) | ||
96 | __up(sem); | ||
97 | } | ||
98 | |||
99 | #endif /* _XTENSA_SEMAPHORE_H */ | ||
diff --git a/include/linux/semaphore.h b/include/linux/semaphore.h new file mode 100644 index 000000000000..b3c691b089b2 --- /dev/null +++ b/include/linux/semaphore.h | |||
@@ -0,0 +1,77 @@ | |||
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 */ | ||