File: /usr/src/linux/include/asm-cris/semaphore.h

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