|
From: Kenn H. <ke...@us...> - 2001-01-29 00:47:50
|
Update of /cvsroot/linux-vax/kernel-2.4/include/asm-vax
In directory usw-pr-cvs1:/tmp/cvs-serv26415
Modified Files:
semaphore-helper.h semaphore.h
Log Message:
Rather than fight with the current VAX versions of semaphore.h and
semaphore-helper.h (which seemed to have rotted quite a bit), I just
took a look at the S390 implementations. The S390 files didn't have
any platform-specific bits, so I've just stolen them en masse. As
long as we get the atomic_xxx operations sorted, it should work OK.
Index: semaphore-helper.h
===================================================================
RCS file: /cvsroot/linux-vax/kernel-2.4/include/asm-vax/semaphore-helper.h,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- semaphore-helper.h 2001/01/17 16:18:52 1.1
+++ semaphore-helper.h 2001/01/29 00:47:41 1.2
@@ -1,13 +1,19 @@
-#ifndef _VAX_SEMAPHORE_HELPER_H
-#define _VAX_SEMAPHORE_HELPER_H
-
/*
- * SMP- and interrupt-safe semaphores helper functions.
+ * $Id$
+ *
+ * VAX version based on S390 version
*
- * (C) Copyright 1996 Linus Torvalds
- * (C) Copyright 1999 Andrea Arcangeli
+ * S390 version
+ * Copyright (C) 1999 IBM Deutschland Entwicklung GmbH, IBM Corporation
+ *
+ * Derived from "include/asm-i386/semaphore-helper.h"
+ * (C) Copyright 1996 Linus Torvalds
+ * (C) Copyright 1999 Andrea Arcangeli
*/
+#ifndef _VAX_SEMAPHORE_HELPER_H
+#define _VAX_SEMAPHORE_HELPER_H
+
/*
* These two _must_ execute atomically wrt each other.
*
@@ -19,34 +25,12 @@
unsigned long flags;
spin_lock_irqsave(&semaphore_wake_lock, flags);
- if (atomic_read(&sem->count) <= 0)
- sem->waking++;
+ sem->waking++;
spin_unlock_irqrestore(&semaphore_wake_lock, flags);
}
static inline int waking_non_zero(struct semaphore *sem)
{
- int ret;
- /* FIXME: use interlocked instructions (ADAWI, atp 1998) */
- __asm__ __volatile__(
- "S1: movl %1,%0\n"
- " tstl %0\n"
- " beql S2\n"
- " decl %1\n"
- "S2:"
- : "=r" (ret)
- : "r" (&sem->waking)
- : "r0", "memory");
-
- return ret;
-}
-
-/* FIXME: this is the original, is the above equivalent? It was in Nov 98,
- * but this has changed recently
- */
-/*
-static inline int waking_non_zero(struct semaphore *sem)
-{
unsigned long flags;
int ret = 0;
@@ -58,16 +42,18 @@
spin_unlock_irqrestore(&semaphore_wake_lock, flags);
return ret;
}
-*/
+
/*
* waking_non_zero_interruptible:
* 1 got the lock
* 0 go to sleep
* -EINTR interrupted
*
- * We must undo the sem->count down_interruptible() increment while we are
- * protected by the spinlock in order to make atomic this atomic_inc() with the
- * atomic_read() in wake_one_more(), otherwise we can race. -arca
+ * If we give up we must undo our count-decrease we previously did in down().
+ * Subtle: up() can continue to happens and increase the semaphore count
+ * even during our critical section protected by the spinlock. So
+ * we must remeber to undo the sem->waking that will be run from
+ * wake_one_more() some time soon, if the semaphore count become > 0.
*/
static inline int waking_non_zero_interruptible(struct semaphore *sem,
struct task_struct *tsk)
@@ -80,7 +66,8 @@
sem->waking--;
ret = 1;
} else if (signal_pending(tsk)) {
- atomic_inc(&sem->count);
+ if (atomic_inc_and_test_greater_zero(&sem->count))
+ sem->waking--;
ret = -EINTR;
}
spin_unlock_irqrestore(&semaphore_wake_lock, flags);
@@ -92,9 +79,7 @@
* 1 failed to lock
* 0 got the lock
*
- * We must undo the sem->count down_trylock() increment while we are
- * protected by the spinlock in order to make atomic this atomic_inc() with the
- * atomic_read() in wake_one_more(), otherwise we can race. -arca
+ * Implementation details are the same of the interruptible case.
*/
static inline int waking_non_zero_trylock(struct semaphore *sem)
{
@@ -103,13 +88,16 @@
spin_lock_irqsave(&semaphore_wake_lock, flags);
if (sem->waking <= 0)
- atomic_inc(&sem->count);
- else {
+ {
+ if (atomic_inc_and_test_greater_zero(&sem->count))
+ sem->waking--;
+ } else {
sem->waking--;
ret = 0;
}
spin_unlock_irqrestore(&semaphore_wake_lock, flags);
return ret;
}
+
+#endif /* _VAX_SEMAPHORE_HELPER_H */
-#endif
Index: semaphore.h
===================================================================
RCS file: /cvsroot/linux-vax/kernel-2.4/include/asm-vax/semaphore.h,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- semaphore.h 2001/01/29 00:44:39 1.3
+++ semaphore.h 2001/01/29 00:47:41 1.4
@@ -191,4 +191,3 @@
}
#endif /* _VAX_SEMAPHORE_H */
-
|