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