Whamcloud - gitweb
3374f43c47f055d4dac7448d72394871104132b8
[fs/lustre-release.git] / lnet / 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  * Lustre Light Super operations
5  *
6  *  Copyright (c) 2004 Cluster File Systems, Inc.
7  *
8  *   This file is part of Lustre, http://www.lustre.org.
9  *
10  *   Lustre is free software; you can redistribute it and/or modify it under
11  *   the terms of version 2 of the GNU General Public License as published by
12  *   the Free Software Foundation. Lustre is distributed in the hope that it
13  *   will be useful, but WITHOUT ANY WARRANTY; without even the implied
14  *   warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  *   GNU General Public License for more details. You should have received a
16  *   copy of the GNU General Public License along with Lustre; if not, write
17  *   to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139,
18  *   USA.
19  */
20
21 /*
22  * xnu_sync.h
23  *
24  * Created by nikita on Sun Jul 18 2004.
25  *
26  * Prototypes of XNU synchronization primitives.
27  */
28
29 #ifndef __LIBCFS_DARWIN_XNU_SYNC_H__
30 #define __LIBCFS_DARWIN_XNU_SYNC_H__
31
32 #ifndef __LIBCFS_LIBCFS_H__
33 #error Do not #include this file directly. #include <libcfs/libcfs.h> instead
34 #endif
35
36 #define XNU_SYNC_DEBUG (0)
37
38 #if XNU_SYNC_DEBUG
39 #define ON_SYNC_DEBUG(e) e
40 #else
41 #define ON_SYNC_DEBUG(e)
42 #endif
43
44 enum {
45         /* "egrep -i '^(o?x)?[abcdeflo]*$' /usr/dict/words" is your friend */
46         KMUT_MAGIC  = 0x0bac0cab, /* [a, [b, c]] = b (a, c) - c (a, b) */
47         KSEM_MAGIC  = 0x1abe11ed,
48         KCOND_MAGIC = 0xb01dface,
49         KRW_MAGIC   = 0xdabb1edd,
50         KSPIN_MAGIC = 0xca11ab1e,
51         KSLEEP_CHAN_MAGIC = 0x0debac1e,
52         KSLEEP_LINK_MAGIC = 0xacc01ade,
53         KTIMER_MAGIC      = 0xbefadd1e
54 };
55
56 /* ------------------------- spin lock ------------------------- */
57
58 /*
59  * XXX nikita: don't use NCPUS it's hardcoded to (1) in cpus.h
60  */
61 #define SMP (1)
62
63 #include <kern/simple_lock.h>
64
65 #include <libcfs/list.h>
66
67 struct kspin {
68 #if SMP
69         hw_lock_data_t lock;
70 #endif
71 #if XNU_SYNC_DEBUG
72         unsigned magic;
73         thread_t owner;
74 #endif
75 };
76
77 /*
78  * XXX nikita: we cannot use simple_* functions, because bsd/sys/lock.h
79  * redefines them to nothing. Use low-level hw_lock_* instead.
80  */
81
82 void kspin_init(struct kspin *spin);
83 void kspin_done(struct kspin *spin);
84 void kspin_lock(struct kspin *spin);
85 void kspin_unlock(struct kspin *spin);
86 int  kspin_trylock(struct kspin *spin);
87
88 #if XNU_SYNC_DEBUG
89 /*
90  * two functions below are for use in assertions
91  */
92 /* true, iff spin-lock is locked by the current thread */
93 int kspin_islocked(struct kspin *spin);
94 /* true, iff spin-lock is not locked by the current thread */
95 int kspin_isnotlocked(struct kspin *spin);
96 #else
97 #define kspin_islocked(s) (1)
98 #define kspin_isnotlocked(s) (1)
99 #endif
100
101 /* ------------------------- semaphore ------------------------- */
102
103 struct ksem {
104         struct kspin      guard;
105         struct wait_queue q;
106         int               value;
107 #if XNU_SYNC_DEBUG
108         unsigned          magic;
109 #endif
110 };
111
112 void ksem_init(struct ksem *sem, int value);
113 void ksem_done(struct ksem *sem);
114 int  ksem_up  (struct ksem *sem, int value);
115 void ksem_down(struct ksem *sem, int value);
116 int  ksem_trydown(struct ksem *sem, int value);
117
118 /* ------------------------- mutex ------------------------- */
119
120 struct kmut {
121         struct ksem s;
122 #if XNU_SYNC_DEBUG
123         unsigned    magic;
124         thread_t    owner;
125 #endif
126 };
127
128 void kmut_init(struct kmut *mut);
129 void kmut_done(struct kmut *mut);
130
131 void kmut_lock   (struct kmut *mut);
132 void kmut_unlock (struct kmut *mut);
133 int  kmut_trylock(struct kmut *mut);
134
135 #if XNU_SYNC_DEBUG
136 /*
137  * two functions below are for use in assertions
138  */
139 /* true, iff mutex is locked by the current thread */
140 int kmut_islocked(struct kmut *mut);
141 /* true, iff mutex is not locked by the current thread */
142 int kmut_isnotlocked(struct kmut *mut);
143 #else
144 #define kmut_islocked(m) (1)
145 #define kmut_isnotlocked(m) (1)
146 #endif
147
148 /* ------------------------- condition variable ------------------------- */
149
150 struct kcond_link {
151         struct kcond_link *next;
152         struct ksem        sem;
153 };
154
155 struct kcond {
156         struct kspin       guard;
157         struct kcond_link *waiters;
158 #if XNU_SYNC_DEBUG
159         unsigned           magic;
160 #endif
161 };
162
163 void kcond_init(struct kcond *cond);
164 void kcond_done(struct kcond *cond);
165 void kcond_wait(struct kcond *cond, struct kspin *lock);
166 void kcond_signal(struct kcond *cond);
167 void kcond_broadcast(struct kcond *cond);
168
169 void kcond_wait_guard(struct kcond *cond);
170 void kcond_signal_guard(struct kcond *cond);
171 void kcond_broadcast_guard(struct kcond *cond);
172
173 /* ------------------------- read-write semaphore ------------------------- */
174
175 struct krw_sem {
176         int          count;
177         struct kcond cond;
178 #if XNU_SYNC_DEBUG
179         unsigned     magic;
180 #endif
181 };
182
183 void krw_sem_init(struct krw_sem *sem);
184 void krw_sem_done(struct krw_sem *sem);
185 void krw_sem_down_r(struct krw_sem *sem);
186 int krw_sem_down_r_try(struct krw_sem *sem);
187 void krw_sem_down_w(struct krw_sem *sem);
188 int krw_sem_down_w_try(struct krw_sem *sem);
189 void krw_sem_up_r(struct krw_sem *sem);
190 void krw_sem_up_w(struct krw_sem *sem);
191
192 /* ------------------------- sleep-channel ------------------------- */
193
194 struct ksleep_chan {
195         struct kspin     guard;
196         struct list_head waiters;
197 #if XNU_SYNC_DEBUG
198         unsigned     magic;
199 #endif
200 };
201
202 #define KSLEEP_CHAN_INITIALIZER         {{{0}}}
203
204 struct ksleep_link {
205         int                 flags;
206         event_t             event;
207         int                 hits;
208         struct ksleep_chan *forward;
209         struct list_head    linkage;
210 #if XNU_SYNC_DEBUG
211         unsigned     magic;
212 #endif
213 };
214
215 enum {
216         KSLEEP_EXCLUSIVE = 1
217 };
218
219 void ksleep_chan_init(struct ksleep_chan *chan);
220 void ksleep_chan_done(struct ksleep_chan *chan);
221
222 void ksleep_link_init(struct ksleep_link *link);
223 void ksleep_link_done(struct ksleep_link *link);
224
225 void ksleep_add(struct ksleep_chan *chan, struct ksleep_link *link);
226 void ksleep_del(struct ksleep_chan *chan, struct ksleep_link *link);
227
228 void ksleep_wait(struct ksleep_chan *chan);
229 int64_t  ksleep_timedwait(struct ksleep_chan *chan, uint64_t timeout);
230
231 void ksleep_wake(struct ksleep_chan *chan);
232 void ksleep_wake_all(struct ksleep_chan *chan);
233 void ksleep_wake_nr(struct ksleep_chan *chan, int nr);
234
235 #define KSLEEP_LINK_DECLARE(name)                       \
236 {                                                       \
237         .flags   = 0,                                   \
238         .event   = 0,                                   \
239         .hits    = 0,                                   \
240         .linkage = PTL_LIST_HEAD_INIT(name.linkage),    \
241         .magic   = KSLEEP_LINK_MAGIC                    \
242 }
243
244 /* ------------------------- timer ------------------------- */
245
246 struct ktimer {
247         struct kspin   guard;
248         void         (*func)(void *);
249         void          *arg;
250         u_int64_t      deadline; /* timer deadline in absolute nanoseconds */
251         int            armed;
252 #if XNU_SYNC_DEBUG
253         unsigned     magic;
254 #endif
255 };
256
257 void ktimer_init(struct ktimer *t, void (*func)(void *), void *arg);
258 void ktimer_done(struct ktimer *t);
259 void ktimer_arm(struct ktimer *t, u_int64_t deadline);
260 void ktimer_disarm(struct ktimer *t);
261 int  ktimer_is_armed(struct ktimer *t);
262
263 u_int64_t ktimer_deadline(struct ktimer *t);
264
265 /* __XNU_SYNC_H__ */
266 #endif
267
268 /*
269  * Local variables:
270  * c-indentation-style: "K&R"
271  * c-basic-offset: 8
272  * tab-width: 8
273  * fill-column: 80
274  * scroll-step: 1
275  * End:
276  */