diff options
Diffstat (limited to 'include/asm-ppc/semaphore.h')
-rw-r--r-- | include/asm-ppc/semaphore.h | 64 |
1 files changed, 26 insertions, 38 deletions
diff --git a/include/asm-ppc/semaphore.h b/include/asm-ppc/semaphore.h index a78c203d2..ab21c33a6 100644 --- a/include/asm-ppc/semaphore.h +++ b/include/asm-ppc/semaphore.h @@ -13,66 +13,54 @@ struct semaphore { atomic_t count; atomic_t waking; - struct wait_queue * wait; + struct wait_queue *wait; }; -#define MUTEX ((struct semaphore) { ATOMIC_INIT(1), ATOMIC_INIT(0), NULL }) -#define MUTEX_LOCKED ((struct semaphore) { ATOMIC_INIT(0), ATOMIC_INIT(0), NULL }) +#define sema_init(sem, val) atomic_set(&((sem)->count), (val)) + +#define MUTEX ((struct semaphore) \ + { ATOMIC_INIT(1), ATOMIC_INIT(0), NULL }) +#define MUTEX_LOCKED ((struct semaphore) \ + { ATOMIC_INIT(0), ATOMIC_INIT(0), NULL }) extern void __down(struct semaphore * sem); extern int __down_interruptible(struct semaphore * sem); +extern int __down_trylock(struct semaphore * sem); extern void __up(struct semaphore * sem); -#define sema_init(sem, val) atomic_set(&((sem)->count), (val)) - -/* - * These two _must_ execute atomically wrt each other. - * - * This is trivially done with load_locked/store_cond, - * i.e. load with reservation and store conditional on the ppc. - */ - -static inline void wake_one_more(struct semaphore * sem) +extern inline void down(struct semaphore * sem) { - atomic_inc(&sem->waking); + if (atomic_dec_return(&sem->count) >= 0) + wmb(); + else + __down(sem); } -static inline int waking_non_zero(struct semaphore *sem, struct task_struct *tsk) +extern inline int down_interruptible(struct semaphore * sem) { - int ret, tmp; - - __asm__ __volatile__( - "1: lwarx %1,0,%2\n" - " cmpwi 0,%1,0\n" - " addic %1,%1,-1\n" - " ble- 2f\n" - " stwcx. %1,0,%2\n" - " bne- 1b\n" - " li %0,1\n" - "2:" - : "=r" (ret), "=&r" (tmp) - : "r" (&sem->waking), "0" (0) - : "cr0", "memory"); + int ret = 0; + if (atomic_dec_return(&sem->count) >= 0) + wmb(); + else + ret = __down_interruptible(sem); return ret; } -extern inline void down(struct semaphore * sem) -{ - if (atomic_dec_return(&sem->count) < 0) - __down(sem); -} - -extern inline int down_interruptible(struct semaphore * sem) +extern inline int down_trylock(struct semaphore * sem) { int ret = 0; - if (atomic_dec_return(&sem->count) < 0) - ret = __down_interruptible(sem); + + if (atomic_dec_return(&sem->count) >= 0) + wmb(); + else + ret = __down_trylock(sem); return ret; } extern inline void up(struct semaphore * sem) { + mb(); if (atomic_inc_return(&sem->count) <= 0) __up(sem); } |