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_s { 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 !LCK_MTX_USE_ARCH 131 extern void lck_mtx_assert_owned_spin( 132 lck_mtx_t *lck); 133 #endif /* !LCK_MTX_USE_ARCH */ 134 135 #if MACH_ASSERT 136 #define LCK_MTX_ASSERT(lck, type) MACH_ASSERT_DO(lck_mtx_assert(lck, type)) 137 #if !LCK_MTX_USE_ARCH 138 #define LCK_MTX_ASSERT_OWNED_SPIN(lck) MACH_ASSERT_DO(lck_mtx_assert_owned_spin(lck)) 139 #endif /* !LCK_MTX_USE_ARCH */ 140 #else /* !MACH_ASSERT */ 141 #define LCK_MTX_ASSERT(lck, type) 142 #if !LCK_MTX_USE_ARCH 143 #define LCK_MTX_ASSERT_OWNED_SPIN(lck) 144 #endif /* !LCK_MTX_USE_ARCH */ 145 #endif /* !MACH_ASSERT */ 146 147 #if DEBUG 148 #define LCK_MTX_ASSERT_DEBUG(lck, type) lck_mtx_assert((lck),(type)) 149 #define LCK_MTX_ASSERT_OWNED_SPIN_DEBUG(lck) lck_mtx_assert_owned_spin(lck) 150 #else /* DEBUG */ 151 #define LCK_MTX_ASSERT_DEBUG(lck, type) 152 #if !LCK_MTX_USE_ARCH 153 #define LCK_MTX_ASSERT_OWNED_SPIN_DEBUG(lck) 154 #endif /* !LCK_MTX_USE_ARCH */ 155 #endif /* DEBUG */ 156 157 #if KERNEL_PRIVATE 158 159 extern boolean_t lck_mtx_try_lock( 160 lck_mtx_t *lck); 161 162 extern void mutex_pause(uint32_t); 163 164 extern boolean_t lck_mtx_yield( 165 lck_mtx_t *lck); 166 167 extern boolean_t lck_mtx_try_lock_spin( 168 lck_mtx_t *lck); 169 170 extern void lck_mtx_lock_spin( 171 lck_mtx_t *lck); 172 173 extern boolean_t kdp_lck_mtx_lock_spin_is_acquired( 174 lck_mtx_t *lck); 175 176 extern void lck_mtx_convert_spin( 177 lck_mtx_t *lck); 178 179 extern void lck_mtx_lock_spin_always( 180 lck_mtx_t *lck); 181 182 extern boolean_t lck_mtx_try_lock_spin_always( 183 lck_mtx_t *lck); 184 185 #define lck_mtx_unlock_always(l) lck_mtx_unlock(l) 186 187 #endif /* KERNEL_PRIVATE */ 188 #if XNU_KERNEL_PRIVATE 189 190 struct lck_mtx_startup_spec { 191 lck_mtx_t *lck; 192 lck_grp_t *lck_grp; 193 lck_attr_t *lck_attr; 194 }; 195 196 extern void lck_mtx_startup_init( 197 struct lck_mtx_startup_spec *spec); 198 199 #define LCK_MTX_DECLARE_ATTR(var, grp, attr) \ 200 lck_mtx_t var; \ 201 static __startup_data struct lck_mtx_startup_spec \ 202 __startup_lck_mtx_spec_ ## var = { &var, grp, attr }; \ 203 STARTUP_ARG(LOCKS, STARTUP_RANK_FOURTH, lck_mtx_startup_init, \ 204 &__startup_lck_mtx_spec_ ## var) 205 206 #define LCK_MTX_DECLARE(var, grp) \ 207 LCK_MTX_DECLARE_ATTR(var, grp, LCK_ATTR_NULL) 208 209 #endif /* XNU_KERNEL_PRIVATE */ 210 211 __END_DECLS 212 213 #endif /* _KERN_LOCK_RW_H_ */ 214