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 */ - |