Whamcloud - gitweb
LU-1346 libcfs: replace libcfs wrappers with kernel API
[fs/lustre-release.git] / libcfs / include / libcfs / darwin / darwin-lock.h
1 /*
2  * GPL HEADER START
3  *
4  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License version 2 only,
8  * as published by the Free Software Foundation.
9  *
10  * This program 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 version 2 for more details (a copy is included
14  * in the LICENSE file that accompanied this code).
15  *
16  * You should have received a copy of the GNU General Public License
17  * version 2 along with this program; If not, see
18  * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
19  *
20  * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
21  * CA 95054 USA or visit www.sun.com if you need additional information or
22  * have any questions.
23  *
24  * GPL HEADER END
25  */
26 /*
27  * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
28  * Use is subject to license terms.
29  */
30 /*
31  * This file is part of Lustre, http://www.lustre.org/
32  * Lustre is a trademark of Sun Microsystems, Inc.
33  */
34
35 #ifndef __LIBCFS_DARWIN_CFS_LOCK_H__
36 #define __LIBCFS_DARWIN_CFS_LOCK_H__
37
38 #ifndef __LIBCFS_LIBCFS_H__
39 #error Do not #include this file directly. #include <libcfs/libcfs.h> instead
40 #endif
41
42 #ifdef  __KERNEL__
43 #include <mach/sync_policy.h>
44 #include <mach/task.h>
45 #include <mach/semaphore.h>
46 #include <kern/assert.h>
47 #include <kern/thread.h>
48
49 #include <libcfs/darwin/darwin-types.h>
50 #include <libcfs/darwin/darwin-sync.h>
51
52 /*
53  * spin_lock (use Linux kernel's primitives)
54  *
55  * - spin_lock_init(x)
56  * - spin_lock(x)
57  * - spin_unlock(x)
58  * - spin_trylock(x)
59  *
60  * - spin_lock_irqsave(x, f)
61  * - spin_unlock_irqrestore(x, f)
62  */
63 struct spin_lock {
64         struct kspin spin;
65 };
66
67 typedef struct spin_lock spinlock_t;
68
69 static inline void spin_lock_init(spinlock_t *lock)
70 {
71         kspin_init(&lock->spin);
72 }
73
74 static inline void spin_lock(spinlock_t *lock)
75 {
76         kspin_lock(&lock->spin);
77 }
78
79 static inline void spin_unlock(spinlock_t *lock)
80 {
81         kspin_unlock(&lock->spin);
82 }
83
84 static inline int spin_trylock(spinlock_t *lock)
85 {
86         return kspin_trylock(&lock->spin);
87 }
88
89 static inline void spin_lock_done(spinlock_t *lock)
90 {
91         kspin_done(&lock->spin);
92 }
93
94 #error "does this lock out timer callbacks?"
95 #define spin_lock_bh(x)         spin_lock(x)
96 #define spin_unlock_bh(x)       spin_unlock(x)
97 #define spin_lock_bh_init(x)    spin_lock_init(x)
98
99 extern boolean_t ml_set_interrupts_enabled(boolean_t enable);
100 #define __disable_irq()         ml_set_interrupts_enabled(FALSE)
101 #define __enable_irq(x)         (void) ml_set_interrupts_enabled(x)
102
103 #define spin_lock_irqsave(s, f)         do{                     \
104                                         f = __disable_irq();    \
105                                         spin_lock(s);   }while(0)
106
107 #define spin_unlock_irqrestore(s, f)    do{                     \
108                                         spin_unlock(s);         \
109                                         __enable_irq(f);}while(0)
110
111 /* 
112  * Semaphore
113  *
114  * - sema_init(x, v)
115  * - __down(x)
116  * - __up(x)
117  */
118 struct semaphore {
119         struct ksem sem;
120 };
121
122 static inline void sema_init(struct semaphore *s, int val)
123 {
124         ksem_init(&s->sem, val);
125 }
126
127 static inline void __down(struct semaphore *s)
128 {
129         ksem_down(&s->sem, 1);
130 }
131
132 static inline void __up(struct semaphore *s)
133 {
134         ksem_up(&s->sem, 1);
135 }
136
137 /*
138  * Mutex:
139  *
140  * - init_mutex(x)
141  * - init_mutex_locked(x)
142  * - mutex_up(x)
143  * - mutex_down(x)
144  */
145
146 #define mutex_up(s)                     __up(s)
147 #define mutex_down(s)                   __down(s)
148
149 #define init_mutex(x)                   sema_init(x, 1)
150 #define init_mutex_locked(x)            sema_init(x, 0)
151
152 /*
153  * Completion:
154  *
155  * - init_completion(c)
156  * - complete(c)
157  * - wait_for_completion(c)
158  */
159 struct completion {
160         /*
161          * Emulate completion by semaphore for now.
162          *
163          * XXX nikita: this is not safe if completion is used to synchronize
164          * exit from kernel daemon thread and kext unloading. In this case
165          * some core function (a la complete_and_exit()) is needed.
166          */
167         struct ksem sem;
168 };
169
170 static inline void init_completion(struct completion *c)
171 {
172         ksem_init(&c->sem, 0);
173 }
174
175 static inline void complete(struct completion *c)
176 {
177         ksem_up(&c->sem, 1);
178 }
179
180 static inline void wait_for_completion(struct completion *c)
181 {
182         ksem_down(&c->sem, 1);
183 }
184
185 /*
186  * rw_semaphore:
187  *
188  * - DECLARE_RWSEM(x)
189  * - init_rwsem(x)
190  * - down_read(x)
191  * - up_read(x)
192  * - down_write(x)
193  * - up_write(x)
194  */
195 struct rw_semaphore {
196         struct krw_sem s;
197 };
198
199 static inline void init_rwsem(struct rw_semaphore *s)
200 {
201         krw_sem_init(&s->s);
202 }
203
204 static inline void fini_rwsem(struct rw_semaphore *s)
205 {
206         krw_sem_done(&s->s);
207 }
208
209 static inline void down_read(struct rw_semaphore *s)
210 {
211         krw_sem_down_r(&s->s);
212 }
213
214 static inline int down_read_trylock(struct rw_semaphore *s)
215 {
216         int ret = krw_sem_down_r_try(&s->s);
217         return ret == 0;
218 }
219
220 static inline void down_write(struct rw_semaphore *s)
221 {
222         krw_sem_down_w(&s->s);
223 }
224
225 static inline int down_write_trylock(struct rw_semaphore *s)
226 {
227         int ret = krw_sem_down_w_try(&s->s);
228         return ret == 0;
229 }
230
231 static inline void up_read(struct rw_semaphore *s)
232 {
233         krw_sem_up_r(&s->s);
234 }
235
236 static inline void up_write(struct rw_semaphore *s)
237 {
238         krw_sem_up_w(&s->s);
239 }
240
241 /* 
242  * read-write lock : Need to be investigated more!!
243  *
244  * - DECLARE_RWLOCK(l)
245  * - rwlock_init(x)
246  * - read_lock(x)
247  * - read_unlock(x)
248  * - write_lock(x)
249  * - write_unlock(x)
250  */
251 typedef struct krw_spin rwlock_t;
252
253 #define rwlock_init(pl)                 krw_spin_init(pl)
254
255 #define read_lock(l)                    krw_spin_down_r(l)
256 #define read_unlock(l)                  krw_spin_up_r(l)
257 #define write_lock(l)                   krw_spin_down_w(l)
258 #define write_unlock(l)                 krw_spin_up_w(l)
259
260 #define write_lock_irqsave(l, f)        do{                     \
261                                         f = __disable_irq();    \
262                                         write_lock(l);  }while(0)
263
264 #define write_unlock_irqrestore(l, f)   do{                     \
265                                         write_unlock(l);        \
266                                         __enable_irq(f);}while(0)
267
268 #define read_lock_irqsave(l, f)         do{                     \
269                                         f = __disable_irq();    \
270                                         read_lock(l);   }while(0)
271
272 #define read_unlock_irqrestore(l, f)    do{                     \
273                                         read_unlock(l);         \
274                                         __enable_irq(f);}while(0)
275 /*
276  * Funnel: 
277  *
278  * Safe funnel in/out
279  */
280 #ifdef __DARWIN8__
281
282 #define CFS_DECL_FUNNEL_DATA
283 #define CFS_DECL_CONE_DATA              DECLARE_FUNNEL_DATA
284 #define CFS_DECL_NET_DATA               DECLARE_FUNNEL_DATA
285 #define CFS_CONE_IN                     do {} while(0)
286 #define CFS_CONE_EX                     do {} while(0)
287
288 #define CFS_NET_IN                      do {} while(0)
289 #define CFS_NET_EX                      do {} while(0)
290
291 #else
292
293 #define CFS_DECL_FUNNEL_DATA                    \
294         boolean_t    __funnel_state = FALSE;    \
295         funnel_t    *__funnel
296 #define CFS_DECL_CONE_DATA              CFS_DECL_FUNNEL_DATA
297 #define CFS_DECL_NET_DATA               CFS_DECL_FUNNEL_DATA
298
299 void lustre_cone_in(boolean_t *state, funnel_t **cone);
300 void lustre_cone_ex(boolean_t state, funnel_t *cone);
301
302 #define CFS_CONE_IN lustre_cone_in(&__funnel_state, &__funnel)
303 #define CFS_CONE_EX lustre_cone_ex(__funnel_state, __funnel)
304
305 void lustre_net_in(boolean_t *state, funnel_t **cone);
306 void lustre_net_ex(boolean_t state, funnel_t *cone);
307
308 #define CFS_NET_IN  lustre_net_in(&__funnel_state, &__funnel)
309 #define CFS_NET_EX  lustre_net_ex(__funnel_state, __funnel)
310
311 #endif
312
313 #else
314 #include <libcfs/user-lock.h>
315 #endif /* __KERNEL__ */
316
317 /* __XNU_CFS_LOCK_H */
318 #endif