macos-104-not-yet-20050508
[openafs.git] / src / rx / DARWIN / rx_kmutex.h
1 /*
2  * Copyright 2000, International Business Machines Corporation and others.
3  * All Rights Reserved.
4  * 
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
8  */
9
10 /*
11  * rx_kmutex.h - mutex and condition variable macros for kernel environment.
12  *
13  * MACOS implementation.
14  */
15
16 #ifndef _RX_KMUTEX_H_
17 #define _RX_KMUTEX_H_
18
19 #include <sys/lock.h>
20 #include <kern/thread.h>
21 #include <sys/vm.h>
22
23 #define RX_ENABLE_LOCKS         1
24 #define AFS_GLOBAL_RXLOCK_KERNEL
25
26 /*
27  * Condition variables
28  *
29  * In Digital Unix (OSF/1), we use something akin to the ancient sleep/wakeup
30  * mechanism.  The condition variable itself plays no role; we just use its
31  * address as a convenient unique number.
32  * 
33  * XXX in darwin, both mach and bsd facilities are available. Should really
34  * stick to one or the other (but mach locks don't have a _try.....)
35  */
36 #define CV_INIT(cv,a,b,c)
37 #define CV_DESTROY(cv)
38 #ifdef AFS_DARWIN14_ENV
39 #define CV_WAIT(cv, lck)    { \
40                                 int isGlockOwner = ISAFS_GLOCK(); \
41                                 if (isGlockOwner) AFS_GUNLOCK();  \
42                                 MUTEX_EXIT(lck);        \
43                                 sleep(cv, PVFS);                \
44                                 if (isGlockOwner) AFS_GLOCK();  \
45                                 MUTEX_ENTER(lck); \
46                             }
47
48 #define CV_TIMEDWAIT(cv,lck,t)  { \
49                                 int isGlockOwner = ISAFS_GLOCK(); \
50                                 if (isGlockOwner) AFS_GUNLOCK();  \
51                                 MUTEX_EXIT(lck);        \
52                                 tsleep(cv,PVFS, "afs_CV_TIMEDWAIT",t);  \
53                                 if (isGlockOwner) AFS_GLOCK();  \
54                                 MUTEX_ENTER(lck);       \
55                             }
56
57 #define CV_SIGNAL(cv)           wakeup_one(cv)
58 #define CV_BROADCAST(cv)        wakeup(cv)
59 #else
60 #define CV_WAIT(cv, lck)    { \
61                                 int isGlockOwner = ISAFS_GLOCK(); \
62                                 if (isGlockOwner) AFS_GUNLOCK();  \
63                                 assert_wait((event_t)(cv), 0);  \
64                                 MUTEX_EXIT(lck);        \
65                                 thread_block(0);                \
66                                 if (isGlockOwner) AFS_GLOCK();  \
67                                 MUTEX_ENTER(lck); \
68                             }
69
70 #define CV_TIMEDWAIT(cv,lck,t)  { \
71                                 int isGlockOwner = ISAFS_GLOCK(); \
72                                 if (isGlockOwner) AFS_GUNLOCK();  \
73                                 assert_wait((event_t)(cv), 0);  \
74                                 thread_set_timer(t, NSEC_PER_SEC/hz);   \
75                                 MUTEX_EXIT(lck);        \
76                                 thread_block(0);                \
77                                 if (isGlockOwner) AFS_GLOCK();  \
78                                 MUTEX_ENTER(lck);       \
79                                 }
80
81 #define CV_SIGNAL(cv)           thread_wakeup_one((event_t)(cv))
82 #define CV_BROADCAST(cv)        thread_wakeup((event_t)(cv))
83 #endif
84
85 #ifdef AFS_DARWIN80_ENV
86 typedef struct {
87     lck_mtx_t *lock;
88     thread_t owner;
89 } afs_kmutex_t;
90 typedef int afs_kcondvar_t;
91
92 extern lck_grp_t * openafs_lck_grp;
93
94 #define MUTEX_SETUP() rx_kmutex_setup()
95 #define MUTEX_FINISH() rx_kmutex_finish()
96 #define LOCKINIT(a) \
97     do { \
98         lck_attr_t * openafs_lck_attr = lck_attr_alloc_init(); \
99         (a) = lck_mtx_alloc_init(openafs_lck_grp, openafs_lck_attr); \
100         lck_attr_free(openafs_lck_attr); \
101     } while(0);
102 #define MUTEX_INIT(a,b,c,d) \
103     do { \
104         lck_attr_t * openafs_lck_attr = lck_attr_alloc_init(); \
105         (a)->lock = lck_mtx_alloc_init(openafs_lck_grp, openafs_lck_attr); \
106         lck_attr_free(openafs_lck_attr); \
107         (a)->owner = (thread_t)0; \
108     } while(0);
109 #define MUTEX_DESTROY(a) \
110     do { \
111         lck_mtx_destroy((a)->lock, openafs_lck_grp); \
112         (a)->owner = (thread_t)-1; \
113     } while(0);
114 #define MUTEX_ENTER(a) \
115     do { \
116         lck_mtx_lock(&(a)->lock); \
117         osi_Assert((a)->owner == (thread_t)0); \
118         (a)->owner = current_thread(); \
119     } while(0);
120 #define MUTEX_TRYENTER(a) \
121         (lck_mtx_try_lock(&(a)->lock) ? ((a)->owner = current_thread(), 1) : 0)
122 #define MUTEX_EXIT(a) \
123     do { \
124         osi_Assert((a)->owner == current_thread()); \
125         (a)->owner = (thread_t)0; \
126         lck_mtx_unlock(&(a)->lock); \
127     } while(0);
128
129 #undef MUTEX_ISMINE
130 #define MUTEX_ISMINE(a) (((afs_kmutex_t *)(a))->owner == current_thread())
131 #else
132 typedef struct {
133     struct lock__bsd__ lock;
134     thread_t owner;
135 } afs_kmutex_t;
136 typedef int afs_kcondvar_t;
137
138 #define LOCK_INIT(a,b) \
139     do { \
140         lockinit(&(a)->lock,PSOCK, "afs rx lock", 0, 0); \
141         (a)->owner = (thread_t)0; \
142     } while(0);
143 #define MUTEX_INIT(a,b,c,d) \
144     do { \
145         lockinit(&(a)->lock,PSOCK, "afs rx mutex", 0, 0); \
146         (a)->owner = (thread_t)0; \
147     } while(0);
148 #define MUTEX_DESTROY(a) \
149     do { \
150         (a)->owner = (thread_t)-1; \
151     } while(0);
152 #define MUTEX_ENTER(a) \
153     do { \
154         lockmgr(&(a)->lock, LK_EXCLUSIVE, 0, current_proc()); \
155         osi_Assert((a)->owner == (thread_t)0); \
156         (a)->owner = current_thread(); \
157     } while(0);
158 #define MUTEX_TRYENTER(a) \
159     ( lockmgr(&(a)->lock, LK_EXCLUSIVE|LK_NOWAIT, 0, current_proc()) ? 0 : ((a)->owner = current_thread(), 1) )
160 #define MUTEX_EXIT(a) \
161     do { \
162         osi_Assert((a)->owner == current_thread()); \
163         (a)->owner = (thread_t)0; \
164         lockmgr(&(a)->lock, LK_RELEASE, 0, current_proc()); \
165     } while(0);
166
167 #undef MUTEX_ISMINE
168 #define MUTEX_ISMINE(a) (((afs_kmutex_t *)(a))->owner == current_thread())
169 #endif
170
171 #undef osirx_AssertMine
172 extern void osirx_AssertMine(afs_kmutex_t * lockaddr, char *msg);
173
174 #endif /* _RX_KMUTEX_H_ */