FreeBSD/Linux Kernel Cross Reference
sys/kern/lock.h
1 /*
2 * Mach Operating System
3 * Copyright (c) 1993-1987 Carnegie Mellon University
4 * All Rights Reserved.
5 *
6 * Permission to use, copy, modify and distribute this software and its
7 * documentation is hereby granted, provided that both the copyright
8 * notice and this permission notice appear in all copies of the
9 * software, derivative works or modified versions, and any portions
10 * thereof, and that both notices appear in supporting documentation.
11 *
12 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
13 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
14 * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
15 *
16 * Carnegie Mellon requests users of this software to return to
17 *
18 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
19 * School of Computer Science
20 * Carnegie Mellon University
21 * Pittsburgh PA 15213-3890
22 *
23 * any improvements or extensions that they make and grant Carnegie Mellon
24 * the rights to redistribute these changes.
25 */
26 /*
27 * HISTORY
28 * $Log: lock.h,v $
29 * Revision 2.12 93/02/05 07:51:21 danner
30 * Reorganization of lock structure.
31 * Recursion_depth is now a bitfield,
32 * and the thread pointer is the first field.
33 * [93/02/04 danner]
34 *
35 * Revision 2.11 93/01/24 13:19:22 danner
36 * Add include of mach/machine/vm_types.h
37 *
38 * Revision 2.10 93/01/19 09:00:57 danner
39 * Underlying simple lock type is now volatile natural_t.
40 * [93/01/19 danner]
41 *
42 * Revision 2.9 93/01/14 17:35:00 danner
43 * Added ANSI function prototypes. Made simple lock data
44 * volatile.
45 * [92/12/30 dbg]
46 * ANSI-fied cpp directives.
47 * [92/12/01 af]
48 *
49 * Revision 2.8 91/11/12 11:51:58 rvb
50 * Added simple_lock_pause.
51 * [91/11/12 rpd]
52 *
53 * Revision 2.7 91/05/18 14:32:17 rpd
54 * Added check_simple_locks.
55 * [91/03/31 rpd]
56 *
57 * Revision 2.6 91/05/14 16:43:51 mrt
58 * Correcting copyright
59 *
60 * Revision 2.5 91/05/08 12:47:17 dbg
61 * When actually using the locks (on multiprocessors), import the
62 * machine-dependent simple_lock routines from machine/lock.h.
63 * [91/04/26 14:42:23 dbg]
64 *
65 * Revision 2.4 91/02/05 17:27:37 mrt
66 * Changed to new Mach copyright
67 * [91/02/01 16:14:39 mrt]
68 *
69 * Revision 2.3 90/11/05 14:31:18 rpd
70 * Added simple_lock_taken.
71 * [90/11/04 rpd]
72 *
73 * Revision 2.2 90/01/11 11:43:26 dbg
74 * Upgraded to match mainline:
75 * Added decl_simple_lock_data, simple_lock_addr macros.
76 * Rearranged complex lock structure to use decl_simple_lock_data
77 * for the interlock field and put it last (except on ns32000).
78 * [89/01/15 15:16:47 rpd]
79 *
80 * Made all machines use the compact field layout.
81 *
82 * Revision 2.1 89/08/03 15:49:42 rwd
83 * Created.
84 *
85 * Revision 2.2 88/07/20 16:49:35 rpd
86 * Allow for sanity-checking of simple locking on uniprocessors,
87 * controlled by new option MACH_LDEBUG. Define composite
88 * MACH_SLOCKS, which is true iff simple locking calls expand
89 * to code. It can be used to #if-out declarations, etc, that
90 * are only used when simple locking calls are real.
91 *
92 * 3-Nov-87 David Black (dlb) at Carnegie-Mellon University
93 * Use optimized lock structure for multimax also.
94 *
95 * 27-Oct-87 Robert Baron (rvb) at Carnegie-Mellon University
96 * Use optimized lock "structure" for balance now that locks are
97 * done inline.
98 *
99 * 26-Jan-87 Avadis Tevanian (avie) at Carnegie-Mellon University
100 * Invert logic of no_sleep to can_sleep.
101 *
102 * 29-Dec-86 David Golub (dbg) at Carnegie-Mellon University
103 * Removed BUSYP, BUSYV, adawi, mpinc, mpdec. Defined the
104 * interlock field of the lock structure to be a simple-lock.
105 *
106 * 9-Nov-86 Michael Young (mwyoung) at Carnegie-Mellon University
107 * Added "unsigned" to fields in vax case, for lint.
108 *
109 * 21-Oct-86 Michael Young (mwyoung) at Carnegie-Mellon University
110 * Added fields for sleep/recursive locks.
111 *
112 * 7-Oct-86 David L. Black (dlb) at Carnegie-Mellon University
113 * Merged Multimax changes.
114 *
115 * 26-Sep-86 Michael Young (mwyoung) at Carnegie-Mellon University
116 * Removed reference to "caddr_t" from BUSYV/P. I really
117 * wish we could get rid of these things entirely.
118 *
119 * 24-Sep-86 Michael Young (mwyoung) at Carnegie-Mellon University
120 * Changed to directly import boolean declaration.
121 *
122 * 1-Aug-86 David Golub (dbg) at Carnegie-Mellon University
123 * Added simple_lock_try, sleep locks, recursive locking.
124 *
125 * 11-Jun-86 Bill Bolosky (bolosky) at Carnegie-Mellon University
126 * Removed ';' from definitions of locking macros (defined only
127 * when NCPU < 2). so as to make things compile.
128 *
129 * 28-Feb-86 Bill Bolosky (bolosky) at Carnegie-Mellon University
130 * Defined adawi to be add when not on a vax.
131 *
132 * 07-Nov-85 Michael Wayne Young (mwyoung) at Carnegie-Mellon University
133 * Overhauled from previous version.
134 */
135 /*
136 * File: kern/lock.h
137 * Author: Avadis Tevanian, Jr., Michael Wayne Young
138 * Date: 1985
139 *
140 * Locking primitives definitions
141 */
142
143 #ifndef _KERN_LOCK_H_
144 #define _KERN_LOCK_H_
145
146 #include <cpus.h>
147 #include <mach_ldebug.h>
148
149 #include <mach/boolean.h>
150 #include <mach/machine/vm_types.h>
151
152 #define MACH_SLOCKS ((NCPUS > 1) || MACH_LDEBUG)
153
154 /*
155 * A simple spin lock.
156 */
157
158 struct slock {
159 volatile natural_t lock_data; /* in general 1 bit is sufficient */
160 };
161
162 typedef struct slock simple_lock_data_t;
163 typedef struct slock *simple_lock_t;
164
165 #if MACH_SLOCKS
166 /*
167 * Use the locks.
168 */
169
170 #define decl_simple_lock_data(class,name) \
171 class simple_lock_data_t name;
172
173 #define simple_lock_addr(lock) (&(lock))
174
175 #if (NCPUS > 1)
176
177 /*
178 * Import the definitions from machine-dependent code.
179 */
180
181 #include <machine/lock.h>
182
183 /*
184 * The single-CPU debugging routines are not valid
185 * on a multiprocessor.
186 */
187 #define simple_lock_taken(lock) (1) /* always succeeds */
188 #define check_simple_locks()
189
190 #else /* NCPUS > 1 */
191 /*
192 * Use our single-CPU locking test routines.
193 */
194
195 extern void simple_lock_init(simple_lock_t);
196 extern void simple_lock(simple_lock_t);
197 extern void simple_unlock(simple_lock_t);
198 extern boolean_t simple_lock_try(simple_lock_t);
199
200 #define simple_lock_pause()
201 #define simple_lock_taken(lock) ((lock)->lock_data)
202
203 extern void check_simple_locks(void);
204
205 #endif /* NCPUS > 1 */
206
207 #else /* MACH_SLOCKS */
208 /*
209 * Do not allocate storage for locks if not needed.
210 */
211 #define decl_simple_lock_data(class,name)
212 #define simple_lock_addr(lock) ((simple_lock_t)0)
213
214 /*
215 * No multiprocessor locking is necessary.
216 */
217 #define simple_lock_init(l)
218 #define simple_lock(l)
219 #define simple_unlock(l)
220 #define simple_lock_try(l) (TRUE) /* always succeeds */
221 #define simple_lock_taken(l) (1) /* always succeeds */
222 #define check_simple_locks()
223 #define simple_lock_pause()
224
225 #endif /* MACH_SLOCKS */
226
227 /*
228 * The general lock structure. Provides for multiple readers,
229 * upgrading from read to write, and sleeping until the lock
230 * can be gained.
231 *
232 * On some architectures, assembly language code in the 'inline'
233 * program fiddles the lock structures. It must be changed in
234 * concert with the structure layout.
235 *
236 * Only the "interlock" field is used for hardware exclusion;
237 * other fields are modified with normal instructions after
238 * acquiring the interlock bit.
239 */
240 struct lock {
241 struct thread *thread; /* Thread that has lock, if
242 recursive locking allowed */
243 unsigned int read_count:16, /* Number of accepted readers */
244 /* boolean_t */ want_upgrade:1, /* Read-to-write upgrade waiting */
245 /* boolean_t */ want_write:1, /* Writer is waiting, or
246 locked for write */
247 /* boolean_t */ waiting:1, /* Someone is sleeping on lock */
248 /* boolean_t */ can_sleep:1, /* Can attempts to lock go to sleep? */
249 recursion_depth:12, /* Depth of recursion */
250 :0;
251 decl_simple_lock_data(,interlock)
252 /* Hardware interlock field.
253 Last in the structure so that
254 field offsets are the same whether
255 or not it is present. */
256 };
257
258 typedef struct lock lock_data_t;
259 typedef struct lock *lock_t;
260
261 /* Sleep locks must work even if no multiprocessing */
262
263 extern void lock_init(lock_t, boolean_t);
264 extern void lock_sleepable(lock_t, boolean_t);
265 extern void lock_write(lock_t);
266 extern void lock_read(lock_t);
267 extern void lock_done(lock_t);
268 extern boolean_t lock_read_to_write(lock_t);
269 extern void lock_write_to_read(lock_t);
270 extern boolean_t lock_try_write(lock_t);
271 extern boolean_t lock_try_read(lock_t);
272 extern boolean_t lock_try_read_to_write(lock_t);
273
274 #define lock_read_done(l) lock_done(l)
275 #define lock_write_done(l) lock_done(l)
276
277 extern void lock_set_recursive(lock_t);
278 extern void lock_clear_recursive(lock_t);
279
280 #endif /* _KERN_LOCK_H_ */
Cache object: bb2c0b8fc017eda703f820b1ef8c1e6c
|