Linux kernel & device driver programming

Cross-Referenced Linux and Device Driver Code

[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ]
Version: [ 2.6.11.8 ] [ 2.6.25 ] [ 2.6.25.8 ] [ 2.6.31.13 ] Architecture: [ i386 ]
  1 #ifndef __LINUX_RT_LOCK_H
  2 #define __LINUX_RT_LOCK_H
  3 
  4 /*
  5  * Real-Time Preemption Support
  6  *
  7  * started by Ingo Molnar:
  8  *
  9  *  Copyright (C) 2004, 2005 Red Hat, Inc., Ingo Molnar <mingo@redhat.com>
 10  *
 11  * This file contains the main data structure definitions.
 12  */
 13 #include <linux/rtmutex.h>
 14 #include <asm/atomic.h>
 15 #include <linux/spinlock_types.h>
 16 #include <linux/sched_prio.h>
 17 
 18 #ifdef CONFIG_PREEMPT_RT
 19 /*
 20  * spinlocks - an RT mutex plus lock-break field:
 21  */
 22 typedef struct {
 23         struct rt_mutex         lock;
 24         unsigned int            break_lock;
 25 #ifdef CONFIG_DEBUG_LOCK_ALLOC
 26         struct lockdep_map      dep_map;
 27 #endif
 28 } spinlock_t;
 29 
 30 #ifdef CONFIG_DEBUG_RT_MUTEXES
 31 # define __RT_SPIN_INITIALIZER(name)                                    \
 32         { .wait_lock = _RAW_SPIN_LOCK_UNLOCKED(name.wait_lock),         \
 33           .save_state = 1,                                              \
 34           .file = __FILE__,                                             \
 35           .line = __LINE__, }
 36 #else
 37 # define __RT_SPIN_INITIALIZER(name)                                    \
 38         { .wait_lock = _RAW_SPIN_LOCK_UNLOCKED(name.wait_lock) }
 39 #endif
 40 
 41 #define __SPIN_LOCK_UNLOCKED(name) (spinlock_t)                         \
 42         { .lock = __RT_SPIN_INITIALIZER(name),                          \
 43           SPIN_DEP_MAP_INIT(name) }
 44 
 45 #else /* !PREEMPT_RT */
 46 
 47 typedef raw_spinlock_t spinlock_t;
 48 
 49 #define __SPIN_LOCK_UNLOCKED    _RAW_SPIN_LOCK_UNLOCKED
 50 
 51 #endif
 52 
 53 #define SPIN_LOCK_UNLOCKED      __SPIN_LOCK_UNLOCKED(spin_old_style)
 54 
 55 
 56 #define __DEFINE_SPINLOCK(name) \
 57         spinlock_t name = __SPIN_LOCK_UNLOCKED(name)
 58 
 59 #define DEFINE_SPINLOCK(name) \
 60         spinlock_t name __cacheline_aligned_in_smp = __SPIN_LOCK_UNLOCKED(name)
 61 
 62 #ifdef CONFIG_PREEMPT_RT
 63 
 64 struct rw_mutex {
 65         struct task_struct      *owner;
 66         struct rt_mutex         mutex;
 67         atomic_t                count;  /* number of times held for read */
 68         atomic_t                owners; /* number of owners as readers */
 69         struct list_head        readers;
 70         int prio;
 71 };
 72 
 73 /*
 74  * RW-semaphores are a spinlock plus a reader-depth count.
 75  *
 76  * Note that the semantics are different from the usual
 77  * Linux rw-sems, in PREEMPT_RT mode we do not allow
 78  * multiple readers to hold the lock at once, we only allow
 79  * a read-lock owner to read-lock recursively. This is
 80  * better for latency, makes the implementation inherently
 81  * fair and makes it simpler as well:
 82  */
 83 struct rw_semaphore {
 84         struct rw_mutex owners;
 85 #ifdef CONFIG_DEBUG_LOCK_ALLOC
 86         struct lockdep_map      dep_map;
 87 #endif
 88 };
 89 
 90 /*
 91  * rwlocks - an RW semaphore plus lock-break field:
 92  */
 93 typedef struct {
 94         struct rw_mutex owners;
 95         unsigned int            break_lock;
 96 #ifdef CONFIG_DEBUG_LOCK_ALLOC
 97         struct lockdep_map      dep_map;
 98 #endif
 99 } rwlock_t;
100 
101 #define __RW_LOCK_UNLOCKED(name) (rwlock_t) \
102         { .owners.mutex = __RT_SPIN_INITIALIZER(name.owners.mutex),     \
103           .owners.prio = MAX_PRIO,                                      \
104           RW_DEP_MAP_INIT(name) }
105 #else /* !PREEMPT_RT */
106 
107 typedef raw_rwlock_t rwlock_t;
108 
109 #define __RW_LOCK_UNLOCKED      _RAW_RW_LOCK_UNLOCKED
110 
111 #endif
112 
113 #define RW_LOCK_UNLOCKED        __RW_LOCK_UNLOCKED(rw_old_style)
114 
115 
116 #define DEFINE_RWLOCK(name) \
117         rwlock_t name __cacheline_aligned_in_smp = __RW_LOCK_UNLOCKED(name)
118 
119 #ifdef CONFIG_PREEMPT_RT
120 
121 /*
122  * Semaphores - a spinlock plus the semaphore count:
123  */
124 struct semaphore {
125         atomic_t                count;
126         struct rt_mutex         lock;
127 };
128 
129 #define DECLARE_MUTEX(name) \
130 struct semaphore name = \
131         { .count = { 1 }, .lock = __RT_MUTEX_INITIALIZER(name.lock) }
132 
133 extern void
134 __sema_init(struct semaphore *sem, int val, char *name, char *file, int line);
135 
136 #define rt_sema_init(sem, val) \
137                 __sema_init(sem, val, #sem, __FILE__, __LINE__)
138 
139 extern void
140 __init_MUTEX(struct semaphore *sem, char *name, char *file, int line);
141 #define rt_init_MUTEX(sem) \
142                 __init_MUTEX(sem, #sem, __FILE__, __LINE__)
143 
144 extern void there_is_no_init_MUTEX_LOCKED_for_RT_semaphores(void);
145 
146 /*
147  * No locked initialization for RT semaphores
148  */
149 #define rt_init_MUTEX_LOCKED(sem) \
150                 there_is_no_init_MUTEX_LOCKED_for_RT_semaphores()
151 extern void  rt_down(struct semaphore *sem);
152 extern int  rt_down_interruptible(struct semaphore *sem);
153 extern int  rt_down_trylock(struct semaphore *sem);
154 extern void  rt_up(struct semaphore *sem);
155 
156 #define rt_sem_is_locked(s)     rt_mutex_is_locked(&(s)->lock)
157 #define rt_sema_count(s)        atomic_read(&(s)->count)
158 
159 extern int __bad_func_type(void);
160 
161 #include <linux/pickop.h>
162 
163 /*
164  * PICK_SEM_OP() is a small redirector to allow less typing of the lock
165  * types struct compat_semaphore, struct semaphore, at the front of the
166  * PICK_FUNCTION macro.
167  */
168 #define PICK_SEM_OP(...) PICK_FUNCTION(struct compat_semaphore *,       \
169         struct semaphore *, ##__VA_ARGS__)
170 #define PICK_SEM_OP_RET(...) PICK_FUNCTION_RET(struct compat_semaphore *,\
171         struct semaphore *, ##__VA_ARGS__)
172 
173 #define sema_init(sem, val) \
174         PICK_SEM_OP(compat_sema_init, rt_sema_init, sem, val)
175 
176 #define init_MUTEX(sem) PICK_SEM_OP(compat_init_MUTEX, rt_init_MUTEX, sem)
177 
178 #define init_MUTEX_LOCKED(sem) \
179         PICK_SEM_OP(compat_init_MUTEX_LOCKED, rt_init_MUTEX_LOCKED, sem)
180 
181 #define down(sem) PICK_SEM_OP(compat_down, rt_down, sem)
182 
183 #define down_interruptible(sem) \
184         PICK_SEM_OP_RET(compat_down_interruptible, rt_down_interruptible, sem)
185 
186 #define down_trylock(sem) \
187         PICK_SEM_OP_RET(compat_down_trylock, rt_down_trylock, sem)
188 
189 #define up(sem) PICK_SEM_OP(compat_up, rt_up, sem)
190 
191 #define sem_is_locked(sem) \
192         PICK_SEM_OP_RET(compat_sem_is_locked, rt_sem_is_locked, sem)
193 
194 #define sema_count(sem) PICK_SEM_OP_RET(compat_sema_count, rt_sema_count, sem)
195 
196 /*
197  * rwsems:
198  */
199 
200 #define __RWSEM_INITIALIZER(name) \
201         { .owners.mutex = __RT_MUTEX_INITIALIZER(name.owners.mutex),    \
202           .owners.prio = MAX_PRIO,                                      \
203           RW_DEP_MAP_INIT(name) }
204 
205 #define DECLARE_RWSEM(lockname) \
206         struct rw_semaphore lockname = __RWSEM_INITIALIZER(lockname)
207 
208 extern void  __rt_rwsem_init(struct rw_semaphore *rwsem, char *name,
209                                      struct lock_class_key *key);
210 
211 # define rt_init_rwsem(sem)                             \
212 do {                                                    \
213         static struct lock_class_key __key;             \
214                                                         \
215         __rt_rwsem_init((sem), #sem, &__key);           \
216 } while (0)
217 
218 extern void __dont_do_this_in_rt(struct rw_semaphore *rwsem);
219 
220 #define rt_down_read_non_owner(rwsem)   __dont_do_this_in_rt(rwsem)
221 #define rt_up_read_non_owner(rwsem)     __dont_do_this_in_rt(rwsem)
222 
223 extern void  rt_down_write(struct rw_semaphore *rwsem);
224 extern void
225 rt_down_read_nested(struct rw_semaphore *rwsem, int subclass);
226 extern void
227 rt_down_write_nested(struct rw_semaphore *rwsem, int subclass);
228 extern void  rt_down_read(struct rw_semaphore *rwsem);
229 extern int  rt_down_write_trylock(struct rw_semaphore *rwsem);
230 extern int  rt_down_read_trylock(struct rw_semaphore *rwsem);
231 extern void  rt_up_read(struct rw_semaphore *rwsem);
232 extern void  rt_up_write(struct rw_semaphore *rwsem);
233 extern void  rt_downgrade_write(struct rw_semaphore *rwsem);
234 
235 # define rt_rwsem_is_locked(rws)        ((rws)->owners.owner != NULL)
236 
237 #define PICK_RWSEM_OP(...) PICK_FUNCTION(struct compat_rw_semaphore *,  \
238         struct rw_semaphore *, ##__VA_ARGS__)
239 #define PICK_RWSEM_OP_RET(...) PICK_FUNCTION_RET(struct compat_rw_semaphore *,\
240         struct rw_semaphore *, ##__VA_ARGS__)
241 
242 #define init_rwsem(rwsem) PICK_RWSEM_OP(compat_init_rwsem, rt_init_rwsem, rwsem)
243 
244 #define down_read(rwsem) PICK_RWSEM_OP(compat_down_read, rt_down_read, rwsem)
245 
246 #define down_read_non_owner(rwsem) \
247         PICK_RWSEM_OP(compat_down_read_non_owner, rt_down_read_non_owner, rwsem)
248 
249 #define down_read_trylock(rwsem) \
250         PICK_RWSEM_OP_RET(compat_down_read_trylock, rt_down_read_trylock, rwsem)
251 
252 #define down_write(rwsem) PICK_RWSEM_OP(compat_down_write, rt_down_write, rwsem)
253 
254 #define down_read_nested(rwsem, subclass) \
255         PICK_RWSEM_OP(compat_down_read_nested, rt_down_read_nested,     \
256                 rwsem, subclass)
257 
258 #define down_write_nested(rwsem, subclass) \
259         PICK_RWSEM_OP(compat_down_write_nested, rt_down_write_nested,   \
260                 rwsem, subclass)
261 
262 #define down_write_trylock(rwsem) \
263         PICK_RWSEM_OP_RET(compat_down_write_trylock, rt_down_write_trylock,\
264                 rwsem)
265 
266 #define up_read(rwsem) PICK_RWSEM_OP(compat_up_read, rt_up_read, rwsem)
267 
268 #define up_read_non_owner(rwsem) \
269         PICK_RWSEM_OP(compat_up_read_non_owner, rt_up_read_non_owner, rwsem)
270 
271 #define up_write(rwsem) PICK_RWSEM_OP(compat_up_write, rt_up_write, rwsem)
272 
273 #define downgrade_write(rwsem) \
274         PICK_RWSEM_OP(compat_downgrade_write, rt_downgrade_write, rwsem)
275 
276 #define rwsem_is_locked(rwsem) \
277         PICK_RWSEM_OP_RET(compat_rwsem_is_locked, rt_rwsem_is_locked, rwsem)
278 
279 #endif /* CONFIG_PREEMPT_RT */
280 
281 #endif
282 
283 
  This page was automatically generated by the LXR engine.