OpenAFS
OpenAFS distributed network file system
/cygdrive/c/src/openafs/openafs.git/repo/src/rx/DARWIN/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  * 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_ */
 All Data Structures Files Functions Variables