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 * MACOS implementation. 00014 */ 00015 00016 #ifndef _RX_KMUTEX_H_ 00017 #define _RX_KMUTEX_H_ 00018 00019 #ifdef AFS_DARWIN80_ENV 00020 #include <kern/locks.h> 00021 /* kernel private from osfmk/kern/locks.h ... sigh */ 00022 extern boolean_t lck_mtx_try_lock(lck_mtx_t *lck); 00023 extern boolean_t lck_rw_try_lock(lck_rw_t *lck, lck_rw_type_t lck_rw_type); 00024 #else 00025 #include <sys/lock.h> 00026 #endif 00027 #include <kern/thread.h> 00028 #include <sys/vm.h> 00029 00030 #define RX_ENABLE_LOCKS 1 00031 #define AFS_GLOBAL_RXLOCK_KERNEL 00032 00033 /* 00034 * Condition variables 00035 * 00036 * In Digital Unix (OSF/1), we use something akin to the ancient sleep/wakeup 00037 * mechanism. The condition variable itself plays no role; we just use its 00038 * address as a convenient unique number. 00039 * 00040 * XXX in darwin, both mach and bsd facilities are available. Should really 00041 * stick to one or the other (but mach locks don't have a _try.....) 00042 * 00043 * in darwin 8.0, the bsd lock facility is no longer available, and only one 00044 * sleep variant is available. Still no lock_try, but we can work around that. 00045 * We can't pass the mutex into msleep, even if we didn't need the two mutex 00046 * hack for lock_try emulation, since msleep won't fixup the owner variable 00047 * and we'll panic. 00048 */ 00049 #define CV_INIT(cv,a,b,c) 00050 #define CV_DESTROY(cv) 00051 #ifdef AFS_DARWIN80_ENV 00052 #define CV_WAIT(cv, lck) do { \ 00053 int isGlockOwner = ISAFS_GLOCK(); \ 00054 if (isGlockOwner) AFS_GUNLOCK(); \ 00055 osi_Assert((lck)->owner == current_thread()); \ 00056 (lck)->owner = (thread_t)0; \ 00057 lck_mtx_lock((lck)->meta); \ 00058 (lck)->waiters--; \ 00059 lck_mtx_unlock((lck)->meta); \ 00060 msleep(cv, (lck)->lock, PDROP|PVFS, "afs_CV_WAIT", NULL); \ 00061 if (isGlockOwner) AFS_GLOCK(); \ 00062 MUTEX_ENTER(lck); \ 00063 } while(0) 00064 00065 #define CV_TIMEDWAIT(cv,lck,t) do { \ 00066 struct timespec ts; \ 00067 int isGlockOwner = ISAFS_GLOCK(); \ 00068 ts.ts_sec = t; \ 00069 ts.ts_nsec = 0; \ 00070 if (isGlockOwner) AFS_GUNLOCK(); \ 00071 osi_Assert((lck)->owner == current_thread()); \ 00072 (lck)->owner = (thread_t)0; \ 00073 lck_mtx_lock((lck)->meta); \ 00074 (lck)->waiters--; \ 00075 lck_mtx_unlock((lck)->meta); \ 00076 msleep(cv, (lck)->lock, PDROP|PVFS, "afs_CV_TIMEDWAIT", &ts); \ 00077 if (isGlockOwner) AFS_GLOCK(); \ 00078 MUTEX_ENTER(lck); \ 00079 } while(0) 00080 #else 00081 #define CV_WAIT(cv, lck) do { \ 00082 int isGlockOwner = ISAFS_GLOCK(); \ 00083 if (isGlockOwner) AFS_GUNLOCK(); \ 00084 MUTEX_EXIT(lck); \ 00085 sleep(cv, PVFS); \ 00086 if (isGlockOwner) AFS_GLOCK(); \ 00087 MUTEX_ENTER(lck); \ 00088 } while(0) 00089 00090 #define CV_TIMEDWAIT(cv,lck,t) do { \ 00091 int isGlockOwner = ISAFS_GLOCK(); \ 00092 if (isGlockOwner) AFS_GUNLOCK(); \ 00093 MUTEX_EXIT(lck); \ 00094 tsleep(cv,PVFS, "afs_CV_TIMEDWAIT",t); \ 00095 if (isGlockOwner) AFS_GLOCK(); \ 00096 MUTEX_ENTER(lck); \ 00097 } while(0) 00098 #endif 00099 #define CV_SIGNAL(cv) wakeup_one((void *)(cv)) 00100 #define CV_BROADCAST(cv) wakeup((void *)(cv)) 00101 00102 #ifdef AFS_DARWIN80_ENV 00103 typedef struct { 00104 lck_mtx_t *meta; 00105 int waiters; /* also includes anyone holding the lock */ 00106 lck_mtx_t *lock; 00107 thread_t owner; 00108 } afs_kmutex_t; 00109 typedef int afs_kcondvar_t; 00110 00111 extern lck_grp_t * openafs_lck_grp; 00112 00113 #define MUTEX_SETUP() rx_kmutex_setup() 00114 #define MUTEX_FINISH() rx_kmutex_finish() 00115 #define LOCKINIT(a) \ 00116 do { \ 00117 lck_attr_t *openafs_lck_attr = lck_attr_alloc_init(); \ 00118 (a) = lck_mtx_alloc_init(openafs_lck_grp, openafs_lck_attr); \ 00119 lck_attr_free(openafs_lck_attr); \ 00120 } while(0) 00121 #define MUTEX_INIT(a,b,c,d) \ 00122 do { \ 00123 lck_attr_t *openafs_lck_attr = lck_attr_alloc_init(); \ 00124 (a)->meta = lck_mtx_alloc_init(openafs_lck_grp, openafs_lck_attr); \ 00125 (a)->lock = lck_mtx_alloc_init(openafs_lck_grp, openafs_lck_attr); \ 00126 lck_attr_free(openafs_lck_attr); \ 00127 (a)->waiters = 0; \ 00128 (a)->owner = (thread_t)0; \ 00129 } while(0) 00130 #define MUTEX_DESTROY(a) \ 00131 do { \ 00132 lck_mtx_destroy((a)->lock, openafs_lck_grp); \ 00133 lck_mtx_destroy((a)->meta, openafs_lck_grp); \ 00134 (a)->owner = (thread_t)-1; \ 00135 } while(0) 00136 #define MUTEX_ENTER(a) \ 00137 do { \ 00138 lck_mtx_lock((a)->meta); \ 00139 (a)->waiters++; \ 00140 lck_mtx_unlock((a)->meta); \ 00141 lck_mtx_lock((a)->lock); \ 00142 osi_Assert((a)->owner == (thread_t)0); \ 00143 (a)->owner = current_thread(); \ 00144 } while(0) 00145 00146 /* acquire main lock before releasing meta lock, so we don't race */ 00147 #define MUTEX_TRYENTER(a) ({ \ 00148 int _ret; \ 00149 lck_mtx_lock((a)->meta); \ 00150 if ((a)->waiters) { \ 00151 lck_mtx_unlock((a)->meta); \ 00152 _ret = 0; \ 00153 } else { \ 00154 (a)->waiters++; \ 00155 lck_mtx_lock((a)->lock); \ 00156 lck_mtx_unlock((a)->meta); \ 00157 osi_Assert((a)->owner == (thread_t)0); \ 00158 (a)->owner = current_thread(); \ 00159 _ret = 1; \ 00160 } \ 00161 _ret; \ 00162 }) 00163 00164 #define MUTEX_EXIT(a) \ 00165 do { \ 00166 osi_Assert((a)->owner == current_thread()); \ 00167 (a)->owner = (thread_t)0; \ 00168 lck_mtx_unlock((a)->lock); \ 00169 lck_mtx_lock((a)->meta); \ 00170 (a)->waiters--; \ 00171 lck_mtx_unlock((a)->meta); \ 00172 } while(0) 00173 00174 #undef MUTEX_ISMINE 00175 #define MUTEX_ISMINE(a) (((afs_kmutex_t *)(a))->owner == current_thread()) 00176 #else 00177 typedef struct { 00178 struct lock__bsd__ lock; 00179 thread_t owner; 00180 } afs_kmutex_t; 00181 typedef int afs_kcondvar_t; 00182 00183 #define LOCK_INIT(a,b) \ 00184 do { \ 00185 lockinit(&(a)->lock,PSOCK, "afs rx lock", 0, 0); \ 00186 (a)->owner = (thread_t)0; \ 00187 } while(0); 00188 #define MUTEX_INIT(a,b,c,d) \ 00189 do { \ 00190 lockinit(&(a)->lock,PSOCK, "afs rx mutex", 0, 0); \ 00191 (a)->owner = (thread_t)0; \ 00192 } while(0); 00193 #define MUTEX_DESTROY(a) \ 00194 do { \ 00195 (a)->owner = (thread_t)-1; \ 00196 } while(0); 00197 #define MUTEX_ENTER(a) \ 00198 do { \ 00199 lockmgr(&(a)->lock, LK_EXCLUSIVE, 0, current_proc()); \ 00200 osi_Assert((a)->owner == (thread_t)0); \ 00201 (a)->owner = current_thread(); \ 00202 } while(0); 00203 #define MUTEX_TRYENTER(a) \ 00204 ( lockmgr(&(a)->lock, LK_EXCLUSIVE|LK_NOWAIT, 0, current_proc()) ? 0 : ((a)->owner = current_thread(), 1) ) 00205 #define MUTEX_EXIT(a) \ 00206 do { \ 00207 osi_Assert((a)->owner == current_thread()); \ 00208 (a)->owner = (thread_t)0; \ 00209 lockmgr(&(a)->lock, LK_RELEASE, 0, current_proc()); \ 00210 } while(0); 00211 00212 #undef MUTEX_ISMINE 00213 #define MUTEX_ISMINE(a) (((afs_kmutex_t *)(a))->owner == current_thread()) 00214 #endif 00215 00216 #undef osirx_AssertMine 00217 extern void osirx_AssertMine(afs_kmutex_t * lockaddr, char *msg); 00218 00219 #endif /* _RX_KMUTEX_H_ */