2 * Copyright (c) 2003-2012 Apple Inc. All rights reserved.
4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
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.
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
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
20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
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.
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
29 #ifndef _KERN_LOCKS_H_
30 #define _KERN_LOCKS_H_
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 <kern/lock_group.h>
38 #include <machine/locks.h>
40 #ifdef MACH_KERNEL_PRIVATE
41 #include <kern/queue.h>
43 extern void lck_mod_init(
48 typedef unsigned int lck_sleep_action_t
;
50 #define LCK_SLEEP_DEFAULT 0x00 /* Release the lock while waiting for the event, then reclaim */
51 /* RW locks are returned in the same mode */
52 #define LCK_SLEEP_UNLOCK 0x01 /* Release the lock and return unheld */
53 #define LCK_SLEEP_SHARED 0x02 /* Reclaim the lock in shared mode (RW only) */
54 #define LCK_SLEEP_EXCLUSIVE 0x04 /* Reclaim the lock in exclusive mode (RW only) */
55 #define LCK_SLEEP_SPIN 0x08 /* Reclaim the lock in spin mode (mutex only) */
56 #define LCK_SLEEP_PROMOTED_PRI 0x10 /* Sleep at a promoted priority */
57 #define LCK_SLEEP_SPIN_ALWAYS 0x20 /* Reclaim the lock in spin-always mode (mutex only) */
59 #define LCK_SLEEP_MASK 0x3f /* Valid actions */
62 #ifdef MACH_KERNEL_PRIVATE
63 typedef struct _lck_attr_
{
64 unsigned int lck_attr_val
;
67 extern lck_attr_t LockDefaultLckAttr
;
69 #define LCK_ATTR_NONE 0
71 #define LCK_ATTR_DEBUG 0x00000001
72 #define LCK_ATTR_RW_SHARED_PRIORITY 0x00010000
75 typedef struct __lck_attr__ lck_attr_t
;
78 #define LCK_ATTR_NULL (lck_attr_t *)0
82 extern lck_attr_t
*lck_attr_alloc_init(
85 extern void lck_attr_setdefault(
88 extern void lck_attr_setdebug(
91 extern void lck_attr_cleardebug(
94 #ifdef XNU_KERNEL_PRIVATE
102 } lck_ticket_internal
;
105 lck_ticket_internal tu
;
109 void lck_ticket_init(lck_ticket_t
*tlock
);
110 void lck_ticket_lock(lck_ticket_t
*tlock
);
111 void lck_ticket_unlock(lck_ticket_t
*tlock
);
112 void lck_ticket_assert_owned(lck_ticket_t
*tlock
);
114 extern void lck_attr_rw_shared_priority(
118 extern void lck_attr_free(
121 #define decl_lck_spin_data(class, name) class lck_spin_t name;
123 extern lck_spin_t
*lck_spin_alloc_init(
127 extern void lck_spin_init(
132 extern void lck_spin_lock(
135 extern void lck_spin_lock_grp(
139 extern void lck_spin_unlock(
142 extern void lck_spin_destroy(
146 extern void lck_spin_free(
150 extern wait_result_t
lck_spin_sleep(
152 lck_sleep_action_t lck_sleep_action
,
154 wait_interrupt_t interruptible
);
156 extern wait_result_t
lck_spin_sleep_grp(
158 lck_sleep_action_t lck_sleep_action
,
160 wait_interrupt_t interruptible
,
163 extern wait_result_t
lck_spin_sleep_deadline(
165 lck_sleep_action_t lck_sleep_action
,
167 wait_interrupt_t interruptible
,
170 #ifdef KERNEL_PRIVATE
172 extern void lck_spin_lock_nopreempt( lck_spin_t
*lck
);
173 extern void lck_spin_lock_nopreempt_grp( lck_spin_t
*lck
, lck_grp_t
*grp
);
175 extern void lck_spin_unlock_nopreempt( lck_spin_t
*lck
);
177 extern boolean_t
lck_spin_try_lock_grp( lck_spin_t
*lck
, lck_grp_t
*grp
);
179 extern boolean_t
lck_spin_try_lock( lck_spin_t
*lck
);
181 extern boolean_t
lck_spin_try_lock_nopreempt( lck_spin_t
*lck
);
182 extern boolean_t
lck_spin_try_lock_nopreempt_grp( lck_spin_t
*lck
, lck_grp_t
*grp
);
184 /* NOT SAFE: To be used only by kernel debugger to avoid deadlock. */
185 extern boolean_t
kdp_lck_spin_is_acquired( lck_spin_t
*lck
);
187 struct _lck_mtx_ext_
;
188 extern void lck_mtx_init_ext(lck_mtx_t
*lck
, struct _lck_mtx_ext_
*lck_ext
,
189 lck_grp_t
*grp
, lck_attr_t
*attr
);
194 #define decl_lck_mtx_data(class, name) class lck_mtx_t name;
196 extern lck_mtx_t
*lck_mtx_alloc_init(
200 extern void lck_mtx_init(
204 extern void lck_mtx_lock(
207 extern void lck_mtx_unlock(
210 extern void lck_mtx_destroy(
214 extern void lck_mtx_free(
218 extern wait_result_t
lck_mtx_sleep(
220 lck_sleep_action_t lck_sleep_action
,
222 wait_interrupt_t interruptible
);
224 extern wait_result_t
lck_mtx_sleep_deadline(
226 lck_sleep_action_t lck_sleep_action
,
228 wait_interrupt_t interruptible
,
230 #if DEVELOPMENT || DEBUG
231 extern void erase_all_test_mtx_stats(void);
232 extern int get_test_mtx_stats_string(char* buffer
, int buffer_size
);
233 extern void lck_mtx_test_init(void);
234 extern void lck_mtx_test_lock(void);
235 extern void lck_mtx_test_unlock(void);
236 extern int lck_mtx_test_mtx_uncontended(int iter
, char* buffer
, int buffer_size
);
237 extern int lck_mtx_test_mtx_contended(int iter
, char* buffer
, int buffer_size
);
238 extern int lck_mtx_test_mtx_uncontended_loop_time(int iter
, char* buffer
, int buffer_size
);
239 extern int lck_mtx_test_mtx_contended_loop_time(int iter
, char* buffer
, int buffer_size
);
241 #ifdef KERNEL_PRIVATE
243 extern boolean_t
lck_mtx_try_lock(
246 extern void mutex_pause(uint32_t);
248 extern void lck_mtx_yield(
251 extern boolean_t
lck_mtx_try_lock_spin(
254 extern void lck_mtx_lock_spin(
257 extern boolean_t
kdp_lck_mtx_lock_spin_is_acquired(
260 extern void lck_mtx_convert_spin(
263 extern void lck_mtx_lock_spin_always(
266 extern boolean_t
lck_mtx_try_lock_spin_always(
269 #define lck_mtx_unlock_always(l) lck_mtx_unlock(l)
271 extern void lck_spin_assert(
275 extern boolean_t
kdp_lck_rw_lock_is_acquired_exclusive(
278 #endif /* KERNEL_PRIVATE */
280 extern void lck_mtx_assert(
285 #define LCK_MTX_ASSERT(lck, type) lck_mtx_assert((lck),(type))
286 #define LCK_SPIN_ASSERT(lck, type) lck_spin_assert((lck),(type))
287 #define LCK_RW_ASSERT(lck, type) lck_rw_assert((lck),(type))
288 #else /* MACH_ASSERT */
289 #define LCK_MTX_ASSERT(lck, type)
290 #define LCK_SPIN_ASSERT(lck, type)
291 #define LCK_RW_ASSERT(lck, type)
292 #endif /* MACH_ASSERT */
295 #define LCK_MTX_ASSERT_DEBUG(lck, type) lck_mtx_assert((lck),(type))
296 #define LCK_SPIN_ASSERT_DEBUG(lck, type) lck_spin_assert((lck),(type))
297 #define LCK_RW_ASSERT_DEBUG(lck, type) lck_rw_assert((lck),(type))
299 #define LCK_MTX_ASSERT_DEBUG(lck, type)
300 #define LCK_SPIN_ASSERT_DEBUG(lck, type)
301 #define LCK_RW_ASSERT_DEBUG(lck, type)
306 #define LCK_ASSERT_OWNED 1
307 #define LCK_ASSERT_NOTOWNED 2
309 #define LCK_MTX_ASSERT_OWNED LCK_ASSERT_OWNED
310 #define LCK_MTX_ASSERT_NOTOWNED LCK_ASSERT_NOTOWNED
312 #ifdef MACH_KERNEL_PRIVATE
313 extern void lck_mtx_lock_wait(
317 extern int lck_mtx_lock_acquire(
320 extern void lck_mtx_unlock_wakeup(
324 extern boolean_t
lck_mtx_ilk_unlock(
327 extern boolean_t
lck_mtx_ilk_try_lock(
330 extern void lck_mtx_wakeup_adjust_pri(thread_t thread
, integer_t priority
);
334 #define decl_lck_rw_data(class, name) class lck_rw_t name;
336 typedef unsigned int lck_rw_type_t
;
338 #define LCK_RW_TYPE_SHARED 0x01
339 #define LCK_RW_TYPE_EXCLUSIVE 0x02
341 #ifdef XNU_KERNEL_PRIVATE
342 #define LCK_RW_ASSERT_SHARED 0x01
343 #define LCK_RW_ASSERT_EXCLUSIVE 0x02
344 #define LCK_RW_ASSERT_HELD 0x03
345 #define LCK_RW_ASSERT_NOTHELD 0x04
350 extern lck_rw_t
*lck_rw_alloc_init(
354 extern void lck_rw_init(
359 extern void lck_rw_lock(
361 lck_rw_type_t lck_rw_type
);
363 extern void lck_rw_unlock(
365 lck_rw_type_t lck_rw_type
);
367 extern void lck_rw_lock_shared(
370 extern void lck_rw_unlock_shared(
373 extern boolean_t
lck_rw_lock_yield_shared(
375 boolean_t force_yield
);
377 extern void lck_rw_lock_exclusive(
380 extern void lck_rw_unlock_exclusive(
383 #ifdef XNU_KERNEL_PRIVATE
386 * read-write locks do not have a concept of ownership, so lck_rw_assert()
387 * merely asserts that someone is holding the lock, not necessarily the caller.
389 extern void lck_rw_assert(
393 extern void lck_rw_clear_promotion(thread_t thread
, uintptr_t trace_obj
);
394 extern void lck_rw_set_promotion_locked(thread_t thread
);
396 uintptr_t unslide_for_kdebug(void* object
);
397 #endif /* XNU_KERNEL_PRIVATE */
399 #ifdef KERNEL_PRIVATE
401 extern lck_rw_type_t
lck_rw_done(
405 extern void lck_rw_destroy(
409 extern void lck_rw_free(
413 extern wait_result_t
lck_rw_sleep(
415 lck_sleep_action_t lck_sleep_action
,
417 wait_interrupt_t interruptible
);
419 extern wait_result_t
lck_rw_sleep_deadline(
421 lck_sleep_action_t lck_sleep_action
,
423 wait_interrupt_t interruptible
,
426 extern boolean_t
lck_rw_lock_shared_to_exclusive(
429 extern void lck_rw_lock_exclusive_to_shared(
432 extern boolean_t
lck_rw_try_lock(
434 lck_rw_type_t lck_rw_type
);
436 #ifdef KERNEL_PRIVATE
438 extern boolean_t
lck_rw_try_lock_shared(
441 extern boolean_t
lck_rw_try_lock_exclusive(
447 #endif /* _KERN_LOCKS_H_ */