]>
Commit | Line | Data |
---|---|---|
91447636 | 1 | /* |
39236c6e | 2 | * Copyright (c) 2003-2012 Apple Inc. All rights reserved. |
91447636 | 3 | * |
2d21ac55 A |
4 | * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ |
5 | * | |
6 | * This file contains Original Code and/or Modifications of Original Code | |
7 | * as defined in and that are subject to the Apple Public Source License | |
8 | * Version 2.0 (the 'License'). You may not use this file except in | |
9 | * compliance with the License. The rights granted to you under the License | |
10 | * may not be used to create, or enable the creation or redistribution of, | |
11 | * unlawful or unlicensed copies of an Apple operating system, or to | |
12 | * circumvent, violate, or enable the circumvention or violation of, any | |
13 | * terms of an Apple operating system software license agreement. | |
14 | * | |
15 | * Please obtain a copy of the License at | |
16 | * http://www.opensource.apple.com/apsl/ and read it before using this file. | |
17 | * | |
18 | * The Original Code and all software distributed under the License are | |
19 | * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER | |
8f6c56a5 A |
20 | * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, |
21 | * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, | |
2d21ac55 A |
22 | * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. |
23 | * Please see the License for the specific language governing rights and | |
24 | * limitations under the License. | |
25 | * | |
26 | * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ | |
91447636 A |
27 | */ |
28 | ||
29 | #ifndef _KERN_LOCKS_H_ | |
30 | #define _KERN_LOCKS_H_ | |
31 | ||
32 | #include <sys/cdefs.h> | |
33 | #include <sys/appleapiopts.h> | |
34 | #include <mach/boolean.h> | |
35 | #include <mach/mach_types.h> | |
36 | #include <kern/kern_types.h> | |
37 | #include <machine/locks.h> | |
38 | ||
39 | #ifdef MACH_KERNEL_PRIVATE | |
40 | #include <kern/queue.h> | |
41 | ||
42 | extern void lck_mod_init( | |
39236c6e | 43 | void); |
91447636 A |
44 | |
45 | typedef unsigned int lck_type_t; | |
46 | ||
47 | #define LCK_TYPE_SPIN 1 | |
48 | #define LCK_TYPE_MTX 2 | |
2d21ac55 | 49 | #define LCK_TYPE_RW 3 |
91447636 A |
50 | |
51 | #endif | |
52 | ||
53 | typedef unsigned int lck_sleep_action_t; | |
54 | ||
55 | #define LCK_SLEEP_DEFAULT 0x00 /* Release the lock while waiting for the event, then reclaim */ | |
56 | /* RW locks are returned in the same mode */ | |
57 | #define LCK_SLEEP_UNLOCK 0x01 /* Release the lock and return unheld */ | |
58 | #define LCK_SLEEP_SHARED 0x02 /* Reclaim the lock in shared mode (RW only) */ | |
59 | #define LCK_SLEEP_EXCLUSIVE 0x04 /* Reclaim the lock in exclusive mode (RW only) */ | |
b0d623f7 | 60 | #define LCK_SLEEP_SPIN 0x08 /* Reclaim the lock in spin mode (mutex only) */ |
fe8ab488 | 61 | #define LCK_SLEEP_PROMOTED_PRI 0x10 /* Sleep at a promoted priority */ |
91447636 | 62 | |
fe8ab488 | 63 | #define LCK_SLEEP_MASK 0x1f /* Valid actions */ |
91447636 A |
64 | |
65 | #ifdef MACH_KERNEL_PRIVATE | |
66 | ||
67 | typedef struct { | |
68 | uint64_t lck_grp_spin_util_cnt; | |
69 | uint64_t lck_grp_spin_held_cnt; | |
70 | uint64_t lck_grp_spin_miss_cnt; | |
71 | uint64_t lck_grp_spin_held_max; | |
72 | uint64_t lck_grp_spin_held_cum; | |
73 | } lck_grp_spin_stat_t; | |
74 | ||
75 | typedef struct { | |
76 | uint64_t lck_grp_mtx_util_cnt; | |
2d21ac55 | 77 | /* On x86, this is used as the "direct wait" count */ |
91447636 A |
78 | uint64_t lck_grp_mtx_held_cnt; |
79 | uint64_t lck_grp_mtx_miss_cnt; | |
80 | uint64_t lck_grp_mtx_wait_cnt; | |
2d21ac55 | 81 | /* Rest currently unused */ |
91447636 A |
82 | uint64_t lck_grp_mtx_held_max; |
83 | uint64_t lck_grp_mtx_held_cum; | |
84 | uint64_t lck_grp_mtx_wait_max; | |
85 | uint64_t lck_grp_mtx_wait_cum; | |
86 | } lck_grp_mtx_stat_t; | |
87 | ||
88 | typedef struct { | |
89 | uint64_t lck_grp_rw_util_cnt; | |
90 | uint64_t lck_grp_rw_held_cnt; | |
91 | uint64_t lck_grp_rw_miss_cnt; | |
92 | uint64_t lck_grp_rw_wait_cnt; | |
93 | uint64_t lck_grp_rw_held_max; | |
94 | uint64_t lck_grp_rw_held_cum; | |
95 | uint64_t lck_grp_rw_wait_max; | |
96 | uint64_t lck_grp_rw_wait_cum; | |
97 | } lck_grp_rw_stat_t; | |
98 | ||
99 | typedef struct _lck_grp_stat_ { | |
100 | lck_grp_spin_stat_t lck_grp_spin_stat; | |
101 | lck_grp_mtx_stat_t lck_grp_mtx_stat; | |
102 | lck_grp_rw_stat_t lck_grp_rw_stat; | |
103 | } lck_grp_stat_t; | |
104 | ||
105 | #define LCK_GRP_MAX_NAME 64 | |
106 | ||
107 | typedef struct _lck_grp_ { | |
108 | queue_chain_t lck_grp_link; | |
b0d623f7 A |
109 | uint32_t lck_grp_refcnt; |
110 | uint32_t lck_grp_spincnt; | |
111 | uint32_t lck_grp_mtxcnt; | |
112 | uint32_t lck_grp_rwcnt; | |
113 | uint32_t lck_grp_attr; | |
2d21ac55 | 114 | char lck_grp_name[LCK_GRP_MAX_NAME]; |
91447636 A |
115 | lck_grp_stat_t lck_grp_stat; |
116 | } lck_grp_t; | |
117 | ||
118 | #define LCK_GRP_NULL (lck_grp_t *)0 | |
119 | ||
120 | #else | |
121 | typedef struct __lck_grp__ lck_grp_t; | |
122 | #endif | |
123 | ||
124 | #ifdef MACH_KERNEL_PRIVATE | |
125 | typedef struct _lck_grp_attr_ { | |
b0d623f7 | 126 | uint32_t grp_attr_val; |
91447636 A |
127 | } lck_grp_attr_t; |
128 | ||
129 | extern lck_grp_attr_t LockDefaultGroupAttr; | |
130 | ||
131 | #define LCK_GRP_ATTR_STAT 0x1 | |
132 | ||
133 | #else | |
134 | typedef struct __lck_grp_attr__ lck_grp_attr_t; | |
135 | #endif | |
136 | ||
137 | #define LCK_GRP_ATTR_NULL (lck_grp_attr_t *)0 | |
138 | ||
139 | __BEGIN_DECLS | |
140 | ||
141 | extern lck_grp_attr_t *lck_grp_attr_alloc_init( | |
142 | void); | |
143 | ||
144 | extern void lck_grp_attr_setdefault( | |
145 | lck_grp_attr_t *attr); | |
146 | ||
147 | extern void lck_grp_attr_setstat( | |
148 | lck_grp_attr_t *attr); | |
149 | ||
150 | extern void lck_grp_attr_free( | |
151 | lck_grp_attr_t *attr); | |
152 | ||
153 | extern lck_grp_t *lck_grp_alloc_init( | |
154 | const char* grp_name, | |
155 | lck_grp_attr_t *attr); | |
156 | ||
157 | __END_DECLS | |
158 | ||
159 | #ifdef MACH_KERNEL_PRIVATE | |
160 | extern void lck_grp_init( | |
161 | lck_grp_t *grp, | |
162 | const char* grp_name, | |
163 | lck_grp_attr_t *attr); | |
164 | ||
165 | extern void lck_grp_reference( | |
166 | lck_grp_t *grp); | |
167 | ||
168 | extern void lck_grp_deallocate( | |
169 | lck_grp_t *grp); | |
170 | ||
171 | extern void lck_grp_lckcnt_incr( | |
172 | lck_grp_t *grp, | |
173 | lck_type_t lck_type); | |
174 | ||
175 | extern void lck_grp_lckcnt_decr( | |
176 | lck_grp_t *grp, | |
177 | lck_type_t lck_type); | |
178 | #endif | |
179 | ||
180 | __BEGIN_DECLS | |
181 | ||
182 | extern void lck_grp_free( | |
183 | lck_grp_t *grp); | |
184 | ||
185 | __END_DECLS | |
186 | ||
187 | #ifdef MACH_KERNEL_PRIVATE | |
188 | typedef struct _lck_attr_ { | |
189 | unsigned int lck_attr_val; | |
190 | } lck_attr_t; | |
191 | ||
192 | extern lck_attr_t LockDefaultLckAttr; | |
193 | ||
0c530ab8 A |
194 | #define LCK_ATTR_NONE 0 |
195 | ||
196 | #define LCK_ATTR_DEBUG 0x00000001 | |
197 | #define LCK_ATTR_RW_SHARED_PRIORITY 0x00010000 | |
91447636 A |
198 | |
199 | #else | |
200 | typedef struct __lck_attr__ lck_attr_t; | |
201 | #endif | |
202 | ||
203 | #define LCK_ATTR_NULL (lck_attr_t *)0 | |
204 | ||
205 | __BEGIN_DECLS | |
206 | ||
207 | extern lck_attr_t *lck_attr_alloc_init( | |
208 | void); | |
209 | ||
210 | extern void lck_attr_setdefault( | |
211 | lck_attr_t *attr); | |
212 | ||
213 | extern void lck_attr_setdebug( | |
214 | lck_attr_t *attr); | |
215 | ||
2d21ac55 A |
216 | extern void lck_attr_cleardebug( |
217 | lck_attr_t *attr); | |
218 | ||
0c530ab8 A |
219 | #ifdef XNU_KERNEL_PRIVATE |
220 | extern void lck_attr_rw_shared_priority( | |
221 | lck_attr_t *attr); | |
222 | #endif | |
223 | ||
91447636 A |
224 | extern void lck_attr_free( |
225 | lck_attr_t *attr); | |
226 | ||
227 | #define decl_lck_spin_data(class,name) class lck_spin_t name; | |
228 | ||
229 | extern lck_spin_t *lck_spin_alloc_init( | |
230 | lck_grp_t *grp, | |
231 | lck_attr_t *attr); | |
232 | ||
233 | extern void lck_spin_init( | |
234 | lck_spin_t *lck, | |
235 | lck_grp_t *grp, | |
236 | lck_attr_t *attr); | |
237 | ||
238 | extern void lck_spin_lock( | |
239 | lck_spin_t *lck); | |
240 | ||
241 | extern void lck_spin_unlock( | |
242 | lck_spin_t *lck); | |
243 | ||
244 | extern void lck_spin_destroy( | |
245 | lck_spin_t *lck, | |
246 | lck_grp_t *grp); | |
247 | ||
248 | extern void lck_spin_free( | |
249 | lck_spin_t *lck, | |
250 | lck_grp_t *grp); | |
251 | ||
252 | extern wait_result_t lck_spin_sleep( | |
253 | lck_spin_t *lck, | |
254 | lck_sleep_action_t lck_sleep_action, | |
255 | event_t event, | |
256 | wait_interrupt_t interruptible); | |
257 | ||
258 | extern wait_result_t lck_spin_sleep_deadline( | |
259 | lck_spin_t *lck, | |
260 | lck_sleep_action_t lck_sleep_action, | |
261 | event_t event, | |
262 | wait_interrupt_t interruptible, | |
263 | uint64_t deadline); | |
264 | ||
265 | #ifdef KERNEL_PRIVATE | |
266 | ||
fe8ab488 A |
267 | extern boolean_t lck_spin_try_lock( lck_spin_t *lck); |
268 | ||
269 | /* NOT SAFE: To be used only by kernel debugger to avoid deadlock. */ | |
3e170ce0 | 270 | extern boolean_t kdp_lck_spin_is_acquired( lck_spin_t *lck); |
91447636 | 271 | |
b0d623f7 A |
272 | struct _lck_mtx_ext_; |
273 | extern void lck_mtx_init_ext(lck_mtx_t *lck, struct _lck_mtx_ext_ *lck_ext, | |
274 | lck_grp_t *grp, lck_attr_t *attr); | |
275 | ||
91447636 A |
276 | #endif |
277 | ||
278 | ||
279 | #define decl_lck_mtx_data(class,name) class lck_mtx_t name; | |
280 | ||
281 | extern lck_mtx_t *lck_mtx_alloc_init( | |
282 | lck_grp_t *grp, | |
283 | lck_attr_t *attr); | |
284 | ||
285 | extern void lck_mtx_init( | |
286 | lck_mtx_t *lck, | |
287 | lck_grp_t *grp, | |
288 | lck_attr_t *attr); | |
91447636 A |
289 | extern void lck_mtx_lock( |
290 | lck_mtx_t *lck); | |
291 | ||
292 | extern void lck_mtx_unlock( | |
293 | lck_mtx_t *lck); | |
6d2010ae | 294 | |
91447636 A |
295 | extern void lck_mtx_destroy( |
296 | lck_mtx_t *lck, | |
297 | lck_grp_t *grp); | |
298 | ||
299 | extern void lck_mtx_free( | |
300 | lck_mtx_t *lck, | |
301 | lck_grp_t *grp); | |
302 | ||
303 | extern wait_result_t lck_mtx_sleep( | |
304 | lck_mtx_t *lck, | |
305 | lck_sleep_action_t lck_sleep_action, | |
306 | event_t event, | |
307 | wait_interrupt_t interruptible); | |
308 | ||
309 | extern wait_result_t lck_mtx_sleep_deadline( | |
310 | lck_mtx_t *lck, | |
311 | lck_sleep_action_t lck_sleep_action, | |
312 | event_t event, | |
313 | wait_interrupt_t interruptible, | |
314 | uint64_t deadline); | |
315 | ||
316 | #ifdef KERNEL_PRIVATE | |
317 | ||
318 | extern boolean_t lck_mtx_try_lock( | |
319 | lck_mtx_t *lck); | |
320 | ||
b0d623f7 A |
321 | extern void mutex_pause(uint32_t); |
322 | ||
323 | extern void lck_mtx_yield ( | |
324 | lck_mtx_t *lck); | |
325 | ||
6d2010ae | 326 | #if defined(__i386__) || defined(__x86_64__) |
2d21ac55 A |
327 | extern boolean_t lck_mtx_try_lock_spin( |
328 | lck_mtx_t *lck); | |
329 | ||
39236c6e A |
330 | extern boolean_t lck_mtx_try_lock_spin_always( |
331 | lck_mtx_t *lck); | |
332 | ||
6d2010ae A |
333 | extern void lck_mtx_lock_spin_always( |
334 | lck_mtx_t *lck); | |
335 | ||
2d21ac55 A |
336 | extern void lck_mtx_lock_spin( |
337 | lck_mtx_t *lck); | |
338 | ||
339 | extern void lck_mtx_convert_spin( | |
340 | lck_mtx_t *lck); | |
6d2010ae | 341 | |
3e170ce0 A |
342 | extern boolean_t kdp_lck_mtx_lock_spin_is_acquired( |
343 | lck_mtx_t *lck); | |
6d2010ae A |
344 | #define lck_mtx_unlock_always(l) lck_mtx_unlock(l) |
345 | ||
2d21ac55 A |
346 | #else |
347 | #define lck_mtx_try_lock_spin(l) lck_mtx_try_lock(l) | |
348 | #define lck_mtx_lock_spin(l) lck_mtx_lock(l) | |
39236c6e | 349 | #define lck_mtx_try_lock_spin_always(l) lck_spin_try_lock(l) |
6d2010ae | 350 | #define lck_mtx_lock_spin_always(l) lck_spin_lock(l) |
3e170ce0 | 351 | #define kdp_lck_mtx_lock_spin_is_acquired(l) kdp_lck_spin_is_acquired(l) |
6d2010ae | 352 | #define lck_mtx_unlock_always(l) lck_spin_unlock(l) |
2d21ac55 A |
353 | #define lck_mtx_convert_spin(l) do {} while (0) |
354 | #endif | |
355 | ||
3e170ce0 A |
356 | extern boolean_t kdp_lck_rw_lock_is_acquired_exclusive( |
357 | lck_rw_t *lck); | |
358 | ||
91447636 A |
359 | #endif /* KERNEL_PRIVATE */ |
360 | ||
361 | extern void lck_mtx_assert( | |
362 | lck_mtx_t *lck, | |
363 | unsigned int type); | |
364 | ||
365 | __END_DECLS | |
366 | ||
367 | #define LCK_MTX_ASSERT_OWNED 0x01 | |
368 | #define LCK_MTX_ASSERT_NOTOWNED 0x02 | |
369 | ||
370 | #ifdef MACH_KERNEL_PRIVATE | |
371 | extern void lck_mtx_lock_wait( | |
372 | lck_mtx_t *lck, | |
373 | thread_t holder); | |
374 | ||
375 | extern int lck_mtx_lock_acquire( | |
376 | lck_mtx_t *lck); | |
377 | ||
378 | extern void lck_mtx_unlock_wakeup( | |
379 | lck_mtx_t *lck, | |
380 | thread_t holder); | |
2d21ac55 A |
381 | extern void lck_mtx_unlockspin_wakeup( |
382 | lck_mtx_t *lck); | |
91447636 A |
383 | |
384 | extern boolean_t lck_mtx_ilk_unlock( | |
385 | lck_mtx_t *lck); | |
2d21ac55 | 386 | |
3e170ce0 A |
387 | extern boolean_t lck_mtx_ilk_try_lock( |
388 | lck_mtx_t *lck); | |
389 | ||
91447636 A |
390 | #endif |
391 | ||
392 | #define decl_lck_rw_data(class,name) class lck_rw_t name; | |
393 | ||
394 | typedef unsigned int lck_rw_type_t; | |
395 | ||
396 | #define LCK_RW_TYPE_SHARED 0x01 | |
397 | #define LCK_RW_TYPE_EXCLUSIVE 0x02 | |
398 | ||
2d21ac55 A |
399 | #ifdef XNU_KERNEL_PRIVATE |
400 | #define LCK_RW_ASSERT_SHARED 0x01 | |
401 | #define LCK_RW_ASSERT_EXCLUSIVE 0x02 | |
39236c6e A |
402 | #define LCK_RW_ASSERT_HELD 0x03 |
403 | #define LCK_RW_ASSERT_NOTHELD 0x04 | |
2d21ac55 A |
404 | #endif |
405 | ||
91447636 A |
406 | __BEGIN_DECLS |
407 | ||
408 | extern lck_rw_t *lck_rw_alloc_init( | |
409 | lck_grp_t *grp, | |
410 | lck_attr_t *attr); | |
411 | ||
412 | extern void lck_rw_init( | |
413 | lck_rw_t *lck, | |
414 | lck_grp_t *grp, | |
415 | lck_attr_t *attr); | |
416 | ||
417 | extern void lck_rw_lock( | |
418 | lck_rw_t *lck, | |
419 | lck_rw_type_t lck_rw_type); | |
420 | ||
421 | extern void lck_rw_unlock( | |
422 | lck_rw_t *lck, | |
423 | lck_rw_type_t lck_rw_type); | |
424 | ||
425 | extern void lck_rw_lock_shared( | |
426 | lck_rw_t *lck); | |
427 | ||
428 | extern void lck_rw_unlock_shared( | |
429 | lck_rw_t *lck); | |
430 | ||
431 | extern void lck_rw_lock_exclusive( | |
432 | lck_rw_t *lck); | |
433 | ||
434 | extern void lck_rw_unlock_exclusive( | |
435 | lck_rw_t *lck); | |
436 | ||
2d21ac55 A |
437 | #ifdef XNU_KERNEL_PRIVATE |
438 | /* | |
439 | * CAUTION | |
440 | * read-write locks do not have a concept of ownership, so lck_rw_assert() | |
441 | * merely asserts that someone is holding the lock, not necessarily the caller. | |
442 | */ | |
443 | extern void lck_rw_assert( | |
444 | lck_rw_t *lck, | |
445 | unsigned int type); | |
39236c6e A |
446 | |
447 | extern void lck_rw_clear_promotion( | |
448 | thread_t thread); | |
2d21ac55 A |
449 | #endif |
450 | ||
91447636 A |
451 | #ifdef KERNEL_PRIVATE |
452 | ||
453 | extern lck_rw_type_t lck_rw_done( | |
454 | lck_rw_t *lck); | |
455 | #endif | |
456 | ||
457 | extern void lck_rw_destroy( | |
458 | lck_rw_t *lck, | |
459 | lck_grp_t *grp); | |
460 | ||
461 | extern void lck_rw_free( | |
462 | lck_rw_t *lck, | |
463 | lck_grp_t *grp); | |
464 | ||
465 | extern wait_result_t lck_rw_sleep( | |
466 | lck_rw_t *lck, | |
467 | lck_sleep_action_t lck_sleep_action, | |
468 | event_t event, | |
469 | wait_interrupt_t interruptible); | |
470 | ||
471 | extern wait_result_t lck_rw_sleep_deadline( | |
472 | lck_rw_t *lck, | |
473 | lck_sleep_action_t lck_sleep_action, | |
474 | event_t event, | |
475 | wait_interrupt_t interruptible, | |
476 | uint64_t deadline); | |
477 | ||
91447636 A |
478 | extern boolean_t lck_rw_lock_shared_to_exclusive( |
479 | lck_rw_t *lck); | |
480 | ||
481 | extern void lck_rw_lock_exclusive_to_shared( | |
482 | lck_rw_t *lck); | |
483 | ||
484 | extern boolean_t lck_rw_try_lock( | |
485 | lck_rw_t *lck, | |
486 | lck_rw_type_t lck_rw_type); | |
487 | ||
2d21ac55 A |
488 | #ifdef KERNEL_PRIVATE |
489 | ||
91447636 A |
490 | extern boolean_t lck_rw_try_lock_shared( |
491 | lck_rw_t *lck); | |
492 | ||
493 | extern boolean_t lck_rw_try_lock_exclusive( | |
494 | lck_rw_t *lck); | |
495 | #endif | |
496 | ||
497 | __END_DECLS | |
498 | ||
499 | #endif /* _KERN_LOCKS_H_ */ |