1/*
2 * Copyright 2009, Colin G��nther, coling@gmx.de.
3 * Copyright 2007, Hugo Santos. All Rights Reserved.
4 * Distributed under the terms of the MIT License.
5 */
6#ifndef _FBSD_COMPAT_SYS_MUTEX_H_
7#define _FBSD_COMPAT_SYS_MUTEX_H_
8
9
10#include <sys/_mutex.h>
11#include <sys/systm.h>
12#include <sys/pcpu.h>
13
14
15#define MA_OWNED		0x1
16#define MA_NOTOWNED		0x2
17#define MA_RECURSED		0x4
18#define MA_NOTRECURSED	0x8
19
20#define	MTX_DEF			0x00000000
21#define MTX_SPIN		0x00000001
22#define MTX_RECURSE		0x00000004
23#define MTX_QUIET		0x00040000
24#define MTX_DUPOK		0x00400000
25
26
27#define MTX_NETWORK_LOCK	"network driver"
28
29
30extern struct mtx Giant;
31
32
33void mtx_init(struct mtx*, const char*, const char*, int);
34void mtx_sysinit(void *arg);
35void mtx_destroy(struct mtx*);
36void mtx_lock_spin(struct mtx* mutex);
37void mtx_unlock_spin(struct mtx* mutex);
38void _mtx_assert(struct mtx *m, int what, const char *file, int line);
39
40
41#ifdef INVARIANTS
42#	define	mtx_assert(m, what)						\
43	_mtx_assert((m), (what), __FILE__, __LINE__)
44#else
45#	define	mtx_assert(m, what)
46#endif
47
48
49static inline void
50mtx_lock(struct mtx* mutex)
51{
52	if (mutex->type == MTX_DEF) {
53		mutex_lock(&mutex->u.mutex_.lock);
54		mutex->u.mutex_.owner = find_thread(NULL);
55	} else if (mutex->type == MTX_RECURSE) {
56		recursive_lock_lock(&mutex->u.recursive);
57	} else if (mutex->type == MTX_SPIN) {
58		mtx_lock_spin(mutex);
59	}
60}
61
62
63static inline int
64mtx_trylock(struct mtx* mutex)
65{
66	if (mutex->type == MTX_DEF) {
67		if (mutex_trylock(&mutex->u.mutex_.lock) != B_OK)
68			return 0;
69		mutex->u.mutex_.owner = find_thread(NULL);
70		return 1;
71	} else if (mutex->type == MTX_RECURSE) {
72		if (recursive_lock_trylock(&mutex->u.recursive) != B_OK)
73			return 0;
74		return 1;
75	} else if (mutex->type == MTX_SPIN) {
76		return 0;
77	}
78	return 0;
79}
80
81
82static inline void
83mtx_unlock(struct mtx* mutex)
84{
85	if (mutex->type == MTX_DEF) {
86		mutex->u.mutex_.owner = -1;
87		mutex_unlock(&mutex->u.mutex_.lock);
88	} else if (mutex->type == MTX_RECURSE) {
89		recursive_lock_unlock(&mutex->u.recursive);
90	} else if (mutex->type == MTX_SPIN) {
91		mtx_unlock_spin(mutex);
92	}
93}
94
95
96static inline int
97mtx_initialized(struct mtx* mutex)
98{
99	/* TODO */
100	return 1;
101}
102
103
104static inline int
105mtx_owned(struct mtx* mutex)
106{
107	if (mutex->type == MTX_DEF)
108		return mutex->u.mutex_.owner == find_thread(NULL);
109	if (mutex->type == MTX_RECURSE) {
110#if KDEBUG
111		return mutex->u.recursive.lock.holder == find_thread(NULL);
112#else
113		return mutex->u.recursive.holder == find_thread(NULL);
114#endif
115	}
116	if (mutex->type == MTX_SPIN)
117		return mutex->u.spinlock_.lock.lock != 0;
118
119	return 0;
120}
121
122
123static inline int
124mtx_recursed(struct mtx* mutex)
125{
126	if (mutex->type == MTX_RECURSE)
127		return mutex->u.recursive.recursion != 0;
128	return 0;
129}
130
131
132struct mtx_args {
133	void		*ma_mtx;
134	const char 	*ma_desc;
135	int		 ma_opts;
136};
137
138#define	MTX_SYSINIT(name, mtx, desc, opts) \
139	static struct mtx_args name##_args = {	\
140		(mtx), \
141		(desc), \
142		(opts), \
143	}; \
144	SYSINIT(name##_mtx, SI_SUB_LOCK, SI_ORDER_MIDDLE, \
145		mtx_sysinit, &name##_args); \
146	SYSUNINIT(name##_mtx, SI_SUB_LOCK, SI_ORDER_MIDDLE, \
147	    (system_init_func_t)mtx_destroy, (void*)mtx)
148
149
150#endif	/* _FBSD_COMPAT_SYS_MUTEX_H_ */
151