[parisc-linux-cvs] Semaphore rewrite
Matthew Wilcox
willy@ldl.fc.hp.com
Fri, 16 Mar 2001 21:33:17 -0700
Here's the rewrite of the implementation I described earlier. It now
survives pipetest.c. go forth and celebrate. Thanks to paul for writing
the pipetest program.
Index: arch/parisc/kernel/semaphore.c
===================================================================
RCS file: /home/cvs/parisc/linux/arch/parisc/kernel/semaphore.c,v
retrieving revision 1.6
diff -u -p -r1.6 semaphore.c
--- semaphore.c 2001/02/16 17:10:55 1.6
+++ semaphore.c 2001/03/17 04:20:19
@@ -34,6 +34,7 @@
*/
void __up(struct semaphore *sem)
{
+ sem->count--;
wake_up(&sem->wait);
}
@@ -47,17 +48,20 @@ void __up(struct semaphore *sem)
/* protected by the sentry still -- use unlocked version */ \
wait.flags = WQ_FLAG_EXCLUSIVE; \
__add_wait_queue_tail(&sem->wait, &wait); \
-lost_race: \
+ lost_race: \
spin_unlock_irq(&sem->sentry); \
#define DOWN_TAIL \
spin_lock_irq(&sem->sentry); \
- if (sem->count < 0) \
- goto lost_race; \
+ if (sem->count == -1) \
+ goto lost_race; /* Someone stole our wakeup */ \
__remove_wait_queue(&sem->wait, &wait); \
current->state = TASK_RUNNING; \
- if (!waitqueue_active(&sem->wait)) \
- sem->count = 1;
+ if (!waitqueue_active(&sem->wait)) { \
+ sem->count = 0; \
+ } else { \
+ sem->count += 1; \
+ }
void __down(struct semaphore * sem)
{
@@ -66,7 +70,7 @@ void __down(struct semaphore * sem)
for(;;) {
set_task_state(current, TASK_UNINTERRUPTIBLE);
/* we can _read_ this without the sentry */
- if (sem->count >= 0)
+ if (sem->count != -1)
break;
schedule();
}
@@ -83,7 +87,7 @@ int __down_interruptible(struct semaphor
for(;;) {
set_task_state(current, TASK_INTERRUPTIBLE);
/* we can _read_ this without the sentry */
- if (sem->count >= 0)
+ if (sem->count != -1)
break;
if (signal_pending(current)) {
Index: include/asm-parisc/semaphore.h
===================================================================
RCS file: /home/cvs/parisc/linux/include/asm-parisc/semaphore.h,v
retrieving revision 1.6
diff -u -p -r1.6 semaphore.h
--- semaphore.h 2001/02/16 02:53:30 1.6
+++ semaphore.h 2001/03/17 04:23:16
@@ -68,7 +68,7 @@ asmlinkage void __down(struct semaphore
asmlinkage int __down_interruptible(struct semaphore * sem);
asmlinkage void __up(struct semaphore * sem);
-/* Sempahores can be `tried' from irq context. So we have to disable
+/* Semaphores can be `tried' from irq context. So we have to disable
* interrupts while we're messing with the semaphore. Sorry.
*/
@@ -131,8 +131,11 @@ extern __inline__ void up(struct semapho
CHECK_MAGIC(sem->__magic);
#endif
spin_lock_irqsave(&sem->sentry, flags);
- if (++sem->count <= 0)
+ if (sem->count < 0) {
__up(sem);
+ } else {
+ sem->count++;
+ }
spin_unlock_irqrestore(&sem->sentry, flags);
}