Xenomai 3.3.2
Loading...
Searching...
No Matches
lock.h
1/*
2 * Copyright (C) 2001-2008,2012 Philippe Gerum <rpm@xenomai.org>.
3 * Copyright (C) 2004,2005 Gilles Chanteperdrix <gilles.chanteperdrix@xenomai.org>.
4 *
5 * Xenomai is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published
7 * by the Free Software Foundation; either version 2 of the License,
8 * or (at your option) any later version.
9 *
10 * Xenomai is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with Xenomai; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
18 * 02111-1307, USA.
19 */
20#ifndef _COBALT_KERNEL_LOCK_H
21#define _COBALT_KERNEL_LOCK_H
22
23#include <pipeline/lock.h>
24#include <linux/percpu.h>
25#include <cobalt/kernel/assert.h>
26#include <pipeline/pipeline.h>
27
33#ifdef CONFIG_XENO_OPT_DEBUG_LOCKING
34
35struct xnlock {
36 unsigned owner;
37 arch_spinlock_t alock;
38 const char *file;
39 const char *function;
40 unsigned int line;
41 int cpu;
42 unsigned long long spin_time;
43 unsigned long long lock_date;
44};
45
46struct xnlockinfo {
47 unsigned long long spin_time;
48 unsigned long long lock_time;
49 const char *file;
50 const char *function;
51 unsigned int line;
52};
53
54#define XNARCH_LOCK_UNLOCKED (struct xnlock) { \
55 ~0, \
56 __ARCH_SPIN_LOCK_UNLOCKED, \
57 NULL, \
58 NULL, \
59 0, \
60 -1, \
61 0LL, \
62 0LL, \
63}
64
65#define XNLOCK_DBG_CONTEXT , __FILE__, __LINE__, __FUNCTION__
66#define XNLOCK_DBG_CONTEXT_ARGS \
67 , const char *file, int line, const char *function
68#define XNLOCK_DBG_PASS_CONTEXT , file, line, function
69
70void xnlock_dbg_prepare_acquire(unsigned long long *start);
71void xnlock_dbg_prepare_spin(unsigned int *spin_limit);
72void xnlock_dbg_acquired(struct xnlock *lock, int cpu,
73 unsigned long long *start,
74 const char *file, int line,
75 const char *function);
76int xnlock_dbg_release(struct xnlock *lock,
77 const char *file, int line,
78 const char *function);
79
80DECLARE_PER_CPU(struct xnlockinfo, xnlock_stats);
81
82#else /* !CONFIG_XENO_OPT_DEBUG_LOCKING */
83
84struct xnlock {
85 unsigned owner;
86 arch_spinlock_t alock;
87};
88
89#define XNARCH_LOCK_UNLOCKED \
90 (struct xnlock) { \
91 ~0, \
92 __ARCH_SPIN_LOCK_UNLOCKED, \
93 }
94
95#define XNLOCK_DBG_CONTEXT
96#define XNLOCK_DBG_CONTEXT_ARGS
97#define XNLOCK_DBG_PASS_CONTEXT
98
99static inline
100void xnlock_dbg_prepare_acquire(unsigned long long *start)
101{
102}
103
104static inline
105void xnlock_dbg_prepare_spin(unsigned int *spin_limit)
106{
107}
108
109static inline void
110xnlock_dbg_acquired(struct xnlock *lock, int cpu,
111 unsigned long long *start)
112{
113}
114
115static inline int xnlock_dbg_release(struct xnlock *lock)
116{
117 return 0;
118}
119
120#endif /* !CONFIG_XENO_OPT_DEBUG_LOCKING */
121
122#if defined(CONFIG_SMP) || defined(CONFIG_XENO_OPT_DEBUG_LOCKING)
123
124#define xnlock_get(lock) __xnlock_get(lock XNLOCK_DBG_CONTEXT)
125#define xnlock_put(lock) __xnlock_put(lock XNLOCK_DBG_CONTEXT)
126#define xnlock_get_irqsave(lock,x) \
127 ((x) = __xnlock_get_irqsave(lock XNLOCK_DBG_CONTEXT))
128#define xnlock_put_irqrestore(lock,x) \
129 __xnlock_put_irqrestore(lock,x XNLOCK_DBG_CONTEXT)
130#define xnlock_clear_irqoff(lock) xnlock_put_irqrestore(lock, 1)
131#define xnlock_clear_irqon(lock) xnlock_put_irqrestore(lock, 0)
132
133static inline void xnlock_init (struct xnlock *lock)
134{
135 *lock = XNARCH_LOCK_UNLOCKED;
136}
137
138#define DECLARE_XNLOCK(lock) struct xnlock lock
139#define DECLARE_EXTERN_XNLOCK(lock) extern struct xnlock lock
140#define DEFINE_XNLOCK(lock) struct xnlock lock = XNARCH_LOCK_UNLOCKED
141#define DEFINE_PRIVATE_XNLOCK(lock) static DEFINE_XNLOCK(lock)
142
143static inline int ____xnlock_get(struct xnlock *lock /*, */ XNLOCK_DBG_CONTEXT_ARGS)
144{
145 int cpu = raw_smp_processor_id();
146 unsigned long long start;
147
148 if (lock->owner == cpu)
149 return 2;
150
151 xnlock_dbg_prepare_acquire(&start);
152
153 arch_spin_lock(&lock->alock);
154 lock->owner = cpu;
155
156 xnlock_dbg_acquired(lock, cpu, &start /*, */ XNLOCK_DBG_PASS_CONTEXT);
157
158 return 0;
159}
160
161static inline void ____xnlock_put(struct xnlock *lock /*, */ XNLOCK_DBG_CONTEXT_ARGS)
162{
163 if (xnlock_dbg_release(lock /*, */ XNLOCK_DBG_PASS_CONTEXT))
164 return;
165
166 lock->owner = ~0U;
167 arch_spin_unlock(&lock->alock);
168}
169
170#ifndef CONFIG_XENO_ARCH_OUTOFLINE_XNLOCK
171#define ___xnlock_get ____xnlock_get
172#define ___xnlock_put ____xnlock_put
173#else /* out of line xnlock */
174int ___xnlock_get(struct xnlock *lock /*, */ XNLOCK_DBG_CONTEXT_ARGS);
175
176void ___xnlock_put(struct xnlock *lock /*, */ XNLOCK_DBG_CONTEXT_ARGS);
177#endif /* out of line xnlock */
178
179static inline spl_t
180__xnlock_get_irqsave(struct xnlock *lock /*, */ XNLOCK_DBG_CONTEXT_ARGS)
181{
182 unsigned long flags;
183
184 splhigh(flags);
185
186 if (__locking_active__)
187 flags |= ___xnlock_get(lock /*, */ XNLOCK_DBG_PASS_CONTEXT);
188
189 return flags;
190}
191
192static inline void __xnlock_put_irqrestore(struct xnlock *lock, spl_t flags
193 /*, */ XNLOCK_DBG_CONTEXT_ARGS)
194{
195 /* Only release the lock if we didn't take it recursively. */
196 if (__locking_active__ && !(flags & 2))
197 ___xnlock_put(lock /*, */ XNLOCK_DBG_PASS_CONTEXT);
198
199 splexit(flags & 1);
200}
201
202static inline int xnlock_is_owner(struct xnlock *lock)
203{
204 if (__locking_active__)
205 return lock->owner == raw_smp_processor_id();
206
207 return 1;
208}
209
210static inline int __xnlock_get(struct xnlock *lock /*, */ XNLOCK_DBG_CONTEXT_ARGS)
211{
212 if (__locking_active__)
213 return ___xnlock_get(lock /* , */ XNLOCK_DBG_PASS_CONTEXT);
214
215 return 0;
216}
217
218static inline void __xnlock_put(struct xnlock *lock /*, */ XNLOCK_DBG_CONTEXT_ARGS)
219{
220 if (__locking_active__)
221 ___xnlock_put(lock /*, */ XNLOCK_DBG_PASS_CONTEXT);
222}
223
224#undef __locking_active__
225
226#else /* !(CONFIG_SMP || CONFIG_XENO_OPT_DEBUG_LOCKING) */
227
228#define xnlock_init(lock) do { } while(0)
229#define xnlock_get(lock) do { } while(0)
230#define xnlock_put(lock) do { } while(0)
231#define xnlock_get_irqsave(lock,x) splhigh(x)
232#define xnlock_put_irqrestore(lock,x) splexit(x)
233#define xnlock_clear_irqoff(lock) splmax()
234#define xnlock_clear_irqon(lock) splnone()
235#define xnlock_is_owner(lock) 1
236
237#define DECLARE_XNLOCK(lock)
238#define DECLARE_EXTERN_XNLOCK(lock)
239#define DEFINE_XNLOCK(lock)
240#define DEFINE_PRIVATE_XNLOCK(lock)
241
242#endif /* !(CONFIG_SMP || CONFIG_XENO_OPT_DEBUG_LOCKING) */
243
244DECLARE_EXTERN_XNLOCK(nklock);
245
248#endif /* !_COBALT_KERNEL_LOCK_H */