1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2 * vim:expandtab:shiftwidth=8:tabstop=8:
4 * Implementation of standard libcfs synchronization primitives for XNU
7 * Copyright (c) 2004 Cluster File Systems, Inc.
9 * This file is part of Lustre, http://www.lustre.org.
11 * Lustre is free software; you can redistribute it and/or modify it under
12 * the terms of version 2 of the GNU General Public License as published by
13 * the Free Software Foundation. Lustre is distributed in the hope that it
14 * will be useful, but WITHOUT ANY WARRANTY; without even the implied
15 * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details. You should have received a
17 * copy of the GNU General Public License along with Lustre; if not, write
18 * to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139,
25 * Created by nikita on Sun Jul 18 2004.
27 * Prototypes of XNU synchronization primitives.
30 #ifndef __LIBCFS_DARWIN_XNU_SYNC_H__
31 #define __LIBCFS_DARWIN_XNU_SYNC_H__
33 #ifndef __LIBCFS_LIBCFS_H__
34 #error Do not #include this file directly. #include <libcfs/libcfs.h> instead
37 #define XNU_SYNC_DEBUG (1)
40 #define ON_SYNC_DEBUG(e) e
42 #define ON_SYNC_DEBUG(e)
46 /* "egrep -i '^(o?x)?[abcdeflo]*$' /usr/dict/words" is your friend */
47 KMUT_MAGIC = 0x0bac0cab, /* [a, [b, c]] = b (a, c) - c (a, b) */
48 KSEM_MAGIC = 0x1abe11ed,
49 KCOND_MAGIC = 0xb01dface,
50 KRW_MAGIC = 0xdabb1edd,
51 KSPIN_MAGIC = 0xca11ab1e,
52 KRW_SPIN_MAGIC = 0xbabeface,
53 KSLEEP_CHAN_MAGIC = 0x0debac1e,
54 KSLEEP_LINK_MAGIC = 0xacc01ade,
55 KTIMER_MAGIC = 0xbefadd1e
58 /* ------------------------- spin lock ------------------------- */
61 * XXX nikita: don't use NCPUS it's hardcoded to (1) in cpus.h
65 #include <libcfs/list.h>
69 #include <sys/param.h>
70 #include <sys/systm.h>
71 #include <sys/kernel.h>
72 #include <kern/locks.h>
75 * hw_lock is not available in Darwin8 (hw_lock_* are not exported at all),
76 * so use lck_spin_t. we can hack out lck_spin_t easily, it's the only
77 * hacking in Darwin8.x. We did so because it'll take a lot of time to
78 * add lock_done for all locks, maybe it should be done in the future.
79 * If lock_done for all locks were added, we can:
81 * typedef lck_spin_t *xnu_spin_t;
85 unsigned int opaque[3];
87 #elif defined (__i386__)
89 unsigned int opaque[10];
94 * wait_queue is not available in Darwin8 (wait_queue_* are not exported),
95 * use assert_wait/wakeup/wake_one (wait_queue in kernel hash).
97 typedef void * xnu_wait_queue_t;
102 #include <mach/mach_types.h>
103 #include <sys/types.h>
104 #include <kern/simple_lock.h>
106 typedef hw_lock_data_t xnu_spin_t;
107 typedef struct wait_queue xnu_wait_queue_t;
122 void kspin_init(struct kspin *spin);
123 void kspin_done(struct kspin *spin);
124 void kspin_lock(struct kspin *spin);
125 void kspin_unlock(struct kspin *spin);
126 int kspin_trylock(struct kspin *spin);
130 * two functions below are for use in assertions
132 /* true, iff spin-lock is locked by the current thread */
133 int kspin_islocked(struct kspin *spin);
134 /* true, iff spin-lock is not locked by the current thread */
135 int kspin_isnotlocked(struct kspin *spin);
137 #define kspin_islocked(s) (1)
138 #define kspin_isnotlocked(s) (1)
141 /* ------------------------- rw spinlock ----------------------- */
150 void krw_spin_init(struct krw_spin *sem);
151 void krw_spin_done(struct krw_spin *sem);
152 void krw_spin_down_r(struct krw_spin *sem);
153 void krw_spin_down_w(struct krw_spin *sem);
154 void krw_spin_up_r(struct krw_spin *sem);
155 void krw_spin_up_w(struct krw_spin *sem);
157 /* ------------------------- semaphore ------------------------- */
168 void ksem_init(struct ksem *sem, int value);
169 void ksem_done(struct ksem *sem);
170 int ksem_up (struct ksem *sem, int value);
171 void ksem_down(struct ksem *sem, int value);
172 int ksem_trydown(struct ksem *sem, int value);
174 /* ------------------------- mutex ------------------------- */
184 void kmut_init(struct kmut *mut);
185 void kmut_done(struct kmut *mut);
187 void kmut_lock (struct kmut *mut);
188 void kmut_unlock (struct kmut *mut);
189 int kmut_trylock(struct kmut *mut);
193 * two functions below are for use in assertions
195 /* true, iff mutex is locked by the current thread */
196 int kmut_islocked(struct kmut *mut);
197 /* true, iff mutex is not locked by the current thread */
198 int kmut_isnotlocked(struct kmut *mut);
200 #define kmut_islocked(m) (1)
201 #define kmut_isnotlocked(m) (1)
204 /* ------------------------- condition variable ------------------------- */
207 struct kcond_link *next;
213 struct kcond_link *waiters;
219 void kcond_init(struct kcond *cond);
220 void kcond_done(struct kcond *cond);
221 void kcond_wait(struct kcond *cond, struct kspin *lock);
222 void kcond_signal(struct kcond *cond);
223 void kcond_broadcast(struct kcond *cond);
225 void kcond_wait_guard(struct kcond *cond);
226 void kcond_signal_guard(struct kcond *cond);
227 void kcond_broadcast_guard(struct kcond *cond);
229 /* ------------------------- read-write semaphore ------------------------- */
239 void krw_sem_init(struct krw_sem *sem);
240 void krw_sem_done(struct krw_sem *sem);
241 void krw_sem_down_r(struct krw_sem *sem);
242 int krw_sem_down_r_try(struct krw_sem *sem);
243 void krw_sem_down_w(struct krw_sem *sem);
244 int krw_sem_down_w_try(struct krw_sem *sem);
245 void krw_sem_up_r(struct krw_sem *sem);
246 void krw_sem_up_w(struct krw_sem *sem);
248 /* ------------------------- sleep-channel ------------------------- */
252 struct list_head waiters;
258 #define KSLEEP_CHAN_INITIALIZER {{{0}}}
264 struct ksleep_chan *forward;
265 struct list_head linkage;
275 void ksleep_chan_init(struct ksleep_chan *chan);
276 void ksleep_chan_done(struct ksleep_chan *chan);
278 void ksleep_link_init(struct ksleep_link *link);
279 void ksleep_link_done(struct ksleep_link *link);
281 void ksleep_add(struct ksleep_chan *chan, struct ksleep_link *link);
282 void ksleep_del(struct ksleep_chan *chan, struct ksleep_link *link);
284 void ksleep_wait(struct ksleep_chan *chan, int state);
285 int64_t ksleep_timedwait(struct ksleep_chan *chan, int state, uint64_t timeout);
287 void ksleep_wake(struct ksleep_chan *chan);
288 void ksleep_wake_all(struct ksleep_chan *chan);
289 void ksleep_wake_nr(struct ksleep_chan *chan, int nr);
291 #define KSLEEP_LINK_DECLARE(name) \
296 .linkage = CFS_LIST_HEAD(name.linkage), \
297 .magic = KSLEEP_LINK_MAGIC \
300 /* ------------------------- timer ------------------------- */
304 void (*func)(void *);
306 u_int64_t deadline; /* timer deadline in absolute nanoseconds */
313 void ktimer_init(struct ktimer *t, void (*func)(void *), void *arg);
314 void ktimer_done(struct ktimer *t);
315 void ktimer_arm(struct ktimer *t, u_int64_t deadline);
316 void ktimer_disarm(struct ktimer *t);
317 int ktimer_is_armed(struct ktimer *t);
319 u_int64_t ktimer_deadline(struct ktimer *t);
326 * c-indentation-style: "K&R"