/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- * vim:expandtab:shiftwidth=8:tabstop=8: * * Lustre Light Super operations * * Copyright (c) 2004 Cluster File Systems, Inc. * * This file is part of Lustre, http://www.lustre.org. * * Lustre is free software; you can redistribute it and/or modify it under * the terms of version 2 of the GNU General Public License as published by * the Free Software Foundation. Lustre is distributed in the hope that it * will be useful, but WITHOUT ANY WARRANTY; without even the implied * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. You should have received a * copy of the GNU General Public License along with Lustre; if not, write * to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, * USA. */ /* * xnu_sync.h * * Created by nikita on Sun Jul 18 2004. * * Prototypes of XNU synchronization primitives. */ #ifndef __LIBCFS_DARWIN_XNU_SYNC_H__ #define __LIBCFS_DARWIN_XNU_SYNC_H__ #ifndef __LIBCFS_LIBCFS_H__ #error Do not #include this file directly. #include instead #endif #define XNU_SYNC_DEBUG (0) #if XNU_SYNC_DEBUG #define ON_SYNC_DEBUG(e) e #else #define ON_SYNC_DEBUG(e) #endif enum { /* "egrep -i '^(o?x)?[abcdeflo]*$' /usr/dict/words" is your friend */ KMUT_MAGIC = 0x0bac0cab, /* [a, [b, c]] = b (a, c) - c (a, b) */ KSEM_MAGIC = 0x1abe11ed, KCOND_MAGIC = 0xb01dface, KRW_MAGIC = 0xdabb1edd, KSPIN_MAGIC = 0xca11ab1e, KSLEEP_CHAN_MAGIC = 0x0debac1e, KSLEEP_LINK_MAGIC = 0xacc01ade, KTIMER_MAGIC = 0xbefadd1e }; /* ------------------------- spin lock ------------------------- */ /* * XXX nikita: don't use NCPUS it's hardcoded to (1) in cpus.h */ #define SMP (1) #include #include struct kspin { #if SMP hw_lock_data_t lock; #endif #if XNU_SYNC_DEBUG unsigned magic; thread_t owner; #endif }; /* * XXX nikita: we cannot use simple_* functions, because bsd/sys/lock.h * redefines them to nothing. Use low-level hw_lock_* instead. */ void kspin_init(struct kspin *spin); void kspin_done(struct kspin *spin); void kspin_lock(struct kspin *spin); void kspin_unlock(struct kspin *spin); int kspin_trylock(struct kspin *spin); #if XNU_SYNC_DEBUG /* * two functions below are for use in assertions */ /* true, iff spin-lock is locked by the current thread */ int kspin_islocked(struct kspin *spin); /* true, iff spin-lock is not locked by the current thread */ int kspin_isnotlocked(struct kspin *spin); #else #define kspin_islocked(s) (1) #define kspin_isnotlocked(s) (1) #endif /* ------------------------- semaphore ------------------------- */ struct ksem { struct kspin guard; struct wait_queue q; int value; #if XNU_SYNC_DEBUG unsigned magic; #endif }; void ksem_init(struct ksem *sem, int value); void ksem_done(struct ksem *sem); int ksem_up (struct ksem *sem, int value); void ksem_down(struct ksem *sem, int value); int ksem_trydown(struct ksem *sem, int value); /* ------------------------- mutex ------------------------- */ struct kmut { struct ksem s; #if XNU_SYNC_DEBUG unsigned magic; thread_t owner; #endif }; void kmut_init(struct kmut *mut); void kmut_done(struct kmut *mut); void kmut_lock (struct kmut *mut); void kmut_unlock (struct kmut *mut); int kmut_trylock(struct kmut *mut); #if XNU_SYNC_DEBUG /* * two functions below are for use in assertions */ /* true, iff mutex is locked by the current thread */ int kmut_islocked(struct kmut *mut); /* true, iff mutex is not locked by the current thread */ int kmut_isnotlocked(struct kmut *mut); #else #define kmut_islocked(m) (1) #define kmut_isnotlocked(m) (1) #endif /* ------------------------- condition variable ------------------------- */ struct kcond_link { struct kcond_link *next; struct ksem sem; }; struct kcond { struct kspin guard; struct kcond_link *waiters; #if XNU_SYNC_DEBUG unsigned magic; #endif }; void kcond_init(struct kcond *cond); void kcond_done(struct kcond *cond); void kcond_wait(struct kcond *cond, struct kspin *lock); void kcond_signal(struct kcond *cond); void kcond_broadcast(struct kcond *cond); void kcond_wait_guard(struct kcond *cond); void kcond_signal_guard(struct kcond *cond); void kcond_broadcast_guard(struct kcond *cond); /* ------------------------- read-write semaphore ------------------------- */ struct krw_sem { int count; struct kcond cond; #if XNU_SYNC_DEBUG unsigned magic; #endif }; void krw_sem_init(struct krw_sem *sem); void krw_sem_done(struct krw_sem *sem); void krw_sem_down_r(struct krw_sem *sem); int krw_sem_down_r_try(struct krw_sem *sem); void krw_sem_down_w(struct krw_sem *sem); int krw_sem_down_w_try(struct krw_sem *sem); void krw_sem_up_r(struct krw_sem *sem); void krw_sem_up_w(struct krw_sem *sem); /* ------------------------- sleep-channel ------------------------- */ struct ksleep_chan { struct kspin guard; struct list_head waiters; #if XNU_SYNC_DEBUG unsigned magic; #endif }; #define KSLEEP_CHAN_INITIALIZER {{{0}}} struct ksleep_link { int flags; event_t event; int hits; struct ksleep_chan *forward; struct list_head linkage; #if XNU_SYNC_DEBUG unsigned magic; #endif }; enum { KSLEEP_EXCLUSIVE = 1 }; void ksleep_chan_init(struct ksleep_chan *chan); void ksleep_chan_done(struct ksleep_chan *chan); void ksleep_link_init(struct ksleep_link *link); void ksleep_link_done(struct ksleep_link *link); void ksleep_add(struct ksleep_chan *chan, struct ksleep_link *link); void ksleep_del(struct ksleep_chan *chan, struct ksleep_link *link); void ksleep_wait(struct ksleep_chan *chan); int64_t ksleep_timedwait(struct ksleep_chan *chan, uint64_t timeout); void ksleep_wake(struct ksleep_chan *chan); void ksleep_wake_all(struct ksleep_chan *chan); void ksleep_wake_nr(struct ksleep_chan *chan, int nr); #define KSLEEP_LINK_DECLARE(name) \ { \ .flags = 0, \ .event = 0, \ .hits = 0, \ .linkage = PTL_LIST_HEAD_INIT(name.linkage), \ .magic = KSLEEP_LINK_MAGIC \ } /* ------------------------- timer ------------------------- */ struct ktimer { struct kspin guard; void (*func)(void *); void *arg; u_int64_t deadline; /* timer deadline in absolute nanoseconds */ int armed; #if XNU_SYNC_DEBUG unsigned magic; #endif }; void ktimer_init(struct ktimer *t, void (*func)(void *), void *arg); void ktimer_done(struct ktimer *t); void ktimer_arm(struct ktimer *t, u_int64_t deadline); void ktimer_disarm(struct ktimer *t); int ktimer_is_armed(struct ktimer *t); u_int64_t ktimer_deadline(struct ktimer *t); /* __XNU_SYNC_H__ */ #endif /* * Local variables: * c-indentation-style: "K&R" * c-basic-offset: 8 * tab-width: 8 * fill-column: 80 * scroll-step: 1 * End: */