bb8cc64165
"extern inline" generates a warning with -Wmissing-prototypes and I'm currently working on getting the kernel cleaned up for adding this to the CFLAGS since it will help us to avoid a nasty class of runtime errors. If there are places that really need a forced inline, __always_inline would be the correct solution. Signed-off-by: Adrian Bunk <bunk@stusta.de> Acked-by: Mikael Starvik <starvik@axis.com> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
82 lines
1.5 KiB
C
82 lines
1.5 KiB
C
/* $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.
|
|
*/
|
|
static inline void wake_one_more(struct semaphore * sem)
|
|
{
|
|
atomic_inc(&sem->waking);
|
|
}
|
|
|
|
static inline int waking_non_zero(struct semaphore *sem)
|
|
{
|
|
unsigned long flags;
|
|
int ret = 0;
|
|
|
|
local_save_flags(flags);
|
|
local_irq_disable();
|
|
if (read(&sem->waking) > 0) {
|
|
dec(&sem->waking);
|
|
ret = 1;
|
|
}
|
|
local_irq_restore(flags);
|
|
return ret;
|
|
}
|
|
|
|
static inline int waking_non_zero_interruptible(struct semaphore *sem,
|
|
struct task_struct *tsk)
|
|
{
|
|
int ret = 0;
|
|
unsigned long flags;
|
|
|
|
local_save_flags(flags);
|
|
local_irq_disable();
|
|
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;
|
|
}
|
|
|
|
static inline int waking_non_zero_trylock(struct semaphore *sem)
|
|
{
|
|
int ret = 1;
|
|
unsigned long flags;
|
|
|
|
local_save_flags(flags);
|
|
local_irq_disable();
|
|
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 */
|
|
|
|
|