1 /* 2 * Copyright (c) 2022 Apple Inc. All rights reserved. 3 * 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 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. 25 * 26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ 27 */ 28 29 #ifndef _KERN_LOCK_MTX_H_ 30 #define _KERN_LOCK_MTX_H_ 31 32 #include <kern/lock_types.h> 33 #include <kern/lock_group.h> 34 #include <kern/lock_attr.h> 35 36 #ifdef XNU_KERNEL_PRIVATE 37 #include <kern/startup.h> 38 #endif /* XNU_KERNEL_PRIVATE */ 39 40 __BEGIN_DECLS 41 42 #if MACH_KERNEL_PRIVATE 43 #if !LCK_MTX_USE_ARCH 44 45 typedef union lck_mtx_state { 46 struct { 47 uint32_t owner : 28; 48 uint32_t ilocked : 1; 49 uint32_t spin_mode : 1; 50 uint32_t needs_wakeup : 1; 51 uint32_t profile : 1; 52 #define LCK_MTX_CTID_MASK 0x0fffffffu 53 #define LCK_MTX_BITS_MASK 0xf0000000u 54 #define LCK_MTX_ILOCK 0x10000000u 55 #define LCK_MTX_SPIN_MODE 0x20000000u 56 #define LCK_MTX_NEEDS_WAKEUP 0x40000000u 57 #if CONFIG_DTRACE 58 #define LCK_MTX_PROFILE 0x80000000u 59 #else 60 #define LCK_MTX_PROFILE 0x00000000u 61 #endif 62 uint16_t ilk_tail; 63 uint16_t as_tail; 64 }; 65 uint32_t data; 66 uint64_t val; 67 } lck_mtx_state_t; 68 69 typedef struct _lck_mtx_ { 70 uint32_t lck_mtx_tsid : 24; /* turnstile ID */ 71 uint8_t lck_mtx_type : 8; /* Type */ 72 uint32_t lck_mtx_grp; 73 lck_mtx_state_t lck_mtx; 74 } lck_mtx_t; 75 76 /* lock marked as destroyed, sets ILOCK | WAITERS */ 77 #define LCK_MTX_TAG_DESTROYED 0xf0fe2007 78 79 /* 80 * for historical reasons the lck_mtx_t definition for the KDK 81 * are in <machine/locks.h> headers. 82 */ 83 #endif /* !LCK_MTX_USE_ARCH */ 84 #endif 85 86 #define decl_lck_mtx_data(class, name) class lck_mtx_t name 87 88 extern lck_mtx_t *lck_mtx_alloc_init( 89 lck_grp_t *grp, 90 lck_attr_t *attr); 91 92 extern void lck_mtx_init( 93 lck_mtx_t *lck, 94 lck_grp_t *grp, 95 lck_attr_t *attr); 96 extern void lck_mtx_lock( 97 lck_mtx_t *lck); 98 99 extern void lck_mtx_unlock( 100 lck_mtx_t *lck); 101 102 extern void lck_mtx_destroy( 103 lck_mtx_t *lck, 104 lck_grp_t *grp); 105 106 extern void lck_mtx_free( 107 lck_mtx_t *lck, 108 lck_grp_t *grp); 109 110 extern wait_result_t lck_mtx_sleep( 111 lck_mtx_t *lck, 112 lck_sleep_action_t lck_sleep_action, 113 event_t event, 114 wait_interrupt_t interruptible); 115 116 extern wait_result_t lck_mtx_sleep_deadline( 117 lck_mtx_t *lck, 118 lck_sleep_action_t lck_sleep_action, 119 event_t event, 120 wait_interrupt_t interruptible, 121 uint64_t deadline); 122 123 #define LCK_MTX_ASSERT_OWNED LCK_ASSERT_OWNED 124 #define LCK_MTX_ASSERT_NOTOWNED LCK_ASSERT_NOTOWNED 125 126 extern void lck_mtx_assert( 127 lck_mtx_t *lck, 128 unsigned int type); 129 130 #if MACH_ASSERT 131 #define LCK_MTX_ASSERT(lck, type) lck_mtx_assert((lck),(type)) 132 #else /* MACH_ASSERT */ 133 #define LCK_MTX_ASSERT(lck, type) 134 #endif /* MACH_ASSERT */ 135 136 #if DEBUG 137 #define LCK_MTX_ASSERT_DEBUG(lck, type) lck_mtx_assert((lck),(type)) 138 #else /* DEBUG */ 139 #define LCK_MTX_ASSERT_DEBUG(lck, type) 140 #endif /* DEBUG */ 141 142 #if KERNEL_PRIVATE 143 144 extern boolean_t lck_mtx_try_lock( 145 lck_mtx_t *lck); 146 147 extern void mutex_pause(uint32_t); 148 149 extern boolean_t lck_mtx_yield( 150 lck_mtx_t *lck); 151 152 extern boolean_t lck_mtx_try_lock_spin( 153 lck_mtx_t *lck); 154 155 extern void lck_mtx_lock_spin( 156 lck_mtx_t *lck); 157 158 extern boolean_t kdp_lck_mtx_lock_spin_is_acquired( 159 lck_mtx_t *lck); 160 161 extern void lck_mtx_convert_spin( 162 lck_mtx_t *lck); 163 164 extern void lck_mtx_lock_spin_always( 165 lck_mtx_t *lck); 166 167 extern boolean_t lck_mtx_try_lock_spin_always( 168 lck_mtx_t *lck); 169 170 #define lck_mtx_unlock_always(l) lck_mtx_unlock(l) 171 172 #endif /* KERNEL_PRIVATE */ 173 #if XNU_KERNEL_PRIVATE 174 175 struct lck_mtx_startup_spec { 176 lck_mtx_t *lck; 177 lck_grp_t *lck_grp; 178 lck_attr_t *lck_attr; 179 }; 180 181 extern void lck_mtx_startup_init( 182 struct lck_mtx_startup_spec *spec); 183 184 #define LCK_MTX_DECLARE_ATTR(var, grp, attr) \ 185 lck_mtx_t var; \ 186 static __startup_data struct lck_mtx_startup_spec \ 187 __startup_lck_mtx_spec_ ## var = { &var, grp, attr }; \ 188 STARTUP_ARG(LOCKS, STARTUP_RANK_FOURTH, lck_mtx_startup_init, \ 189 &__startup_lck_mtx_spec_ ## var) 190 191 #define LCK_MTX_DECLARE(var, grp) \ 192 LCK_MTX_DECLARE_ATTR(var, grp, LCK_ATTR_NULL) 193 194 #endif /* XNU_KERNEL_PRIVATE */ 195 196 __END_DECLS 197 198 #endif /* _KERN_LOCK_RW_H_ */ 199