2005-04-16 15:20:36 -07:00
/* $Id: semaphore-helper.h,v 1.3 2001/03/26 15:00:33 orjanf Exp $
*
* SMP - and interrupt - safe semaphores helper functions . Generic versions , no
* optimizations whatsoever . . .
*
*/
# ifndef _ASM_SEMAPHORE_HELPER_H
# define _ASM_SEMAPHORE_HELPER_H
# include <asm/atomic.h>
# include <linux/errno.h>
# define read(a) ((a)->counter)
# define inc(a) (((a)->counter)++)
# define dec(a) (((a)->counter)--)
# define count_inc(a) ((*(a))++)
/*
* These two _must_ execute atomically wrt each other .
*/
2006-12-06 20:40:21 -08:00
static inline void wake_one_more ( struct semaphore * sem )
2005-04-16 15:20:36 -07:00
{
atomic_inc ( & sem - > waking ) ;
}
2006-12-06 20:40:21 -08:00
static inline int waking_non_zero ( struct semaphore * sem )
2005-04-16 15:20:36 -07:00
{
unsigned long flags ;
int ret = 0 ;
2007-02-10 01:43:50 -08:00
local_irq_save ( flags ) ;
2005-04-16 15:20:36 -07:00
if ( read ( & sem - > waking ) > 0 ) {
dec ( & sem - > waking ) ;
ret = 1 ;
}
local_irq_restore ( flags ) ;
return ret ;
}
2006-12-06 20:40:21 -08:00
static inline int waking_non_zero_interruptible ( struct semaphore * sem ,
2005-04-16 15:20:36 -07:00
struct task_struct * tsk )
{
int ret = 0 ;
unsigned long flags ;
2007-02-10 01:43:50 -08:00
local_irq_save ( flags ) ;
2005-04-16 15:20:36 -07:00
if ( read ( & sem - > waking ) > 0 ) {
dec ( & sem - > waking ) ;
ret = 1 ;
} else if ( signal_pending ( tsk ) ) {
inc ( & sem - > count ) ;
ret = - EINTR ;
}
local_irq_restore ( flags ) ;
return ret ;
}
2006-12-06 20:40:21 -08:00
static inline int waking_non_zero_trylock ( struct semaphore * sem )
2005-04-16 15:20:36 -07:00
{
int ret = 1 ;
unsigned long flags ;
2007-02-10 01:43:50 -08:00
local_irq_save ( flags ) ;
2005-04-16 15:20:36 -07:00
if ( read ( & sem - > waking ) < = 0 )
inc ( & sem - > count ) ;
else {
dec ( & sem - > waking ) ;
ret = 0 ;
}
local_irq_restore ( flags ) ;
return ret ;
}
# endif /* _ASM_SEMAPHORE_HELPER_H */