1/* $Id: semaphore-helper.h,v 1.1.1.1 2007/08/03 18:53:22 Exp $ 2 * 3 * SMP- and interrupt-safe semaphores helper functions. Generic versions, no 4 * optimizations whatsoever... 5 * 6 */ 7 8#ifndef _ASM_SEMAPHORE_HELPER_H 9#define _ASM_SEMAPHORE_HELPER_H 10 11#include <asm/atomic.h> 12#include <linux/errno.h> 13 14#define read(a) ((a)->counter) 15#define inc(a) (((a)->counter)++) 16#define dec(a) (((a)->counter)--) 17 18#define count_inc(a) ((*(a))++) 19 20/* 21 * These two _must_ execute atomically wrt each other. 22 */ 23static inline void wake_one_more(struct semaphore * sem) 24{ 25 atomic_inc(&sem->waking); 26} 27 28static inline int waking_non_zero(struct semaphore *sem) 29{ 30 unsigned long flags; 31 int ret = 0; 32 33 local_irq_save(flags); 34 if (read(&sem->waking) > 0) { 35 dec(&sem->waking); 36 ret = 1; 37 } 38 local_irq_restore(flags); 39 return ret; 40} 41 42static inline int waking_non_zero_interruptible(struct semaphore *sem, 43 struct task_struct *tsk) 44{ 45 int ret = 0; 46 unsigned long flags; 47 48 local_irq_save(flags); 49 if (read(&sem->waking) > 0) { 50 dec(&sem->waking); 51 ret = 1; 52 } else if (signal_pending(tsk)) { 53 inc(&sem->count); 54 ret = -EINTR; 55 } 56 local_irq_restore(flags); 57 return ret; 58} 59 60static inline int waking_non_zero_trylock(struct semaphore *sem) 61{ 62 int ret = 1; 63 unsigned long flags; 64 65 local_irq_save(flags); 66 if (read(&sem->waking) <= 0) 67 inc(&sem->count); 68 else { 69 dec(&sem->waking); 70 ret = 0; 71 } 72 local_irq_restore(flags); 73 return ret; 74} 75 76#endif /* _ASM_SEMAPHORE_HELPER_H */ 77