netbsd: rebase cm at NetBSD 4.0
[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 #include <sys/lock.h>
29
30 /* You can't have AFS_GLOBAL_SUNLOCK and not RX_ENABLE_LOCKS */
31 #define RX_ENABLE_LOCKS 1
32 #define AFS_GLOBAL_RXLOCK_KERNEL
33
34 /*
35  * Condition variables
36  *
37  * In Digital Unix (OSF/1), we use something akin to the ancient sleep/wakeup
38  * mechanism.  The condition variable itself plays no role; we just use its
39  * address as a convenient unique number.  NetBSD has some improvements in
40  * its versions of these mechanisms.
41  */
42 #define CV_INIT(cv, a, b, c)
43 #define CV_DESTROY(cv)
44 #define CV_WAIT(cv, lck)    { \
45         struct simplelock slock = SIMPLELOCK_INITIALIZER;               \
46         simple_lock(&slock);                                            \
47         int glocked = ISAFS_GLOCK();                                    \
48         if (glocked)                                                    \
49             AFS_GUNLOCK();                                              \
50         MUTEX_EXIT(lck);                                                \
51         ltsleep(cv, PSOCK, "afs_rx_cv_wait", 0, &slock);                \
52         if (glocked)                                                    \
53             AFS_GLOCK();                                                \
54         MUTEX_ENTER(lck);                                               \
55         simple_unlock(&slock);                                          \
56     }
57
58 #define CV_TIMEDWAIT(cv, lck, t)  {                                     \
59         struct simplelock slock = SIMPLELOCK_INITIALIZER;               \
60         simple_lock(&slock);                                            \
61         int glocked = ISAFS_GLOCK();                                    \
62         if (glocked)                                                    \
63             AFS_GUNLOCK();                                              \
64         MUTEX_EXIT(lck);                                                \
65         tsleep(cv, PSOCK, "afs_rx_cv_timedwait", t, &slock);            \
66         if (glocked)                                                    \
67             AFS_GLOCK();                                                \
68         MUTEX_ENTER(lck);                                               \
69         simple_unlock(&slock);                                          \
70     }
71
72 #define CV_SIGNAL(cv)           wakeup_one(cv)
73 #define CV_BROADCAST(cv)        wakeup(cv)
74
75 /* #define osi_rxWakeup(cv)        wakeup(cv) */
76 typedef int afs_kcondvar_t;
77
78 typedef struct {
79     struct lock lock;
80     struct lwp *owner;
81 } afs_kmutex_t;
82
83 #define MUTEX_INIT(a,b,c,d) \
84     do { \
85         lockinit(&(a)->lock, PSOCK, "afs rx mutex", 0, 0); \
86         (a)->owner = 0; \
87     } while(0);
88 #define MUTEX_DESTROY(a) \
89     do { \
90         (a)->owner = (struct lwp *)-1; \
91     } while(0);
92
93 #if defined(LOCKDEBUG)
94 #define MUTEX_ENTER(a) \
95     do { \
96         _lockmgr(&(a)->lock, LK_EXCLUSIVE, 0, __FILE__, __LINE__); \
97         osi_Assert((a)->owner == 0); \
98         (a)->owner = curlwp; \
99     } while(0);
100 #define MUTEX_TRYENTER(a) \
101     ( _lockmgr(&(a)->lock, LK_EXCLUSIVE | LK_NOWAIT, 0, __FILE__, __LINE__) ? 0 \
102       : ((a)->owner = curlwp, 1) )
103 #define MUTEX_EXIT(a) \
104     do { \
105         osi_Assert((a)->owner == curlwp); \
106         (a)->owner = 0; \
107         _lockmgr(&(a)->lock, LK_RELEASE, 0, __FILE__, __LINE__); \
108     } while(0);
109 #else
110 #define MUTEX_ENTER(a) \
111     do { \
112         lockmgr(&(a)->lock, LK_EXCLUSIVE, 0); \
113         osi_Assert((a)->owner == 0); \
114         (a)->owner = curlwp; \
115     } while(0);
116 #define MUTEX_TRYENTER(a) \
117     ( lockmgr(&(a)->lock, LK_EXCLUSIVE | LK_NOWAIT, 0) ? 0 \
118       : ((a)->owner = curlwp, 1) )
119 #define MUTEX_EXIT(a) \
120     do { \
121         osi_Assert((a)->owner == curlwp); \
122         (a)->owner = 0; \
123         lockmgr(&(a)->lock, LK_RELEASE, 0); \
124     } while(0);
125 #endif /* LOCKDEBUG */
126 #define MUTEX_ISMINE(a) \
127     (lockstatus(a) == LK_EXCLUSIVE)
128 #define MUTEX_LOCKED(a) \
129     (lockstatus(a) == LK_EXCLUSIVE)
130
131 #endif /* _RX_KMUTEX_H_ */