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.
|