20#ifndef _COBALT_KERNEL_LOCK_H
21#define _COBALT_KERNEL_LOCK_H
23#include <pipeline/lock.h>
24#include <linux/percpu.h>
25#include <cobalt/kernel/assert.h>
26#include <pipeline/pipeline.h>
33#ifdef CONFIG_XENO_OPT_DEBUG_LOCKING
37 arch_spinlock_t alock;
42 unsigned long long spin_time;
43 unsigned long long lock_date;
47 unsigned long long spin_time;
48 unsigned long long lock_time;
54#define XNARCH_LOCK_UNLOCKED (struct xnlock) { \
56 __ARCH_SPIN_LOCK_UNLOCKED, \
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
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);
80DECLARE_PER_CPU(
struct xnlockinfo, xnlock_stats);
86 arch_spinlock_t alock;
89#define XNARCH_LOCK_UNLOCKED \
92 __ARCH_SPIN_LOCK_UNLOCKED, \
95#define XNLOCK_DBG_CONTEXT
96#define XNLOCK_DBG_CONTEXT_ARGS
97#define XNLOCK_DBG_PASS_CONTEXT
100void xnlock_dbg_prepare_acquire(
unsigned long long *start)
105void xnlock_dbg_prepare_spin(
unsigned int *spin_limit)
110xnlock_dbg_acquired(
struct xnlock *lock,
int cpu,
111 unsigned long long *start)
115static inline int xnlock_dbg_release(
struct xnlock *lock)
122#if defined(CONFIG_SMP) || defined(CONFIG_XENO_OPT_DEBUG_LOCKING)
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)
133static inline void xnlock_init (
struct xnlock *lock)
135 *lock = XNARCH_LOCK_UNLOCKED;
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)
143static inline int ____xnlock_get(
struct xnlock *lock XNLOCK_DBG_CONTEXT_ARGS)
145 int cpu = raw_smp_processor_id();
146 unsigned long long start;
148 if (lock->owner == cpu)
151 xnlock_dbg_prepare_acquire(&start);
153 arch_spin_lock(&lock->alock);
156 xnlock_dbg_acquired(lock, cpu, &start XNLOCK_DBG_PASS_CONTEXT);
161static inline void ____xnlock_put(
struct xnlock *lock XNLOCK_DBG_CONTEXT_ARGS)
163 if (xnlock_dbg_release(lock XNLOCK_DBG_PASS_CONTEXT))
167 arch_spin_unlock(&lock->alock);
170#ifndef CONFIG_XENO_ARCH_OUTOFLINE_XNLOCK
171#define ___xnlock_get ____xnlock_get
172#define ___xnlock_put ____xnlock_put
174int ___xnlock_get(
struct xnlock *lock XNLOCK_DBG_CONTEXT_ARGS);
176void ___xnlock_put(
struct xnlock *lock XNLOCK_DBG_CONTEXT_ARGS);
180__xnlock_get_irqsave(
struct xnlock *lock XNLOCK_DBG_CONTEXT_ARGS)
186 if (__locking_active__)
187 flags |= ___xnlock_get(lock XNLOCK_DBG_PASS_CONTEXT);
192static inline void __xnlock_put_irqrestore(
struct xnlock *lock, spl_t flags
193 XNLOCK_DBG_CONTEXT_ARGS)
196 if (__locking_active__ && !(flags & 2))
197 ___xnlock_put(lock XNLOCK_DBG_PASS_CONTEXT);
202static inline int xnlock_is_owner(
struct xnlock *lock)
204 if (__locking_active__)
205 return lock->owner == raw_smp_processor_id();
210static inline int __xnlock_get(
struct xnlock *lock XNLOCK_DBG_CONTEXT_ARGS)
212 if (__locking_active__)
213 return ___xnlock_get(lock XNLOCK_DBG_PASS_CONTEXT);
218static inline void __xnlock_put(
struct xnlock *lock XNLOCK_DBG_CONTEXT_ARGS)
220 if (__locking_active__)
221 ___xnlock_put(lock XNLOCK_DBG_PASS_CONTEXT);
224#undef __locking_active__
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
237#define DECLARE_XNLOCK(lock)
238#define DECLARE_EXTERN_XNLOCK(lock)
239#define DEFINE_XNLOCK(lock)
240#define DEFINE_PRIVATE_XNLOCK(lock)
244DECLARE_EXTERN_XNLOCK(nklock);