initial-linux24-support-20001105
[openafs.git] / src / rx / LINUX / 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  * Linux implementation.
14  * This are noops until such time as the kernel no longer has a global lock.
15  */
16 #ifndef RX_KMUTEX_H_
17 #define RX_KMUTEX_H_
18
19 #include "../rx/rx_kernel.h"    /* for osi_Panic() */
20
21 /* AFS_GLOBAL_RXLOCK_KERNEL is defined so that the busy tq code paths are
22  * used. The thread can sleep when sending packets.
23  */
24 #define AFS_GLOBAL_RXLOCK_KERNEL 1
25
26
27 #ifdef CONFIG_SMP
28 #define RX_ENABLE_LOCKS 1
29
30 #ifndef _LINUX_CODA_FS_I
31 #define _LINUX_CODA_FS_I
32 struct coda_inode_info {};
33 #endif
34 #include "linux/wait.h"
35 #include "linux/sched.h"
36
37 typedef struct afs_kmutex {
38     struct semaphore sem;
39     int owner;
40 } afs_kmutex_t;
41
42 #if defined(AFS_LINUX24_ENV)
43 typedef wait_queue_head_t afs_kcondvar_t;
44 #else
45 typedef struct wait_queue *afs_kcondvar_t;
46 #endif
47
48 static inline int MUTEX_ISMINE(afs_kmutex_t *l)
49 {
50     return l->owner == current->pid;
51 }
52
53
54 static inline void afs_mutex_init(afs_kmutex_t *l)
55 {
56 #if defined(AFS_LINUX24_ENV)
57     init_MUTEX(&l->sem);
58 #else
59     l->sem = MUTEX;
60 #endif
61     l->owner = 0;
62 }
63 #define MUTEX_INIT(a,b,c,d) afs_mutex_init(a)
64
65 #define MUTEX_DESTROY(a)
66
67 static inline void MUTEX_ENTER(afs_kmutex_t *l)
68 {
69     down(&l->sem);
70     if (l->owner)
71         osi_Panic("mutex_enter: 0x%x held by %d", l, l->owner);
72     l->owner = current->pid;
73 }
74                                                               
75 /* And how to do a good tryenter? */
76 static inline int MUTEX_TRYENTER(afs_kmutex_t *l)
77 {
78     if (!l->owner) {
79         MUTEX_ENTER(l);
80         return 1;
81     }
82     else
83         return 0;
84 }
85
86 static inline void MUTEX_EXIT(afs_kmutex_t *l)
87 {
88     if (l->owner != current->pid)
89         osi_Panic("mutex_exit: 0x%x held by %d",
90                   l, l->owner);
91     l->owner = 0;
92     up(&l->sem);
93 }
94
95 #if defined(AFS_LINUX24_ENV)
96 #define CV_INIT(cv,b,c,d) init_waitqueue_head((wait_queue_head_t *)(cv))
97 #else
98 #define CV_INIT(cv,b,c,d) init_waitqueue((struct wait_queue**)(cv))
99 #endif
100 #define CV_DESTROY(cv)
101
102 /* CV_WAIT and CV_TIMEDWAIT rely on the fact that the Linux kernel has
103  * a global lock. Thus we can safely drop our locks before calling the
104  * kernel sleep services.
105  */
106 static inline CV_WAIT(afs_kcondvar_t *cv, afs_kmutex_t *l)
107 {
108     int isAFSGlocked = ISAFS_GLOCK(); 
109
110     if (isAFSGlocked) AFS_GUNLOCK();
111     MUTEX_EXIT(l);
112
113 #if defined(AFS_LINUX24_ENV)
114     interruptible_sleep_on((wait_queue_head_t *)cv);
115 #else
116     interruptible_sleep_on((struct wait_queue**)cv);
117 #endif
118
119     MUTEX_ENTER(l);
120     if (isAFSGlocked) AFS_GLOCK();
121
122     return 0;
123 }
124
125 static inline CV_TIMEDWAIT(afs_kcondvar_t *cv, afs_kmutex_t *l, int waittime)
126 {
127     int isAFSGlocked = ISAFS_GLOCK();
128     long t = waittime * HZ / 1000;
129
130     if (isAFSGlocked) AFS_GUNLOCK();
131     MUTEX_EXIT(l);
132     
133 #if defined(AFS_LINUX24_ENV)
134     t = interruptible_sleep_on_timeout((wait_queue_head_t *)cv, t);
135 #else
136     t = interruptible_sleep_on_timeout((struct wait_queue**)cv, t);
137 #endif
138     
139     MUTEX_ENTER(l);
140     if (isAFSGlocked) AFS_GLOCK();
141
142     return 0;
143 }
144
145 #if defined(AFS_LINUX24_ENV)
146 #define CV_SIGNAL(cv) wake_up((wait_queue_head_t *)cv)
147 #define CV_BROADCAST(cv) wake_up((wait_queue_head_t *)cv)
148 #else
149 #define CV_SIGNAL(cv) wake_up((struct wait_queue**)cv)
150 #define CV_BROADCAST(cv) wake_up((struct wait_queue**)cv)
151 #endif
152
153 #else
154
155 #define MUTEX_ISMINE(a)
156 #define osirx_AssertMine(addr, msg)
157
158 #define MUTEX_DESTROY(a)
159 #define MUTEX_ENTER(a)
160 #define MUTEX_TRYENTER(a) 1
161 #define MUTEX_EXIT(a)  
162 #define MUTEX_INIT(a,b,c,d) 
163 #define CV_INIT(a,b,c,d)
164 #define CV_DESTROY(a)
165 #endif
166
167 /* Since we're using the RX listener daemon, we don't need to hold off
168  * interrupts.
169  */
170 #define SPLVAR
171 #define NETPRI
172 #define USERPRI
173
174 #endif /* RX_KMUTEX_H_ */