blob: 965bfe8f52cf3f6fbd83c097fd87000358971008 [file] [log] [blame]
/*
* OSKA Linux implementation -- semaphores
*
* Copyright (C) 2007 Cambridge Silicon Radio Ltd.
*
* Refer to LICENSE.txt included with this source code for details on
* the license terms.
*/
#ifndef __OSKA_LINUX_SEMAPHORE_H
#define __OSKA_LINUX_SEMAPHORE_H
#include <linux/kernel.h>
#include <linux/kernel-compat.h>
typedef struct semaphore os_semaphore_t;
static inline void os_semaphore_init(os_semaphore_t *sem)
{
sema_init(sem, 0);
}
static inline void os_semaphore_destroy(os_semaphore_t *sem)
{
}
static inline void os_semaphore_wait(os_semaphore_t *sem)
{
down(sem);
}
/*
* down_timeout() was added in 2.6.26 with the generic semaphore
* implementation. For now, only support it on recent kernels as
* semaphores may be replaced by an event API that would be
* implemented with wait_event(), and wait_event_timeout().
*/
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26)
static inline int os_semaphore_wait_timed(os_semaphore_t *sem,
int time_ms)
{
if (down_timeout(sem, msecs_to_jiffies(time_ms)) < 0) {
return -ETIMEDOUT;
}
return 0;
}
#else
static inline int os_semaphore_wait_timed(os_semaphore_t *sem, int time_ms)
{
unsigned long now = jiffies;
do{
if(!down_trylock(sem))
return 0;
msleep(1);
} while(time_before(jiffies, now + msecs_to_jiffies(time_ms)));
return -ETIMEDOUT;
}
#endif
static inline void os_semaphore_post(os_semaphore_t *sem)
{
up(sem);
}
#endif /* __OSKA_LINUX_SEMAPHORE_H */