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>
21 /* kernel private from osfmk/kern/locks.h ... sigh */
22 extern boolean_t
lck_mtx_try_lock(lck_mtx_t
*lck
);
23 extern boolean_t
lck_rw_try_lock(lck_rw_t
*lck
, lck_rw_type_t lck_rw_type
);
27 #include <kern/thread.h>
30 #define RX_ENABLE_LOCKS 1
35 * In Digital Unix (OSF/1), we use something akin to the ancient sleep/wakeup
36 * mechanism. The condition variable itself plays no role; we just use its
37 * address as a convenient unique number.
39 * XXX in darwin, both mach and bsd facilities are available. Should really
40 * stick to one or the other (but mach locks don't have a _try.....)
42 * in darwin 8.0, the bsd lock facility is no longer available, and only one
43 * sleep variant is available. Still no lock_try, but we can work around that.
44 * We can't pass the mutex into msleep, even if we didn't need the two mutex
45 * hack for lock_try emulation, since msleep won't fixup the owner variable
48 #define CV_INIT(cv,a,b,c)
49 #define CV_DESTROY(cv)
50 #ifdef AFS_DARWIN80_ENV
51 #define CV_WAIT(cv, lck) do { \
52 int isGlockOwner = ISAFS_GLOCK(); \
53 if (isGlockOwner) AFS_GUNLOCK(); \
54 osi_Assert((lck)->owner == current_thread()); \
55 (lck)->owner = (thread_t)0; \
56 lck_mtx_lock((lck)->meta); \
58 lck_mtx_unlock((lck)->meta); \
59 msleep(cv, (lck)->lock, PDROP|PVFS, "afs_CV_WAIT", NULL); \
60 if (isGlockOwner) AFS_GLOCK(); \
64 #define CV_TIMEDWAIT(cv,lck,t) do { \
66 int isGlockOwner = ISAFS_GLOCK(); \
69 if (isGlockOwner) AFS_GUNLOCK(); \
70 osi_Assert((lck)->owner == current_thread()); \
71 (lck)->owner = (thread_t)0; \
72 lck_mtx_lock((lck)->meta); \
74 lck_mtx_unlock((lck)->meta); \
75 msleep(cv, (lck)->lock, PDROP|PVFS, "afs_CV_TIMEDWAIT", &ts); \
76 if (isGlockOwner) AFS_GLOCK(); \
80 #define CV_WAIT(cv, lck) do { \
81 int isGlockOwner = ISAFS_GLOCK(); \
82 if (isGlockOwner) AFS_GUNLOCK(); \
85 if (isGlockOwner) AFS_GLOCK(); \
89 #define CV_TIMEDWAIT(cv,lck,t) do { \
90 int isGlockOwner = ISAFS_GLOCK(); \
91 if (isGlockOwner) AFS_GUNLOCK(); \
93 tsleep(cv,PVFS, "afs_CV_TIMEDWAIT",t); \
94 if (isGlockOwner) AFS_GLOCK(); \
98 #define CV_SIGNAL(cv) wakeup_one((void *)(cv))
99 #define CV_BROADCAST(cv) wakeup((void *)(cv))
101 #ifdef AFS_DARWIN80_ENV
104 int waiters
; /* also includes anyone holding the lock */
108 typedef int afs_kcondvar_t
;
110 extern lck_grp_t
* openafs_lck_grp
;
112 #define MUTEX_SETUP() rx_kmutex_setup()
113 #define MUTEX_FINISH() rx_kmutex_finish()
114 #define LOCKINIT(a) \
116 lck_attr_t *openafs_lck_attr = lck_attr_alloc_init(); \
117 (a) = lck_mtx_alloc_init(openafs_lck_grp, openafs_lck_attr); \
118 lck_attr_free(openafs_lck_attr); \
120 #define MUTEX_INIT(a,b,c,d) \
122 lck_attr_t *openafs_lck_attr = lck_attr_alloc_init(); \
123 (a)->meta = lck_mtx_alloc_init(openafs_lck_grp, openafs_lck_attr); \
124 (a)->lock = lck_mtx_alloc_init(openafs_lck_grp, openafs_lck_attr); \
125 lck_attr_free(openafs_lck_attr); \
127 (a)->owner = (thread_t)0; \
129 #define MUTEX_DESTROY(a) \
131 lck_mtx_destroy((a)->lock, openafs_lck_grp); \
132 lck_mtx_destroy((a)->meta, openafs_lck_grp); \
133 (a)->owner = (thread_t)-1; \
135 #define MUTEX_ENTER(a) \
137 lck_mtx_lock((a)->meta); \
139 lck_mtx_unlock((a)->meta); \
140 lck_mtx_lock((a)->lock); \
141 osi_Assert((a)->owner == (thread_t)0); \
142 (a)->owner = current_thread(); \
145 /* acquire main lock before releasing meta lock, so we don't race */
146 #define MUTEX_TRYENTER(a) ({ \
148 lck_mtx_lock((a)->meta); \
149 if ((a)->waiters) { \
150 lck_mtx_unlock((a)->meta); \
154 lck_mtx_lock((a)->lock); \
155 lck_mtx_unlock((a)->meta); \
156 osi_Assert((a)->owner == (thread_t)0); \
157 (a)->owner = current_thread(); \
163 #define MUTEX_EXIT(a) \
165 osi_Assert((a)->owner == current_thread()); \
166 (a)->owner = (thread_t)0; \
167 lck_mtx_unlock((a)->lock); \
168 lck_mtx_lock((a)->meta); \
170 lck_mtx_unlock((a)->meta); \
173 #define MUTEX_ASSERT(a) osi_Assert(((afs_kmutex_t *)(a))->owner == current_thread())
176 struct lock__bsd__ lock
;
179 typedef int afs_kcondvar_t
;
181 #define LOCK_INIT(a,b) \
183 lockinit(&(a)->lock,PSOCK, "afs rx lock", 0, 0); \
184 (a)->owner = (thread_t)0; \
186 #define MUTEX_INIT(a,b,c,d) \
188 lockinit(&(a)->lock,PSOCK, "afs rx mutex", 0, 0); \
189 (a)->owner = (thread_t)0; \
191 #define MUTEX_DESTROY(a) \
193 (a)->owner = (thread_t)-1; \
195 #define MUTEX_ENTER(a) \
197 lockmgr(&(a)->lock, LK_EXCLUSIVE, 0, current_proc()); \
198 osi_Assert((a)->owner == (thread_t)0); \
199 (a)->owner = current_thread(); \
201 #define MUTEX_TRYENTER(a) \
202 ( lockmgr(&(a)->lock, LK_EXCLUSIVE|LK_NOWAIT, 0, current_proc()) ? 0 : ((a)->owner = current_thread(), 1) )
203 #define MUTEX_EXIT(a) \
205 osi_Assert((a)->owner == current_thread()); \
206 (a)->owner = (thread_t)0; \
207 lockmgr(&(a)->lock, LK_RELEASE, 0, current_proc()); \
210 #define MUTEX_ASSERT(a) osi_Assert(((afs_kmutex_t *)(a))->owner == current_thread())
213 #endif /* _RX_KMUTEX_H_ */