more debug output
[linux-2.4.git] / include / asm-cris / semaphore.h
1 /* On the i386 these are coded in asm, perhaps we should as well. Later.. */
2
3 #ifndef _CRIS_SEMAPHORE_H
4 #define _CRIS_SEMAPHORE_H
5
6 #define RW_LOCK_BIAS             0x01000000
7
8 #include <linux/wait.h>
9 #include <linux/spinlock.h>
10 #include <linux/rwsem.h>
11
12 #include <asm/system.h>
13 #include <asm/atomic.h>
14
15 /*
16  * CRIS semaphores, implemented in C-only so far.
17  */
18
19 int printk(const char *fmt, ...);
20
21 struct semaphore {
22         int count; /* not atomic_t since we do the atomicity here already */
23         atomic_t waking;
24         wait_queue_head_t wait;
25 #if WAITQUEUE_DEBUG
26         long __magic;
27 #endif
28 };
29
30 #if WAITQUEUE_DEBUG
31 # define __SEM_DEBUG_INIT(name)         , (long)&(name).__magic
32 #else
33 # define __SEM_DEBUG_INIT(name)
34 #endif
35
36 #define __SEMAPHORE_INITIALIZER(name,count)             \
37         { count, ATOMIC_INIT(0),          \
38           __WAIT_QUEUE_HEAD_INITIALIZER((name).wait)    \
39           __SEM_DEBUG_INIT(name) }
40
41 #define __MUTEX_INITIALIZER(name) \
42         __SEMAPHORE_INITIALIZER(name,1)
43
44 #define __DECLARE_SEMAPHORE_GENERIC(name,count) \
45         struct semaphore name = __SEMAPHORE_INITIALIZER(name,count)
46
47 #define DECLARE_MUTEX(name) __DECLARE_SEMAPHORE_GENERIC(name,1)
48 #define DECLARE_MUTEX_LOCKED(name) __DECLARE_SEMAPHORE_GENERIC(name,0)
49
50 extern inline void sema_init(struct semaphore *sem, int val)
51 {
52         *sem = (struct semaphore)__SEMAPHORE_INITIALIZER((*sem),val);
53 }
54
55 extern inline void init_MUTEX (struct semaphore *sem)
56 {
57         sema_init(sem, 1);
58 }
59
60 extern inline void init_MUTEX_LOCKED (struct semaphore *sem)
61 {
62         sema_init(sem, 0);
63 }
64
65 extern void __down(struct semaphore * sem);
66 extern int __down_interruptible(struct semaphore * sem);
67 extern int __down_trylock(struct semaphore * sem);
68 extern void __up(struct semaphore * sem);
69
70 /* notice - we probably can do cli/sti here instead of saving */
71
72 extern inline void down(struct semaphore * sem)
73 {
74         unsigned long flags;
75         int failed;
76
77 #if WAITQUEUE_DEBUG
78         CHECK_MAGIC(sem->__magic);
79 #endif
80
81         /* atomically decrement the semaphores count, and if its negative, we wait */
82         save_flags(flags);
83         cli();
84         failed = --(sem->count) < 0;
85         restore_flags(flags);
86         if(failed) {
87                 __down(sem);
88         }
89 }
90
91 /*
92  * This version waits in interruptible state so that the waiting
93  * process can be killed.  The down_interruptible routine
94  * returns negative for signalled and zero for semaphore acquired.
95  */
96
97 extern inline int down_interruptible(struct semaphore * sem)
98 {
99         unsigned long flags;
100         int failed;
101
102 #if WAITQUEUE_DEBUG
103         CHECK_MAGIC(sem->__magic);
104 #endif
105
106         /* atomically decrement the semaphores count, and if its negative, we wait */
107         save_flags(flags);
108         cli();
109         failed = --(sem->count) < 0;
110         restore_flags(flags);
111         if(failed)
112                 failed = __down_interruptible(sem);
113         return(failed);
114 }
115
116 extern inline int down_trylock(struct semaphore * sem)
117 {
118         unsigned long flags;
119         int failed;
120
121 #if WAITQUEUE_DEBUG
122         CHECK_MAGIC(sem->__magic);
123 #endif
124
125         save_flags(flags);
126         cli();
127         failed = --(sem->count) < 0;
128         restore_flags(flags);
129         if(failed)
130                 failed = __down_trylock(sem);
131         return(failed);
132 }
133
134 /*
135  * Note! This is subtle. We jump to wake people up only if
136  * the semaphore was negative (== somebody was waiting on it).
137  * The default case (no contention) will result in NO
138  * jumps for both down() and up().
139  */
140 extern inline void up(struct semaphore * sem)
141 {
142         unsigned long flags;
143         int wakeup;
144
145 #if WAITQUEUE_DEBUG
146         CHECK_MAGIC(sem->__magic);
147 #endif
148
149         /* atomically increment the semaphores count, and if it was negative, we wake people */
150         save_flags(flags);
151         cli();
152         wakeup = ++(sem->count) <= 0;
153         restore_flags(flags);
154         if(wakeup) {
155                 __up(sem);
156         }
157 }
158
159 static inline int sem_getcount(struct semaphore *sem)
160 {
161         return sem->count;
162 }
163
164 #endif