OpenAFS
OpenAFS distributed network file system
|
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_ */