Import Upstream version 1.8.5
[hcoop/debian/openafs.git] / src / rx / NBSD / 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 * Based to the degree possible on FreeBSD implementation (which is by
14 * Garrett Wollman (?) and Jim Rees). I couldn't rework it as I did for
15 * FreeBSD, because NetBSD doesn't have anything like FreeBSD's new
16 * locking primitives. So anyway, these are potentially heavier locks than
17 * the *ahem* locking Jim had in the OpenBSD port, although it looks as
18 * if struct lock is evolving into an adaptive mutex implementation (see
19 * LOCK(9)), which should be reasonable for the code we have today. The
20 * available optimization would be to replace such a lock with a simple_lock
21 * any place we only consider the current CPU, and could not sleep
22 * (Matt).
23 */
24
25 #ifndef _RX_KMUTEX_H_
26 #define _RX_KMUTEX_H_
27
28 #ifdef AFS_NBSD50_ENV
29 #include <sys/mutex.h>
30 #include <sys/condvar.h>
31 #else
32 #include <sys/lock.h>
33 #endif
34
35 /* You can't have AFS_GLOBAL_SUNLOCK and not RX_ENABLE_LOCKS */
36 #define RX_ENABLE_LOCKS 1
37
38 #if defined(AFS_NBSD50_ENV)
39 typedef kmutex_t afs_kmutex_t;
40
41 #define MUTEX_INIT(a,b,c,d) mutex_init((a), (c), IPL_NONE)
42 #define MUTEX_DESTROY(a) mutex_destroy((a))
43 #define MUTEX_ENTER(a) mutex_enter((a))
44 #define MUTEX_TRYENTER(a) mutex_tryenter((a))
45 #define MUTEX_EXIT(a) mutex_exit((a))
46 #define MUTEX_ASSERT(a) osi_Assert(mutex_owned((a)))
47
48 typedef kcondvar_t afs_kcondvar_t;
49 int afs_cv_wait(afs_kcondvar_t *, afs_kmutex_t *, int);
50
51 #define CV_INIT(a, b, c, d) cv_init(a, b)
52 #define CV_DESTROY(a) cv_destroy(a)
53 #define CV_SIGNAL(a) cv_signal(a)
54 #define CV_BROADCAST(a) cv_broadcast(a)
55 #define CV_WAIT(a, b) afs_cv_wait(a, b, 0)
56 #define CV_WAIT_SIG(a, b) afs_cv_wait(a, b, 1)
57
58 #else
59
60 /*
61 * Condition variables
62 *
63 * In Digital Unix (OSF/1), we use something akin to the ancient sleep/wakeup
64 * mechanism. The condition variable itself plays no role; we just use its
65 * address as a convenient unique number. NetBSD has some improvements in
66 * its versions of these mechanisms.
67 */
68 #define CV_INIT(cv, a, b, c)
69 #define CV_DESTROY(cv)
70 #define CV_WAIT(cv, lck) { \
71 struct simplelock slock = SIMPLELOCK_INITIALIZER; \
72 simple_lock(&slock); \
73 int glocked = ISAFS_GLOCK(); \
74 if (glocked) \
75 AFS_GUNLOCK(); \
76 MUTEX_EXIT(lck); \
77 ltsleep(cv, PSOCK, "afs_rx_cv_wait", 0, &slock); \
78 if (glocked) \
79 AFS_GLOCK(); \
80 MUTEX_ENTER(lck); \
81 simple_unlock(&slock); \
82 }
83
84 #define CV_TIMEDWAIT(cv, lck, t) { \
85 struct simplelock slock = SIMPLELOCK_INITIALIZER; \
86 simple_lock(&slock); \
87 int glocked = ISAFS_GLOCK(); \
88 if (glocked) \
89 AFS_GUNLOCK(); \
90 MUTEX_EXIT(lck); \
91 tsleep(cv, PSOCK, "afs_rx_cv_timedwait", t, &slock); \
92 if (glocked) \
93 AFS_GLOCK(); \
94 MUTEX_ENTER(lck); \
95 simple_unlock(&slock); \
96 }
97
98 #define CV_SIGNAL(cv) wakeup_one(cv)
99 #define CV_BROADCAST(cv) wakeup(cv)
100
101 #define osi_rxWakeup(cv) wakeup(cv)
102 typedef int afs_kcondvar_t;
103
104 typedef struct {
105 struct lock lock;
106 struct lwp *owner;
107 } afs_kmutex_t;
108
109 #define MUTEX_INIT(a,b,c,d) \
110 do { \
111 lockinit(&(a)->lock, PSOCK, "afs rx mutex", 0, 0); \
112 (a)->owner = 0; \
113 } while(0);
114 #define MUTEX_DESTROY(a) \
115 do { \
116 (a)->owner = (struct lwp *)-1; \
117 } while(0);
118 #if defined(LOCKDEBUG)
119 #define MUTEX_ENTER(a) \
120 do { \
121 _lockmgr(&(a)->lock, LK_EXCLUSIVE, 0, __FILE__, __LINE__); \
122 osi_Assert((a)->owner == 0); \
123 (a)->owner = curlwp; \
124 } while(0);
125 #define MUTEX_TRYENTER(a) \
126 ( _lockmgr(&(a)->lock, LK_EXCLUSIVE | LK_NOWAIT, 0, __FILE__, __LINE__) ? 0 \
127 : ((a)->owner = curlwp, 1) )
128 #define MUTEX_EXIT(a) \
129 do { \
130 osi_Assert((a)->owner == curlwp); \
131 (a)->owner = 0; \
132 _lockmgr(&(a)->lock, LK_RELEASE, 0, __FILE__, __LINE__); \
133 } while(0);
134 #else
135 #define MUTEX_ENTER(a) \
136 do { \
137 lockmgr(&(a)->lock, LK_EXCLUSIVE, 0); \
138 osi_Assert((a)->owner == 0); \
139 (a)->owner = curlwp; \
140 } while(0);
141 #define MUTEX_TRYENTER(a) \
142 ( lockmgr(&(a)->lock, LK_EXCLUSIVE | LK_NOWAIT, 0) ? 0 \
143 : ((a)->owner = curlwp, 1) )
144 #define MUTEX_EXIT(a) \
145 do { \
146 osi_Assert((a)->owner == curlwp); \
147 (a)->owner = 0; \
148 lockmgr(&(a)->lock, LK_RELEASE, 0); \
149 } while(0);
150 #endif /* LOCKDEBUG */
151
152 #define MUTEX_ASSERT(a) \
153 osi_Assert((lockstatus(a) == LK_EXCLUSIVE))
154 #define MUTEX_LOCKED(a) \
155 (lockstatus(a) == LK_EXCLUSIVE)
156
157 #endif /* AFS_NBSD50_ENV */
158
159 #endif /* _RX_KMUTEX_H_ */