1 /* 2 * Copyright (c) 2000-2005 Apple Computer, 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 * Copyright (C) 1998 Apple Computer 30 * All Rights Reserved 31 */ 32 /* 33 * @OSF_COPYRIGHT@ 34 */ 35 /* 36 * Mach Operating System 37 * Copyright (c) 1991,1990,1989,1988,1987 Carnegie Mellon University 38 * All Rights Reserved. 39 * 40 * Permission to use, copy, modify and distribute this software and its 41 * documentation is hereby granted, provided that both the copyright 42 * notice and this permission notice appear in all copies of the 43 * software, derivative works or modified versions, and any portions 44 * thereof, and that both notices appear in supporting documentation. 45 * 46 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" 47 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR 48 * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. 49 * 50 * Carnegie Mellon requests users of this software to return to 51 * 52 * Software Distribution Coordinator or [email protected] 53 * School of Computer Science 54 * Carnegie Mellon University 55 * Pittsburgh PA 15213-3890 56 * 57 * any improvements or extensions that they make and grant Carnegie Mellon 58 * the rights to redistribute these changes. 59 */ 60 /* 61 * File: kern/simple_lock.h (derived from kern/lock.h) 62 * Author: Avadis Tevanian, Jr., Michael Wayne Young 63 * Date: 1985 64 * 65 * Atomic primitives and Simple Locking primitives definitions 66 */ 67 68 #ifdef KERNEL_PRIVATE 69 70 #ifndef _KERN_SIMPLE_LOCK_H_ 71 #define _KERN_SIMPLE_LOCK_H_ 72 73 #include <mach/boolean.h> 74 #include <kern/lock_types.h> 75 #include <kern/lock_group.h> 76 #include <machine/simple_lock.h> 77 78 #ifdef XNU_KERNEL_PRIVATE 79 80 #if MACH_KERNEL_PRIVATE 81 #include <machine/atomic.h> 82 #include <mach_ldebug.h> 83 #endif 84 85 __BEGIN_DECLS 86 87 #pragma GCC visibility push(hidden) 88 89 #ifdef MACH_KERNEL_PRIVATE 90 extern void hw_lock_init( 91 hw_lock_t); 92 93 extern void hw_lock_lock( 94 hw_lock_t 95 LCK_GRP_ARG(lck_grp_t*)); 96 97 extern void hw_lock_lock_nopreempt( 98 hw_lock_t 99 LCK_GRP_ARG(lck_grp_t*)); 100 101 extern unsigned int hw_lock_to( 102 hw_lock_t, 103 uint64_t, 104 hw_lock_timeout_handler_t 105 LCK_GRP_ARG(lck_grp_t*)) __result_use_check; 106 107 extern unsigned int hw_lock_to_nopreempt( 108 hw_lock_t, 109 uint64_t, 110 hw_lock_timeout_handler_t 111 LCK_GRP_ARG(lck_grp_t*)) __result_use_check; 112 113 extern unsigned int hw_lock_try( 114 hw_lock_t 115 LCK_GRP_ARG(lck_grp_t*)) __result_use_check; 116 117 extern unsigned int hw_lock_try_nopreempt( 118 hw_lock_t 119 LCK_GRP_ARG(lck_grp_t*)) __result_use_check; 120 121 #if !LOCK_STATS 122 #define hw_lock_lock(lck, grp) \ 123 hw_lock_lock(lck) 124 125 #define hw_lock_lock_nopreempt(lck, grp) \ 126 hw_lock_lock_nopreempt(lck) 127 128 #define hw_lock_to(lck, timeout, handler, grp) \ 129 hw_lock_to(lck, timeout, handler) 130 131 #define hw_lock_to_nopreempt(lck, timeout, handler, grp) \ 132 hw_lock_to_nopreempt(lck, timeout, handler) 133 134 #define hw_lock_try(lck, grp) \ 135 hw_lock_try(lck) 136 137 #define hw_lock_try_nopreempt(lck, grp) \ 138 hw_lock_try_nopreempt(lck) 139 #endif /* !LOCK_STATS */ 140 141 extern void hw_lock_unlock( 142 hw_lock_t); 143 144 extern void hw_lock_unlock_nopreempt( 145 hw_lock_t); 146 147 extern unsigned int hw_lock_held( 148 hw_lock_t) __result_use_check; 149 150 extern boolean_t hw_atomic_test_and_set32( 151 uint32_t *target, 152 uint32_t test_mask, 153 uint32_t set_mask, 154 enum memory_order ord, 155 boolean_t wait); 156 157 extern boolean_t atomic_test_and_set32( 158 uint32_t *target, 159 uint32_t test_mask, 160 uint32_t set_mask, 161 enum memory_order ord, 162 boolean_t wait); 163 164 extern void atomic_exchange_abort( 165 void); 166 167 extern boolean_t atomic_exchange_complete32( 168 uint32_t *target, 169 uint32_t previous, 170 uint32_t newval, 171 enum memory_order ord); 172 173 extern uint32_t atomic_exchange_begin32( 174 uint32_t *target, 175 uint32_t *previous, 176 enum memory_order ord); 177 178 #if defined(__arm__) || defined(__arm64__) 179 uint32_t load_exclusive32( 180 uint32_t *target, 181 enum memory_order ord); 182 boolean_t store_exclusive32( 183 uint32_t *target, 184 uint32_t value, 185 enum memory_order ord); 186 #endif /* defined(__arm__)||defined(__arm64__) */ 187 188 extern void usimple_unlock_nopreempt( 189 usimple_lock_t); 190 191 #endif /* MACH_KERNEL_PRIVATE */ 192 193 struct usimple_lock_startup_spec { 194 usimple_lock_t lck; 195 unsigned short lck_init_arg; 196 }; 197 198 extern void usimple_lock_startup_init( 199 struct usimple_lock_startup_spec *spec); 200 201 #define SIMPLE_LOCK_DECLARE(var, arg) \ 202 decl_simple_lock_data(, var); \ 203 static __startup_data struct usimple_lock_startup_spec \ 204 __startup_usimple_lock_spec_ ## var = { &var, arg }; \ 205 STARTUP_ARG(LOCKS_EARLY, STARTUP_RANK_FOURTH, usimple_lock_startup_init, \ 206 &__startup_usimple_lock_spec_ ## var) 207 208 extern void * hw_wait_while_equals( 209 void **address, 210 void *current); 211 212 extern void usimple_lock_init( 213 usimple_lock_t, 214 unsigned short); 215 216 extern void usimple_lock( 217 usimple_lock_t 218 LCK_GRP_ARG(lck_grp_t*)); 219 220 extern unsigned int usimple_lock_try( 221 usimple_lock_t 222 LCK_GRP_ARG(lck_grp_t*)) __result_use_check; 223 224 extern void usimple_lock_try_lock_loop( 225 usimple_lock_t 226 LCK_GRP_ARG(lck_grp_t*)); 227 228 #if defined(__x86_64__) 229 extern unsigned int usimple_lock_try_lock_mp_signal_safe_loop_deadline( 230 usimple_lock_t, 231 uint64_t 232 LCK_GRP_ARG(lck_grp_t*)) /* __result_use_check */; 233 234 extern unsigned int usimple_lock_try_lock_mp_signal_safe_loop_duration( 235 usimple_lock_t, 236 uint64_t 237 LCK_GRP_ARG(lck_grp_t*)) __result_use_check; 238 #endif 239 240 extern void usimple_unlock( 241 usimple_lock_t); 242 243 #if !LOCK_STATS 244 #define usimple_lock(lck, grp) \ 245 usimple_lock(lck) 246 247 #define usimple_lock_try(lck, grp) \ 248 usimple_lock_try(lck) 249 250 #define usimple_lock_try_lock_loop(lck, grp) \ 251 usimple_lock_try_lock_loop(lck) 252 253 #if defined(__x86_64__) 254 #define usimple_lock_try_lock_mp_signal_safe_loop_deadline(lck, ddl, grp) \ 255 usimple_lock_try_lock_mp_signal_safe_loop_deadline(lck, ddl) 256 #define usimple_lock_try_lock_mp_signal_safe_loop_duration(lck, dur, grp) \ 257 usimple_lock_try_lock_mp_signal_safe_loop_duration(lck, dur) 258 #endif 259 #endif /* !LOCK_STATS */ 260 261 262 /* 263 * If we got to here and we still don't have simple_lock_init 264 * defined, then we must either be outside the osfmk component, 265 * running on a true SMP, or need debug. 266 */ 267 #if !defined(simple_lock_init) 268 #define simple_lock_init(l, t) usimple_lock_init(l,t) 269 #define simple_lock(l, grp) usimple_lock(l, grp) 270 #define simple_unlock(l) usimple_unlock(l) 271 #define simple_lock_try(l, grp) usimple_lock_try(l, grp) 272 #define simple_lock_try_lock_loop(l, grp) usimple_lock_try_lock_loop(l, grp) 273 #define simple_lock_try_lock_mp_signal_safe_loop_deadline(l, ddl, grp) \ 274 usimple_lock_try_lock_mp_signal_safe_loop_deadline(l, ddl, grp) 275 #define simple_lock_try_lock_mp_signal_safe_loop_duration(l, dur, grp) \ 276 usimple_lock_try_lock_mp_signal_safe_loop_duration(l, dur, grp) 277 #define simple_lock_addr(l) (&(l)) 278 #endif /* !defined(simple_lock_init) */ 279 280 #ifdef MACH_KERNEL_PRIVATE 281 282 typedef uint32_t hw_lock_bit_t; 283 284 extern void hw_lock_bit( 285 hw_lock_bit_t *, 286 unsigned int 287 LCK_GRP_ARG(lck_grp_t*)); 288 289 extern void hw_lock_bit_nopreempt( 290 hw_lock_bit_t *, 291 unsigned int 292 LCK_GRP_ARG(lck_grp_t*)); 293 294 295 extern unsigned int hw_lock_bit_try( 296 hw_lock_bit_t *, 297 unsigned int 298 LCK_GRP_ARG(lck_grp_t*)) __result_use_check; 299 300 extern unsigned int hw_lock_bit_to( 301 hw_lock_bit_t *, 302 unsigned int, 303 uint64_t, 304 hw_lock_timeout_handler_t 305 LCK_GRP_ARG(lck_grp_t*)) __result_use_check; 306 307 extern hw_lock_status_t hw_lock_bit_to_allow_invalid( 308 hw_lock_bit_t *, 309 unsigned int, 310 uint64_t, 311 hw_lock_timeout_handler_t 312 LCK_GRP_ARG(lck_grp_t*)) __result_use_check; 313 314 extern void hw_unlock_bit( 315 hw_lock_bit_t *, 316 unsigned int); 317 318 extern void hw_unlock_bit_nopreempt( 319 hw_lock_bit_t *, 320 unsigned int); 321 322 #define hw_lock_bit_held(l, b) \ 323 (((*(l)) & (1 << (b))) != 0) 324 325 #if !LOCK_STATS 326 #define hw_lock_bit(lck, bit, grp) \ 327 hw_lock_bit(lck, bit) 328 329 #define hw_lock_bit_nopreempt(lck, bit, grp) \ 330 hw_lock_bit_nopreempt(lck, bit) 331 332 333 #define hw_lock_bit_try(lck, bit, grp) \ 334 hw_lock_bit_try(lck, bit) 335 336 #define hw_lock_bit_to(lck, bit, timeout, handler, grp) \ 337 hw_lock_bit_to(lck, bit, timeout, handler) 338 339 #define hw_lock_bit_to_allow_invalid(lck, bit, timeout, handler, grp) \ 340 hw_lock_bit_to_allow_invalid(lck, bit, timeout, handler) 341 #endif /* !LOCK_STATS */ 342 #endif /* MACH_KERNEL_PRIVATE */ 343 344 __END_DECLS 345 346 #pragma GCC visibility pop 347 348 #endif /* XNU_KERNEL_PRIVATE */ 349 #endif /*!_KERN_SIMPLE_LOCK_H_*/ 350 351 #endif /* KERNEL_PRIVATE */ 352