diff options
author | Ralf Baechle <ralf@linux-mips.org> | 1999-10-20 21:10:58 +0000 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 1999-10-20 21:10:58 +0000 |
commit | 3c230e92ef761debb676d8790010c30230415f90 (patch) | |
tree | 3184b411f0a099c3ee19a653c4a3525eebfdcbb1 /include/asm-mips/semaphore.h | |
parent | ff28d8ce709b1137516ff67a7c398ccf3c93ab5e (diff) |
Fix 32-bit version as well. I didn't really test these but they should
be ok as the code is almost identical with the 64-bit variant.
Diffstat (limited to 'include/asm-mips/semaphore.h')
-rw-r--r-- | include/asm-mips/semaphore.h | 79 |
1 files changed, 51 insertions, 28 deletions
diff --git a/include/asm-mips/semaphore.h b/include/asm-mips/semaphore.h index 0b283f4f4..40e51b09e 100644 --- a/include/asm-mips/semaphore.h +++ b/include/asm-mips/semaphore.h @@ -1,4 +1,4 @@ -/* $Id: semaphore.h,v 1.9 1999/08/13 17:07:27 harald Exp $ +/* $Id: semaphore.h,v 1.10 1999/10/09 00:01:43 ralf Exp $ * * SMP- and interrupt-safe semaphores.. * @@ -8,6 +8,7 @@ * * (C) Copyright 1996 Linus Torvalds * (C) Copyright 1998, 1999 Ralf Baechle + * (C) Copyright 1999 Silicon Graphics, Inc. */ #ifndef _ASM_SEMAPHORE_H #define _ASM_SEMAPHORE_H @@ -109,7 +110,23 @@ extern inline int down_trylock(struct semaphore * sem) * down_trylock returns 0 on success, 1 if we failed to get the lock. * * We must manipulate count and waking simultaneously and atomically. - * Do this by using ll/sc on the pair of 32-bit words. + * Here, we this by using ll/sc on the pair of 32-bit words. This + * won't work on MIPS32 platforms, however, and must be rewritten. + * + * Pseudocode: + * + * Decrement(sem->count) + * If(sem->count >=0) { + * Return(SUCCESS) // resource is free + * } else { + * If(sem->waking <= 0) { // if no wakeup pending + * Increment(sem->count) // undo decrement + * Return(FAILURE) + * } else { + * Decrement(sem->waking) // otherwise "steal" wakeup + * Return(SUCCESS) + * } + * } */ extern inline int down_trylock(struct semaphore * sem) { @@ -121,55 +138,61 @@ extern inline int down_trylock(struct semaphore * sem) #ifdef __MIPSEB__ __asm__ __volatile__(" .set mips3 + 0: lld %1, %4 dli %3, 0x0000000100000000 - sltu %0, %1, $0 - - bltz %1, 1f - move %3, $0 + dsubu %1, %3 + li %0, 0 + bgez %1, 2f + sll %2, %1, 0 + blez %2, 1f + daddiu %1, %1, -1 + b 2f 1: - - sltu %2, %1, $0 - and %0, %0, %2 - bnez %0, 2f - - subu %0, %3 + daddu %1, %1, %3 + li %0, 1 + 2: scd %1, %4 - beqz %1, 0b - 2: .set mips0" : "=&r"(ret), "=&r"(tmp), "=&r"(tmp2), "=&r"(sub) : "m"(*sem) : "memory"); -#endif -#ifdef __MIPSEL__ +#elif defined(__MIPSEL__) + __asm__ __volatile__(" .set mips3 - 0: lld %1, %4 - dli %3, 0x0000000100000000 - sltu %0, %1, $0 + 0: lld %1, %4 + li %0, 0 + sll %2, %1, 0 + addiu %2, %2, -1 + bgez %2, 2f bltz %1, 1f - move %3, $0 + dsll32 %2, %2, 0 + dsrl32 %2, %2, 0 + dli %3, 0x0000000100000000 + dsubu %1, %3 + b 2f 1: - - sltu %2, %1, $0 - and %0, %0, %2 - bnez %0, 2f - - subu %0, %3 + li %0, 1 + b 3f + 2: + dsrl32 %1, %1, 0 + dsll32 %1, %1, 0 + or %1, %1, %2 + 3: scd %1, %4 - beqz %1, 0b - 2: .set mips0" : "=&r"(ret), "=&r"(tmp), "=&r"(tmp2), "=&r"(sub) : "m"(*sem) : "memory"); +#else +#error "MIPS but neither __MIPSEL__ nor __MIPSEB__" #endif return ret; |