1#ifndef _ASM_IA64_SEMAPHORE_H
2#define _ASM_IA64_SEMAPHORE_H
3
4/*
5 * Copyright (C) 1998-2000 Hewlett-Packard Co
6 * Copyright (C) 1998-2000 David Mosberger-Tang <davidm@hpl.hp.com>
7 */
8
9#include <linux/wait.h>
10#include <linux/rwsem.h>
11
12#include <asm/atomic.h>
13
14struct semaphore {
15	atomic_t count;
16	int sleepers;
17	wait_queue_head_t wait;
18};
19
20#define __SEMAPHORE_INITIALIZER(name, n)				\
21{									\
22	.count		= ATOMIC_INIT(n),				\
23	.sleepers	= 0,						\
24	.wait		= __WAIT_QUEUE_HEAD_INITIALIZER((name).wait)	\
25}
26
27#define __DECLARE_SEMAPHORE_GENERIC(name,count)					\
28	struct semaphore name = __SEMAPHORE_INITIALIZER(name, count)
29
30#define DECLARE_MUTEX(name)		__DECLARE_SEMAPHORE_GENERIC(name, 1)
31#define DECLARE_MUTEX_LOCKED(name)	__DECLARE_SEMAPHORE_GENERIC(name, 0)
32
33static inline void
34sema_init (struct semaphore *sem, int val)
35{
36	*sem = (struct semaphore) __SEMAPHORE_INITIALIZER(*sem, val);
37}
38
39static inline void
40init_MUTEX (struct semaphore *sem)
41{
42	sema_init(sem, 1);
43}
44
45static inline void
46init_MUTEX_LOCKED (struct semaphore *sem)
47{
48	sema_init(sem, 0);
49}
50
51extern void __down (struct semaphore * sem);
52extern int  __down_interruptible (struct semaphore * sem);
53extern int  __down_trylock (struct semaphore * sem);
54extern void __up (struct semaphore * sem);
55
56/*
57 * Atomically decrement the semaphore's count.  If it goes negative,
58 * block the calling thread in the TASK_UNINTERRUPTIBLE state.
59 */
60static inline void
61down (struct semaphore *sem)
62{
63	might_sleep();
64	if (ia64_fetchadd(-1, &sem->count.counter, acq) < 1)
65		__down(sem);
66}
67
68/*
69 * Atomically decrement the semaphore's count.  If it goes negative,
70 * block the calling thread in the TASK_INTERRUPTIBLE state.
71 */
72static inline int
73down_interruptible (struct semaphore * sem)
74{
75	int ret = 0;
76
77	might_sleep();
78	if (ia64_fetchadd(-1, &sem->count.counter, acq) < 1)
79		ret = __down_interruptible(sem);
80	return ret;
81}
82
83static inline int
84down_trylock (struct semaphore *sem)
85{
86	int ret = 0;
87
88	if (ia64_fetchadd(-1, &sem->count.counter, acq) < 1)
89		ret = __down_trylock(sem);
90	return ret;
91}
92
93static inline void
94up (struct semaphore * sem)
95{
96	if (ia64_fetchadd(1, &sem->count.counter, rel) <= -1)
97		__up(sem);
98}
99
100#endif /* _ASM_IA64_SEMAPHORE_H */
101