2 * Copyright 2000, International Business Machines Corporation and others.
5 * This software has been released under the terms of the IBM Public
6 * License. For details, see the LICENSE file in the top-level source
7 * directory or online at http://www.openafs.org/dl/license10.html
11 * rx_kmutex.h - mutex and condition variable macros for kernel environment.
13 * MACOS implementation.
19 #ifdef AFS_DARWIN80_ENV
20 #include <kern/locks.h>
24 #include <kern/thread.h>
27 #define RX_ENABLE_LOCKS 1
28 #define AFS_GLOBAL_RXLOCK_KERNEL
33 * In Digital Unix (OSF/1), we use something akin to the ancient sleep/wakeup
34 * mechanism. The condition variable itself plays no role; we just use its
35 * address as a convenient unique number.
37 * XXX in darwin, both mach and bsd facilities are available. Should really
38 * stick to one or the other (but mach locks don't have a _try.....)
40 * in darwin 8.0, the bsd lock facility is no longer available, and only one
41 * sleep variant is available. Still no lock_try, but we can work around that.
42 * We can't pass the mutex into msleep, even if we didn't need the two mutex
43 * hack for lock_try emulation, since msleep won't fixup the owner variable
46 #define CV_INIT(cv,a,b,c)
47 #define CV_DESTROY(cv)
48 #ifdef AFS_DARWIN14_ENV
49 #ifdef AFS_DARWIN80_ENV
50 #define VFSSLEEP(cv) msleep(cv, NULL, PVFS, "afs_CV_WAIT", NULL)
51 #define VFSTSLEEP(cv,t) do { \
55 msleep(cv, NULL, PVFS, "afs_CV_TIMEDWAIT", &ts); \
58 #define VFSSLEEP(cv) sleep(cv, PVFS)
59 #define VFSTSLEEP(cv, t) tsleep(cv,PVFS, "afs_CV_TIMEDWAIT",t)
61 #define CV_WAIT(cv, lck) do { \
62 int isGlockOwner = ISAFS_GLOCK(); \
63 if (isGlockOwner) AFS_GUNLOCK(); \
66 if (isGlockOwner) AFS_GLOCK(); \
70 #define CV_TIMEDWAIT(cv,lck,t) do { \
71 int isGlockOwner = ISAFS_GLOCK(); \
72 if (isGlockOwner) AFS_GUNLOCK(); \
75 if (isGlockOwner) AFS_GLOCK(); \
79 #define CV_SIGNAL(cv) wakeup_one((void *)(cv))
80 #define CV_BROADCAST(cv) wakeup((void *)(cv))
82 #define CV_WAIT(cv, lck) { \
83 int isGlockOwner = ISAFS_GLOCK(); \
84 if (isGlockOwner) AFS_GUNLOCK(); \
85 assert_wait((event_t)(cv), 0); \
88 if (isGlockOwner) AFS_GLOCK(); \
92 #define CV_TIMEDWAIT(cv,lck,t) { \
93 int isGlockOwner = ISAFS_GLOCK(); \
94 if (isGlockOwner) AFS_GUNLOCK(); \
95 assert_wait((event_t)(cv), 0); \
96 thread_set_timer(t, NSEC_PER_SEC/hz); \
99 if (isGlockOwner) AFS_GLOCK(); \
103 #define CV_SIGNAL(cv) thread_wakeup_one((event_t)(cv))
104 #define CV_BROADCAST(cv) thread_wakeup((event_t)(cv))
107 #ifdef AFS_DARWIN80_ENV
110 int waiters; /* also includes anyone holding the lock */
114 typedef int afs_kcondvar_t;
116 extern lck_grp_t * openafs_lck_grp;
118 #define MUTEX_SETUP() rx_kmutex_setup()
119 #define MUTEX_FINISH() rx_kmutex_finish()
120 #define LOCKINIT(a) \
122 lck_attr_t *openafs_lck_attr = lck_attr_alloc_init(); \
123 (a) = lck_mtx_alloc_init(openafs_lck_grp, openafs_lck_attr); \
124 lck_attr_free(openafs_lck_attr); \
126 #define MUTEX_INIT(a,b,c,d) \
128 lck_attr_t *openafs_lck_attr = lck_attr_alloc_init(); \
129 (a)->meta = lck_mtx_alloc_init(openafs_lck_grp, openafs_lck_attr); \
130 (a)->lock = lck_mtx_alloc_init(openafs_lck_grp, openafs_lck_attr); \
131 lck_attr_free(openafs_lck_attr); \
133 (a)->owner = (thread_t)0; \
135 #define MUTEX_DESTROY(a) \
137 lck_mtx_destroy((a)->lock, openafs_lck_grp); \
138 lck_mtx_destroy((a)->meta, openafs_lck_grp); \
139 (a)->owner = (thread_t)-1; \
141 #define MUTEX_ENTER(a) \
143 lck_mtx_lock((a)->meta); \
145 lck_mtx_unlock((a)->meta); \
146 lck_mtx_lock((a)->lock); \
147 osi_Assert((a)->owner == (thread_t)0); \
148 (a)->owner = current_thread(); \
151 /* acquire main lock before releasing meta lock, so we don't race */
152 #define MUTEX_TRYENTER(a) ({ \
154 lck_mtx_lock((a)->meta); \
155 if ((a)->waiters) { \
156 lck_mtx_unlock((a)->meta); \
160 lck_mtx_lock((a)->lock); \
161 lck_mtx_unlock((a)->meta); \
162 osi_Assert((a)->owner == (thread_t)0); \
163 (a)->owner = current_thread(); \
169 #define MUTEX_EXIT(a) \
171 osi_Assert((a)->owner == current_thread()); \
172 (a)->owner = (thread_t)0; \
173 lck_mtx_unlock((a)->lock); \
174 lck_mtx_lock((a)->meta); \
176 lck_mtx_unlock((a)->meta); \
180 #define MUTEX_ISMINE(a) (((afs_kmutex_t *)(a))->owner == current_thread())
183 struct lock__bsd__ lock;
186 typedef int afs_kcondvar_t;
188 #define LOCK_INIT(a,b) \
190 lockinit(&(a)->lock,PSOCK, "afs rx lock", 0, 0); \
191 (a)->owner = (thread_t)0; \
193 #define MUTEX_INIT(a,b,c,d) \
195 lockinit(&(a)->lock,PSOCK, "afs rx mutex", 0, 0); \
196 (a)->owner = (thread_t)0; \
198 #define MUTEX_DESTROY(a) \
200 (a)->owner = (thread_t)-1; \
202 #define MUTEX_ENTER(a) \
204 lockmgr(&(a)->lock, LK_EXCLUSIVE, 0, current_proc()); \
205 osi_Assert((a)->owner == (thread_t)0); \
206 (a)->owner = current_thread(); \
208 #define MUTEX_TRYENTER(a) \
209 ( lockmgr(&(a)->lock, LK_EXCLUSIVE|LK_NOWAIT, 0, current_proc()) ? 0 : ((a)->owner = current_thread(), 1) )
210 #define MUTEX_EXIT(a) \
212 osi_Assert((a)->owner == current_thread()); \
213 (a)->owner = (thread_t)0; \
214 lockmgr(&(a)->lock, LK_RELEASE, 0, current_proc()); \
218 #define MUTEX_ISMINE(a) (((afs_kmutex_t *)(a))->owner == current_thread())
221 #undef osirx_AssertMine
222 extern void osirx_AssertMine(afs_kmutex_t * lockaddr, char *msg);
224 #endif /* _RX_KMUTEX_H_ */