OpenAFS
OpenAFS distributed network file system
/cygdrive/c/src/openafs/openafs.git/repo/src/rx/NBSD/rx_kmutex.h
00001 /*
00002  * Copyright 2000, International Business Machines Corporation and others.
00003  * All Rights Reserved.
00004  *
00005  * This software has been released under the terms of the IBM Public
00006  * License.  For details, see the LICENSE file in the top-level source
00007  * directory or online at http://www.openafs.org/dl/license10.html
00008  */
00009 
00010 /*
00011  * rx_kmutex.h - mutex and condition variable macros for kernel environment.
00012  *
00013  * Based to the degree possible on FreeBSD implementation (which is by
00014  * Garrett Wollman (?) and Jim Rees).  I couldn't rework it as I did for
00015  * FreeBSD, because NetBSD doesn't have anything like FreeBSD's  new
00016  * locking primitives.  So anyway, these are potentially heavier locks than
00017  * the *ahem* locking Jim had in the OpenBSD port, although it looks as
00018  * if struct lock is evolving into an adaptive mutex implementation (see
00019  * LOCK(9)), which should be reasonable for the code we have today.  The
00020  * available optimization would be to replace such a lock with a simple_lock
00021  * any place we only consider the current CPU, and could not sleep
00022  * (Matt).
00023  */
00024 
00025 #ifndef _RX_KMUTEX_H_
00026 #define _RX_KMUTEX_H_
00027 
00028 #ifdef AFS_NBSD50_ENV
00029 #include <sys/mutex.h>
00030 #include <sys/condvar.h>
00031 #else
00032 #include <sys/lock.h>
00033 #endif
00034 
00035 /* You can't have AFS_GLOBAL_SUNLOCK and not RX_ENABLE_LOCKS */
00036 #define RX_ENABLE_LOCKS 1
00037 #define AFS_GLOBAL_RXLOCK_KERNEL
00038 
00039 #if defined(AFS_NBSD50_ENV)
00040 typedef kmutex_t afs_kmutex_t;
00041 
00042 #define MUTEX_INIT(a,b,c,d) mutex_init((a), (c), IPL_NONE)
00043 #define MUTEX_DESTROY(a) mutex_destroy((a))
00044 #define MUTEX_ENTER(a) mutex_enter((a));
00045 #define MUTEX_TRYENTER(a) mutex_tryenter((a))
00046 #define MUTEX_EXIT(a) mutex_exit((a))
00047 #define MUTEX_ISMINE(a) mutex_owned((a))
00048 
00049 typedef kcondvar_t afs_kcondvar_t;
00050 int afs_cv_wait(afs_kcondvar_t *, afs_kmutex_t *, int);
00051 
00052 #define CV_INIT(a, b, c, d) cv_init(a, b)
00053 #define CV_DESTROY(a) cv_destroy(a)
00054 #define CV_SIGNAL(a) cv_signal(a)
00055 #define CV_BROADCAST(a) cv_broadcast(a)
00056 #define CV_WAIT(a, b) afs_cv_wait(a, b, 0)
00057 #define CV_WAIT_SIG  afs_cv_wait(a, b, 1)
00058 
00059 #else
00060 
00061 /*
00062  * Condition variables
00063  *
00064  * In Digital Unix (OSF/1), we use something akin to the ancient sleep/wakeup
00065  * mechanism.  The condition variable itself plays no role; we just use its
00066  * address as a convenient unique number.  NetBSD has some improvements in
00067  * its versions of these mechanisms.
00068  */
00069 #define CV_INIT(cv, a, b, c)
00070 #define CV_DESTROY(cv)
00071 #define CV_WAIT(cv, lck)    { \
00072         struct simplelock slock = SIMPLELOCK_INITIALIZER;               \
00073         simple_lock(&slock);                                            \
00074         int glocked = ISAFS_GLOCK();                                    \
00075         if (glocked)                                                    \
00076             AFS_GUNLOCK();                                              \
00077         MUTEX_EXIT(lck);                                                \
00078         ltsleep(cv, PSOCK, "afs_rx_cv_wait", 0, &slock);                \
00079         if (glocked)                                                    \
00080             AFS_GLOCK();                                                \
00081         MUTEX_ENTER(lck);                                               \
00082         simple_unlock(&slock);                                          \
00083     }
00084 
00085 #define CV_TIMEDWAIT(cv, lck, t)  {                                     \
00086         struct simplelock slock = SIMPLELOCK_INITIALIZER;               \
00087         simple_lock(&slock);                                            \
00088         int glocked = ISAFS_GLOCK();                                    \
00089         if (glocked)                                                    \
00090             AFS_GUNLOCK();                                              \
00091         MUTEX_EXIT(lck);                                                \
00092         tsleep(cv, PSOCK, "afs_rx_cv_timedwait", t, &slock);            \
00093         if (glocked)                                                    \
00094             AFS_GLOCK();                                                \
00095         MUTEX_ENTER(lck);                                               \
00096         simple_unlock(&slock);                                          \
00097     }
00098 
00099 #define CV_SIGNAL(cv)           wakeup_one(cv)
00100 #define CV_BROADCAST(cv)        wakeup(cv)
00101 
00102 #define osi_rxWakeup(cv)        wakeup(cv)
00103 typedef int afs_kcondvar_t;
00104 
00105 typedef struct {
00106     struct lock lock;
00107     struct lwp *owner;
00108 } afs_kmutex_t;
00109 
00110 #define MUTEX_INIT(a,b,c,d) \
00111     do { \
00112         lockinit(&(a)->lock, PSOCK, "afs rx mutex", 0, 0); \
00113         (a)->owner = 0; \
00114     } while(0);
00115 #define MUTEX_DESTROY(a) \
00116     do { \
00117         (a)->owner = (struct lwp *)-1; \
00118     } while(0);
00119 #if defined(LOCKDEBUG)
00120 #define MUTEX_ENTER(a) \
00121     do { \
00122         _lockmgr(&(a)->lock, LK_EXCLUSIVE, 0, __FILE__, __LINE__); \
00123         osi_Assert((a)->owner == 0); \
00124         (a)->owner = curlwp; \
00125     } while(0);
00126 #define MUTEX_TRYENTER(a) \
00127     ( _lockmgr(&(a)->lock, LK_EXCLUSIVE | LK_NOWAIT, 0, __FILE__, __LINE__) ? 0 \
00128       : ((a)->owner = curlwp, 1) )
00129 #define MUTEX_EXIT(a) \
00130     do { \
00131         osi_Assert((a)->owner == curlwp); \
00132         (a)->owner = 0; \
00133         _lockmgr(&(a)->lock, LK_RELEASE, 0, __FILE__, __LINE__); \
00134     } while(0);
00135 #else
00136 #define MUTEX_ENTER(a) \
00137     do { \
00138         lockmgr(&(a)->lock, LK_EXCLUSIVE, 0); \
00139         osi_Assert((a)->owner == 0); \
00140         (a)->owner = curlwp; \
00141     } while(0);
00142 #define MUTEX_TRYENTER(a) \
00143     ( lockmgr(&(a)->lock, LK_EXCLUSIVE | LK_NOWAIT, 0) ? 0 \
00144       : ((a)->owner = curlwp, 1) )
00145 #define MUTEX_EXIT(a) \
00146     do { \
00147         osi_Assert((a)->owner == curlwp); \
00148         (a)->owner = 0; \
00149         lockmgr(&(a)->lock, LK_RELEASE, 0); \
00150     } while(0);
00151 #endif  /* LOCKDEBUG */
00152 
00153 #define MUTEX_ISMINE(a) \
00154     (lockstatus(a) == LK_EXCLUSIVE)
00155 #define MUTEX_LOCKED(a) \
00156     (lockstatus(a) == LK_EXCLUSIVE)
00157 
00158 #endif  /* AFS_NBSD50_ENV */
00159 
00160 #endif /* _RX_KMUTEX_H_ */
 All Data Structures Files Functions Variables