Whamcloud - gitweb
10e471a0f2352dc352c1c464a1f6d99e091dfbd8
[fs/lustre-release.git] / libcfs / include / libcfs / darwin / darwin-sync.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  * libcfs/include/libcfs/darwin/darwin-sync.h
35  *
36  * Prototypes of XNU synchronization primitives.
37  */
38
39 #ifndef __LIBCFS_DARWIN_XNU_SYNC_H__
40 #define __LIBCFS_DARWIN_XNU_SYNC_H__
41
42 #ifndef __LIBCFS_LIBCFS_H__
43 #error Do not #include this file directly. #include <libcfs/libcfs.h> instead
44 #endif
45
46 #define XNU_SYNC_DEBUG (1)
47
48 #if XNU_SYNC_DEBUG
49 #define ON_SYNC_DEBUG(e) e
50 #else
51 #define ON_SYNC_DEBUG(e)
52 #endif
53
54 enum {
55         /* "egrep -i '^(o?x)?[abcdeflo]*$' /usr/dict/words" is your friend */
56         KMUT_MAGIC  = 0x0bac0cab, /* [a, [b, c]] = b (a, c) - c (a, b) */
57         KSEM_MAGIC  = 0x1abe11ed,
58         KCOND_MAGIC = 0xb01dface,
59         KRW_MAGIC   = 0xdabb1edd,
60         KSPIN_MAGIC = 0xca11ab1e,
61         KRW_SPIN_MAGIC    = 0xbabeface,
62         KSLEEP_CHAN_MAGIC = 0x0debac1e,
63         KSLEEP_LINK_MAGIC = 0xacc01ade,
64         KTIMER_MAGIC      = 0xbefadd1e
65 };
66
67 /* ------------------------- spin lock ------------------------- */
68
69 /*
70  * XXX nikita: don't use NCPUS it's hardcoded to (1) in cpus.h
71  */
72 #define SMP (1)
73
74 #include <libcfs/list.h>
75
76 #ifdef __DARWIN8__
77
78 #include <sys/param.h>
79 #include <sys/systm.h>
80 #include <sys/kernel.h>
81 #include <kern/locks.h>
82
83 /*
84  * hw_lock is not available in Darwin8 (hw_lock_* are not exported at all), 
85  * so use lck_spin_t. we can hack out lck_spin_t easily, it's the only 
86  * hacking in Darwin8.x. We did so because it'll take a lot of time to 
87  * add lock_done for all locks, maybe it should be done in the future.
88  * If lock_done for all locks were added, we can:
89  *
90  * typedef lck_spin_t      *xnu_spin_t;
91  */
92 #if defined (__ppc__)
93 typedef struct {
94         unsigned int    opaque[3];
95 } xnu_spin_t;
96 #elif defined (__i386__)
97 typedef struct {
98         unsigned int    opaque[10];
99 } xnu_spin_t;
100 #endif
101
102 /* 
103  * wait_queue is not available in Darwin8 (wait_queue_* are not exported), 
104  * use assert_wait/wakeup/wake_one (wait_queue in kernel hash).
105  */
106 typedef void * xnu_wait_queue_t;
107
108 /* DARWIN8 */
109 #else
110
111 #include <mach/mach_types.h>
112 #include <sys/types.h>
113 #include <kern/simple_lock.h>
114
115 typedef hw_lock_data_t          xnu_spin_t;
116 typedef struct wait_queue       xnu_wait_queue_t;
117
118 /* DARWIN8 */
119 #endif
120
121 struct kspin {
122 #if SMP
123         xnu_spin_t      lock;
124 #endif
125 #if XNU_SYNC_DEBUG
126         unsigned        magic;
127         thread_t        owner;
128 #endif
129 };
130
131 void kspin_init(struct kspin *spin);
132 void kspin_done(struct kspin *spin);
133 void kspin_lock(struct kspin *spin);
134 void kspin_unlock(struct kspin *spin);
135 int  kspin_trylock(struct kspin *spin);
136
137 #if XNU_SYNC_DEBUG
138 /*
139  * two functions below are for use in assertions
140  */
141 /* true, iff spin-lock is locked by the current thread */
142 int kspin_islocked(struct kspin *spin);
143 /* true, iff spin-lock is not locked by the current thread */
144 int kspin_isnotlocked(struct kspin *spin);
145 #else
146 #define kspin_islocked(s) (1)
147 #define kspin_isnotlocked(s) (1)
148 #endif
149
150 /* ------------------------- rw spinlock ----------------------- */
151 struct krw_spin {
152         struct kspin      guard;
153         int               count;
154 #if XNU_SYNC_DEBUG
155         unsigned          magic;
156 #endif
157 };
158
159 void krw_spin_init(struct krw_spin *sem);
160 void krw_spin_done(struct krw_spin *sem);
161 void krw_spin_down_r(struct krw_spin *sem);
162 void krw_spin_down_w(struct krw_spin *sem);
163 void krw_spin_up_r(struct krw_spin *sem);
164 void krw_spin_up_w(struct krw_spin *sem);
165
166 /* ------------------------- semaphore ------------------------- */
167
168 struct ksem {
169         struct kspin      guard;
170         xnu_wait_queue_t  q;
171         int               value;
172 #if XNU_SYNC_DEBUG
173         unsigned          magic;
174 #endif
175 };
176
177 void ksem_init(struct ksem *sem, int value);
178 void ksem_done(struct ksem *sem);
179 int  ksem_up  (struct ksem *sem, int value);
180 void ksem_down(struct ksem *sem, int value);
181 int  ksem_trydown(struct ksem *sem, int value);
182
183 /* ------------------------- mutex ------------------------- */
184
185 struct kmut {
186         struct ksem s;
187 #if XNU_SYNC_DEBUG
188         unsigned    magic;
189         thread_t    owner;
190 #endif
191 };
192
193 void kmut_init(struct kmut *mut);
194 void kmut_done(struct kmut *mut);
195
196 void kmut_lock   (struct kmut *mut);
197 void kmut_unlock (struct kmut *mut);
198 int  kmut_trylock(struct kmut *mut);
199
200 #if XNU_SYNC_DEBUG
201 /*
202  * two functions below are for use in assertions
203  */
204 /* true, iff mutex is locked by the current thread */
205 int kmut_islocked(struct kmut *mut);
206 /* true, iff mutex is not locked by the current thread */
207 int kmut_isnotlocked(struct kmut *mut);
208 #else
209 #define kmut_islocked(m) (1)
210 #define kmut_isnotlocked(m) (1)
211 #endif
212
213 /* ------------------------- condition variable ------------------------- */
214
215 struct kcond_link {
216         struct kcond_link *next;
217         struct ksem        sem;
218 };
219
220 struct kcond {
221         struct kspin       guard;
222         struct kcond_link *waiters;
223 #if XNU_SYNC_DEBUG
224         unsigned           magic;
225 #endif
226 };
227
228 void kcond_init(struct kcond *cond);
229 void kcond_done(struct kcond *cond);
230 void kcond_wait(struct kcond *cond, struct kspin *lock);
231 void kcond_signal(struct kcond *cond);
232 void kcond_broadcast(struct kcond *cond);
233
234 void kcond_wait_guard(struct kcond *cond);
235 void kcond_signal_guard(struct kcond *cond);
236 void kcond_broadcast_guard(struct kcond *cond);
237
238 /* ------------------------- read-write semaphore ------------------------- */
239
240 struct krw_sem {
241         int          count;
242         struct kcond cond;
243 #if XNU_SYNC_DEBUG
244         unsigned     magic;
245 #endif
246 };
247
248 void krw_sem_init(struct krw_sem *sem);
249 void krw_sem_done(struct krw_sem *sem);
250 void krw_sem_down_r(struct krw_sem *sem);
251 int krw_sem_down_r_try(struct krw_sem *sem);
252 void krw_sem_down_w(struct krw_sem *sem);
253 int krw_sem_down_w_try(struct krw_sem *sem);
254 void krw_sem_up_r(struct krw_sem *sem);
255 void krw_sem_up_w(struct krw_sem *sem);
256
257 /* ------------------------- sleep-channel ------------------------- */
258
259 struct ksleep_chan {
260         struct kspin     guard;
261         struct list_head waiters;
262 #if XNU_SYNC_DEBUG
263         unsigned     magic;
264 #endif
265 };
266
267 #define KSLEEP_CHAN_INITIALIZER         {{{0}}}
268
269 struct ksleep_link {
270         int                 flags;
271         event_t             event;
272         int                 hits;
273         struct ksleep_chan *forward;
274         struct list_head    linkage;
275 #if XNU_SYNC_DEBUG
276         unsigned     magic;
277 #endif
278 };
279
280 enum {
281         KSLEEP_EXCLUSIVE = 1
282 };
283
284 void ksleep_chan_init(struct ksleep_chan *chan);
285 void ksleep_chan_done(struct ksleep_chan *chan);
286
287 void ksleep_link_init(struct ksleep_link *link);
288 void ksleep_link_done(struct ksleep_link *link);
289
290 void ksleep_add(struct ksleep_chan *chan, struct ksleep_link *link);
291 void ksleep_del(struct ksleep_chan *chan, struct ksleep_link *link);
292
293 void ksleep_wait(struct ksleep_chan *chan, int state);
294 int64_t  ksleep_timedwait(struct ksleep_chan *chan, int state, __u64 timeout);
295
296 void ksleep_wake(struct ksleep_chan *chan);
297 void ksleep_wake_all(struct ksleep_chan *chan);
298 void ksleep_wake_nr(struct ksleep_chan *chan, int nr);
299
300 #define KSLEEP_LINK_DECLARE(name)               \
301 {                                               \
302         .flags   = 0,                           \
303         .event   = 0,                           \
304         .hits    = 0,                           \
305         .linkage = LIST_HEAD_INIT(name.linkage),\
306         .magic   = KSLEEP_LINK_MAGIC            \
307 }
308
309 /* ------------------------- timer ------------------------- */
310
311 struct ktimer {
312         struct kspin   guard;
313         void         (*func)(void *);
314         void          *arg;
315         u_int64_t      deadline; /* timer deadline in absolute nanoseconds */
316         int            armed;
317 #if XNU_SYNC_DEBUG
318         unsigned     magic;
319 #endif
320 };
321
322 void ktimer_init(struct ktimer *t, void (*func)(void *), void *arg);
323 void ktimer_done(struct ktimer *t);
324 void ktimer_arm(struct ktimer *t, u_int64_t deadline);
325 void ktimer_disarm(struct ktimer *t);
326 int  ktimer_is_armed(struct ktimer *t);
327
328 u_int64_t ktimer_deadline(struct ktimer *t);
329
330 /* __XNU_SYNC_H__ */
331 #endif
332
333 /*
334  * Local variables:
335  * c-indentation-style: "K&R"
336  * c-basic-offset: 8
337  * tab-width: 8
338  * fill-column: 80
339  * scroll-step: 1
340  * End:
341  */