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
30 extern struct mtx Giant;
31
32
33 void mtx_init(struct mtx*, const char*, const char*, int);
34 void mtx_sysinit(void *arg);
35 void mtx_destroy(struct mtx*);
36 void mtx_lock_spin(struct mtx* mutex);
37 void mtx_unlock_spin(struct mtx* mutex);
38 void _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
49 static inline void
mtx_lock(struct mtx * mutex)50 mtx_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
63 static inline int
mtx_trylock(struct mtx * mutex)64 mtx_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
82 static inline void
mtx_unlock(struct mtx * mutex)83 mtx_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
96 static inline int
mtx_initialized(struct mtx * mutex)97 mtx_initialized(struct mtx* mutex)
98 {
99 /* TODO */
100 return 1;
101 }
102
103
104 static inline int
mtx_owned(struct mtx * mutex)105 mtx_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
123 static inline int
mtx_recursed(struct mtx * mutex)124 mtx_recursed(struct mtx* mutex)
125 {
126 if (mutex->type == MTX_RECURSE)
127 return mutex->u.recursive.recursion != 0;
128 return 0;
129 }
130
131
132 struct 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