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