diff options
Diffstat (limited to 'lib/rwsem-spinlock.c')
-rw-r--r-- | lib/rwsem-spinlock.c | 37 |
1 files changed, 22 insertions, 15 deletions
diff --git a/lib/rwsem-spinlock.c b/lib/rwsem-spinlock.c index 9df3ca56db11..ffc9fc7f3b05 100644 --- a/lib/rwsem-spinlock.c +++ b/lib/rwsem-spinlock.c | |||
@@ -17,6 +17,19 @@ struct rwsem_waiter { | |||
17 | #define RWSEM_WAITING_FOR_WRITE 0x00000002 | 17 | #define RWSEM_WAITING_FOR_WRITE 0x00000002 |
18 | }; | 18 | }; |
19 | 19 | ||
20 | int rwsem_is_locked(struct rw_semaphore *sem) | ||
21 | { | ||
22 | int ret = 1; | ||
23 | unsigned long flags; | ||
24 | |||
25 | if (spin_trylock_irqsave(&sem->wait_lock, flags)) { | ||
26 | ret = (sem->activity != 0); | ||
27 | spin_unlock_irqrestore(&sem->wait_lock, flags); | ||
28 | } | ||
29 | return ret; | ||
30 | } | ||
31 | EXPORT_SYMBOL(rwsem_is_locked); | ||
32 | |||
20 | /* | 33 | /* |
21 | * initialise the semaphore | 34 | * initialise the semaphore |
22 | */ | 35 | */ |
@@ -34,6 +47,7 @@ void __init_rwsem(struct rw_semaphore *sem, const char *name, | |||
34 | spin_lock_init(&sem->wait_lock); | 47 | spin_lock_init(&sem->wait_lock); |
35 | INIT_LIST_HEAD(&sem->wait_list); | 48 | INIT_LIST_HEAD(&sem->wait_list); |
36 | } | 49 | } |
50 | EXPORT_SYMBOL(__init_rwsem); | ||
37 | 51 | ||
38 | /* | 52 | /* |
39 | * handle the lock release when processes blocked on it that can now run | 53 | * handle the lock release when processes blocked on it that can now run |
@@ -129,13 +143,14 @@ void __sched __down_read(struct rw_semaphore *sem) | |||
129 | { | 143 | { |
130 | struct rwsem_waiter waiter; | 144 | struct rwsem_waiter waiter; |
131 | struct task_struct *tsk; | 145 | struct task_struct *tsk; |
146 | unsigned long flags; | ||
132 | 147 | ||
133 | spin_lock_irq(&sem->wait_lock); | 148 | spin_lock_irqsave(&sem->wait_lock, flags); |
134 | 149 | ||
135 | if (sem->activity >= 0 && list_empty(&sem->wait_list)) { | 150 | if (sem->activity >= 0 && list_empty(&sem->wait_list)) { |
136 | /* granted */ | 151 | /* granted */ |
137 | sem->activity++; | 152 | sem->activity++; |
138 | spin_unlock_irq(&sem->wait_lock); | 153 | spin_unlock_irqrestore(&sem->wait_lock, flags); |
139 | goto out; | 154 | goto out; |
140 | } | 155 | } |
141 | 156 | ||
@@ -150,7 +165,7 @@ void __sched __down_read(struct rw_semaphore *sem) | |||
150 | list_add_tail(&waiter.list, &sem->wait_list); | 165 | list_add_tail(&waiter.list, &sem->wait_list); |
151 | 166 | ||
152 | /* we don't need to touch the semaphore struct anymore */ | 167 | /* we don't need to touch the semaphore struct anymore */ |
153 | spin_unlock_irq(&sem->wait_lock); | 168 | spin_unlock_irqrestore(&sem->wait_lock, flags); |
154 | 169 | ||
155 | /* wait to be given the lock */ | 170 | /* wait to be given the lock */ |
156 | for (;;) { | 171 | for (;;) { |
@@ -195,13 +210,14 @@ void __sched __down_write_nested(struct rw_semaphore *sem, int subclass) | |||
195 | { | 210 | { |
196 | struct rwsem_waiter waiter; | 211 | struct rwsem_waiter waiter; |
197 | struct task_struct *tsk; | 212 | struct task_struct *tsk; |
213 | unsigned long flags; | ||
198 | 214 | ||
199 | spin_lock_irq(&sem->wait_lock); | 215 | spin_lock_irqsave(&sem->wait_lock, flags); |
200 | 216 | ||
201 | if (sem->activity == 0 && list_empty(&sem->wait_list)) { | 217 | if (sem->activity == 0 && list_empty(&sem->wait_list)) { |
202 | /* granted */ | 218 | /* granted */ |
203 | sem->activity = -1; | 219 | sem->activity = -1; |
204 | spin_unlock_irq(&sem->wait_lock); | 220 | spin_unlock_irqrestore(&sem->wait_lock, flags); |
205 | goto out; | 221 | goto out; |
206 | } | 222 | } |
207 | 223 | ||
@@ -216,7 +232,7 @@ void __sched __down_write_nested(struct rw_semaphore *sem, int subclass) | |||
216 | list_add_tail(&waiter.list, &sem->wait_list); | 232 | list_add_tail(&waiter.list, &sem->wait_list); |
217 | 233 | ||
218 | /* we don't need to touch the semaphore struct anymore */ | 234 | /* we don't need to touch the semaphore struct anymore */ |
219 | spin_unlock_irq(&sem->wait_lock); | 235 | spin_unlock_irqrestore(&sem->wait_lock, flags); |
220 | 236 | ||
221 | /* wait to be given the lock */ | 237 | /* wait to be given the lock */ |
222 | for (;;) { | 238 | for (;;) { |
@@ -305,12 +321,3 @@ void __downgrade_write(struct rw_semaphore *sem) | |||
305 | spin_unlock_irqrestore(&sem->wait_lock, flags); | 321 | spin_unlock_irqrestore(&sem->wait_lock, flags); |
306 | } | 322 | } |
307 | 323 | ||
308 | EXPORT_SYMBOL(__init_rwsem); | ||
309 | EXPORT_SYMBOL(__down_read); | ||
310 | EXPORT_SYMBOL(__down_read_trylock); | ||
311 | EXPORT_SYMBOL(__down_write_nested); | ||
312 | EXPORT_SYMBOL(__down_write); | ||
313 | EXPORT_SYMBOL(__down_write_trylock); | ||
314 | EXPORT_SYMBOL(__up_read); | ||
315 | EXPORT_SYMBOL(__up_write); | ||
316 | EXPORT_SYMBOL(__downgrade_write); | ||