a3240ff8512b3c6059a04df505c98d2eaa42785f
[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_ISMINE(a) 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  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_ISMINE(a) \
153     (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_ */