OSAtomicDeprecated.h (46062B) - Raw
1 /* 2 * Copyright (c) 2004-2016 Apple Inc. All rights reserved. 3 * 4 * @APPLE_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. Please obtain a copy of the License at 10 * http://www.opensource.apple.com/apsl/ and read it before using this 11 * file. 12 * 13 * The Original Code and all software distributed under the License are 14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 18 * Please see the License for the specific language governing rights and 19 * limitations under the License. 20 * 21 * @APPLE_LICENSE_HEADER_END@ 22 */ 23 24 #ifndef _OSATOMIC_DEPRECATED_H_ 25 #define _OSATOMIC_DEPRECATED_H_ 26 27 /*! @header 28 * These are deprecated legacy interfaces for atomic operations. 29 * The C11 interfaces in <stdatomic.h> resp. C++11 interfaces in <atomic> 30 * should be used instead. 31 * 32 * Define OSATOMIC_USE_INLINED=1 to get inline implementations of these 33 * interfaces in terms of the <stdatomic.h> resp. <atomic> primitives. 34 * This is intended as a transition convenience, direct use of those primitives 35 * is preferred. 36 */ 37 38 #include <Availability.h> 39 #include <TargetConditionals.h> 40 41 #if !(defined(OSATOMIC_USE_INLINED) && OSATOMIC_USE_INLINED) 42 43 #include <sys/cdefs.h> 44 #include <stddef.h> 45 #include <stdint.h> 46 #include <stdbool.h> 47 48 #ifndef OSATOMIC_DEPRECATED 49 #define OSATOMIC_DEPRECATED 1 50 #ifndef __cplusplus 51 #define OSATOMIC_BARRIER_DEPRECATED_MSG(_r) \ 52 "Use " #_r "() from <stdatomic.h> instead" 53 #define OSATOMIC_DEPRECATED_MSG(_r) \ 54 "Use " #_r "_explicit(memory_order_relaxed) from <stdatomic.h> instead" 55 #else 56 #define OSATOMIC_BARRIER_DEPRECATED_MSG(_r) \ 57 "Use std::" #_r "() from <atomic> instead" 58 #define OSATOMIC_DEPRECATED_MSG(_r) \ 59 "Use std::" #_r "_explicit(std::memory_order_relaxed) from <atomic> instead" 60 #endif 61 #define OSATOMIC_BARRIER_DEPRECATED_REPLACE_WITH(_r) \ 62 __OS_AVAILABILITY_MSG(macosx, deprecated=10.12, OSATOMIC_BARRIER_DEPRECATED_MSG(_r)) \ 63 __OS_AVAILABILITY_MSG(ios, deprecated=10.0, OSATOMIC_BARRIER_DEPRECATED_MSG(_r)) \ 64 __OS_AVAILABILITY_MSG(tvos, deprecated=10.0, OSATOMIC_BARRIER_DEPRECATED_MSG(_r)) \ 65 __OS_AVAILABILITY_MSG(watchos, deprecated=3.0, OSATOMIC_BARRIER_DEPRECATED_MSG(_r)) 66 #define OSATOMIC_DEPRECATED_REPLACE_WITH(_r) \ 67 __OS_AVAILABILITY_MSG(macosx, deprecated=10.12, OSATOMIC_DEPRECATED_MSG(_r)) \ 68 __OS_AVAILABILITY_MSG(ios, deprecated=10.0, OSATOMIC_DEPRECATED_MSG(_r)) \ 69 __OS_AVAILABILITY_MSG(tvos, deprecated=10.0, OSATOMIC_DEPRECATED_MSG(_r)) \ 70 __OS_AVAILABILITY_MSG(watchos, deprecated=3.0, OSATOMIC_DEPRECATED_MSG(_r)) 71 #else 72 #undef OSATOMIC_DEPRECATED 73 #define OSATOMIC_DEPRECATED 0 74 #define OSATOMIC_BARRIER_DEPRECATED_REPLACE_WITH(_r) 75 #define OSATOMIC_DEPRECATED_REPLACE_WITH(_r) 76 #endif 77 78 /* 79 * WARNING: all addresses passed to these functions must be "naturally aligned", 80 * i.e. <code>int32_t</code> pointers must be 32-bit aligned (low 2 bits of 81 * address are zeroes), and <code>int64_t</code> pointers must be 64-bit 82 * aligned (low 3 bits of address are zeroes.). 83 * Note that this is not the default alignment of the <code>int64_t</code> type 84 * in the iOS ARMv7 ABI, see 85 * {@link //apple_ref/doc/uid/TP40009021-SW8 iPhoneOSABIReference} 86 * 87 * Note that some versions of the atomic functions incorporate memory barriers 88 * and some do not. Barriers strictly order memory access on weakly-ordered 89 * architectures such as ARM. All loads and stores that appear (in sequential 90 * program order) before the barrier are guaranteed to complete before any 91 * load or store that appears after the barrier. 92 * 93 * The barrier operation is typically a no-op on uniprocessor systems and 94 * fully enabled on multiprocessor systems. On some platforms, such as ARM, 95 * the barrier can be quite expensive. 96 * 97 * Most code should use the barrier functions to ensure that memory shared 98 * between threads is properly synchronized. For example, if you want to 99 * initialize a shared data structure and then atomically increment a variable 100 * to indicate that the initialization is complete, you must use 101 * {@link OSAtomicIncrement32Barrier} to ensure that the stores to your data 102 * structure complete before the atomic increment. 103 * 104 * Likewise, the consumer of that data structure must use 105 * {@link OSAtomicDecrement32Barrier}, 106 * in order to ensure that their loads of the structure are not executed before 107 * the atomic decrement. On the other hand, if you are simply incrementing a 108 * global counter, then it is safe and potentially faster to use 109 * {@link OSAtomicIncrement32}. 110 * 111 * If you are unsure which version to use, prefer the barrier variants as they 112 * are safer. 113 * 114 * For the kernel-space version of this header, see 115 * {@link //apple_ref/doc/header/OSAtomic.h OSAtomic.h (Kernel Framework)} 116 * 117 * @apiuid //apple_ref/doc/header/user_space_OSAtomic.h 118 */ 119 120 __BEGIN_DECLS 121 122 /*! @typedef OSAtomic_int64_aligned64_t 123 * 64-bit aligned <code>int64_t</code> type. 124 * Use for variables whose addresses are passed to OSAtomic*64() functions to 125 * get the compiler to generate the required alignment. 126 */ 127 128 #if __has_attribute(aligned) 129 typedef int64_t __attribute__((__aligned__((sizeof(int64_t))))) 130 OSAtomic_int64_aligned64_t; 131 #else 132 typedef int64_t OSAtomic_int64_aligned64_t; 133 #endif 134 135 /*! @group Arithmetic functions 136 All functions in this group return the new value. 137 */ 138 139 /*! @abstract Atomically adds two 32-bit values. 140 @discussion 141 This function adds the value given by <code>__theAmount</code> to the 142 value in the memory location referenced by <code>__theValue</code>, 143 storing the result back to that memory location atomically. 144 @result Returns the new value. 145 */ 146 OSATOMIC_DEPRECATED_REPLACE_WITH(atomic_fetch_add) 147 __OSX_AVAILABLE_STARTING(__MAC_10_4, __IPHONE_2_0) 148 int32_t OSAtomicAdd32( int32_t __theAmount, volatile int32_t *__theValue ); 149 150 151 /*! @abstract Atomically adds two 32-bit values. 152 @discussion 153 This function adds the value given by <code>__theAmount</code> to the 154 value in the memory location referenced by <code>__theValue</code>, 155 storing the result back to that memory location atomically. 156 157 This function is equivalent to {@link OSAtomicAdd32} 158 except that it also introduces a barrier. 159 @result Returns the new value. 160 */ 161 OSATOMIC_BARRIER_DEPRECATED_REPLACE_WITH(atomic_fetch_add) 162 __OSX_AVAILABLE_STARTING(__MAC_10_4, __IPHONE_2_0) 163 int32_t OSAtomicAdd32Barrier( int32_t __theAmount, volatile int32_t *__theValue ); 164 165 166 #if __MAC_OS_X_VERSION_MIN_REQUIRED >= __MAC_10_10 || __IPHONE_OS_VERSION_MIN_REQUIRED >= __IPHONE_7_1 || TARGET_OS_DRIVERKIT 167 168 /*! @abstract Atomically increments a 32-bit value. 169 @result Returns the new value. 170 */ 171 OSATOMIC_DEPRECATED_REPLACE_WITH(atomic_fetch_add) 172 __OSX_AVAILABLE_STARTING(__MAC_10_10, __IPHONE_7_1) 173 int32_t OSAtomicIncrement32( volatile int32_t *__theValue ); 174 175 176 /*! @abstract Atomically increments a 32-bit value with a barrier. 177 @discussion 178 This function is equivalent to {@link OSAtomicIncrement32} 179 except that it also introduces a barrier. 180 @result Returns the new value. 181 */ 182 OSATOMIC_BARRIER_DEPRECATED_REPLACE_WITH(atomic_fetch_add) 183 __OSX_AVAILABLE_STARTING(__MAC_10_10, __IPHONE_7_1) 184 int32_t OSAtomicIncrement32Barrier( volatile int32_t *__theValue ); 185 186 187 /*! @abstract Atomically decrements a 32-bit value. 188 @result Returns the new value. 189 */ 190 OSATOMIC_DEPRECATED_REPLACE_WITH(atomic_fetch_sub) 191 __OSX_AVAILABLE_STARTING(__MAC_10_10, __IPHONE_7_1) 192 int32_t OSAtomicDecrement32( volatile int32_t *__theValue ); 193 194 195 /*! @abstract Atomically decrements a 32-bit value with a barrier. 196 @discussion 197 This function is equivalent to {@link OSAtomicDecrement32} 198 except that it also introduces a barrier. 199 @result Returns the new value. 200 */ 201 OSATOMIC_BARRIER_DEPRECATED_REPLACE_WITH(atomic_fetch_sub) 202 __OSX_AVAILABLE_STARTING(__MAC_10_10, __IPHONE_7_1) 203 int32_t OSAtomicDecrement32Barrier( volatile int32_t *__theValue ); 204 205 #else 206 __inline static 207 int32_t OSAtomicIncrement32( volatile int32_t *__theValue ) 208 { return OSAtomicAdd32( 1, __theValue); } 209 210 __inline static 211 int32_t OSAtomicIncrement32Barrier( volatile int32_t *__theValue ) 212 { return OSAtomicAdd32Barrier( 1, __theValue); } 213 214 __inline static 215 int32_t OSAtomicDecrement32( volatile int32_t *__theValue ) 216 { return OSAtomicAdd32( -1, __theValue); } 217 218 __inline static 219 int32_t OSAtomicDecrement32Barrier( volatile int32_t *__theValue ) 220 { return OSAtomicAdd32Barrier( -1, __theValue); } 221 #endif 222 223 224 /*! @abstract Atomically adds two 64-bit values. 225 @discussion 226 This function adds the value given by <code>__theAmount</code> to the 227 value in the memory location referenced by <code>__theValue</code>, 228 storing the result back to that memory location atomically. 229 @result Returns the new value. 230 */ 231 OSATOMIC_DEPRECATED_REPLACE_WITH(atomic_fetch_add) 232 __OSX_AVAILABLE_STARTING(__MAC_10_4, __IPHONE_2_0) 233 int64_t OSAtomicAdd64( int64_t __theAmount, 234 volatile OSAtomic_int64_aligned64_t *__theValue ); 235 236 237 /*! @abstract Atomically adds two 64-bit values with a barrier. 238 @discussion 239 This function adds the value given by <code>__theAmount</code> to the 240 value in the memory location referenced by <code>__theValue</code>, 241 storing the result back to that memory location atomically. 242 243 This function is equivalent to {@link OSAtomicAdd64} 244 except that it also introduces a barrier. 245 @result Returns the new value. 246 */ 247 OSATOMIC_BARRIER_DEPRECATED_REPLACE_WITH(atomic_fetch_add) 248 __OSX_AVAILABLE_STARTING(__MAC_10_4, __IPHONE_3_2) 249 int64_t OSAtomicAdd64Barrier( int64_t __theAmount, 250 volatile OSAtomic_int64_aligned64_t *__theValue ); 251 252 253 #if __MAC_OS_X_VERSION_MIN_REQUIRED >= __MAC_10_10 || __IPHONE_OS_VERSION_MIN_REQUIRED >= __IPHONE_7_1 || TARGET_OS_DRIVERKIT 254 255 /*! @abstract Atomically increments a 64-bit value. 256 @result Returns the new value. 257 */ 258 OSATOMIC_DEPRECATED_REPLACE_WITH(atomic_fetch_add) 259 __OSX_AVAILABLE_STARTING(__MAC_10_10, __IPHONE_7_1) 260 int64_t OSAtomicIncrement64( volatile OSAtomic_int64_aligned64_t *__theValue ); 261 262 263 /*! @abstract Atomically increments a 64-bit value with a barrier. 264 @discussion 265 This function is equivalent to {@link OSAtomicIncrement64} 266 except that it also introduces a barrier. 267 @result Returns the new value. 268 */ 269 OSATOMIC_BARRIER_DEPRECATED_REPLACE_WITH(atomic_fetch_add) 270 __OSX_AVAILABLE_STARTING(__MAC_10_10, __IPHONE_7_1) 271 int64_t OSAtomicIncrement64Barrier( volatile OSAtomic_int64_aligned64_t *__theValue ); 272 273 274 /*! @abstract Atomically decrements a 64-bit value. 275 @result Returns the new value. 276 */ 277 OSATOMIC_DEPRECATED_REPLACE_WITH(atomic_fetch_sub) 278 __OSX_AVAILABLE_STARTING(__MAC_10_10, __IPHONE_7_1) 279 int64_t OSAtomicDecrement64( volatile OSAtomic_int64_aligned64_t *__theValue ); 280 281 282 /*! @abstract Atomically decrements a 64-bit value with a barrier. 283 @discussion 284 This function is equivalent to {@link OSAtomicDecrement64} 285 except that it also introduces a barrier. 286 @result Returns the new value. 287 */ 288 OSATOMIC_BARRIER_DEPRECATED_REPLACE_WITH(atomic_fetch_sub) 289 __OSX_AVAILABLE_STARTING(__MAC_10_10, __IPHONE_7_1) 290 int64_t OSAtomicDecrement64Barrier( volatile OSAtomic_int64_aligned64_t *__theValue ); 291 292 #else 293 __inline static 294 int64_t OSAtomicIncrement64( volatile OSAtomic_int64_aligned64_t *__theValue ) 295 { return OSAtomicAdd64( 1, __theValue); } 296 297 __inline static 298 int64_t OSAtomicIncrement64Barrier( volatile OSAtomic_int64_aligned64_t *__theValue ) 299 { return OSAtomicAdd64Barrier( 1, __theValue); } 300 301 __inline static 302 int64_t OSAtomicDecrement64( volatile OSAtomic_int64_aligned64_t *__theValue ) 303 { return OSAtomicAdd64( -1, __theValue); } 304 305 __inline static 306 int64_t OSAtomicDecrement64Barrier( volatile OSAtomic_int64_aligned64_t *__theValue ) 307 { return OSAtomicAdd64Barrier( -1, __theValue); } 308 #endif 309 310 311 /*! @group Boolean functions (AND, OR, XOR) 312 * 313 * @discussion Functions in this group come in four variants for each operation: 314 * with and without barriers, and functions that return the original value or 315 * the result value of the operation. 316 * 317 * The "Orig" versions return the original value, (before the operation); the non-Orig 318 * versions return the value after the operation. All are layered on top of 319 * {@link OSAtomicCompareAndSwap32} and similar. 320 */ 321 322 /*! @abstract Atomic bitwise OR of two 32-bit values. 323 @discussion 324 This function performs the bitwise OR of the value given by <code>__theMask</code> 325 with the value in the memory location referenced by <code>__theValue</code>, 326 storing the result back to that memory location atomically. 327 @result Returns the new value. 328 */ 329 OSATOMIC_DEPRECATED_REPLACE_WITH(atomic_fetch_or) 330 __OSX_AVAILABLE_STARTING(__MAC_10_4, __IPHONE_2_0) 331 int32_t OSAtomicOr32( uint32_t __theMask, volatile uint32_t *__theValue ); 332 333 334 /*! @abstract Atomic bitwise OR of two 32-bit values with barrier. 335 @discussion 336 This function performs the bitwise OR of the value given by <code>__theMask</code> 337 with the value in the memory location referenced by <code>__theValue</code>, 338 storing the result back to that memory location atomically. 339 340 This function is equivalent to {@link OSAtomicOr32} 341 except that it also introduces a barrier. 342 @result Returns the new value. 343 */ 344 OSATOMIC_BARRIER_DEPRECATED_REPLACE_WITH(atomic_fetch_or) 345 __OSX_AVAILABLE_STARTING(__MAC_10_4, __IPHONE_2_0) 346 int32_t OSAtomicOr32Barrier( uint32_t __theMask, volatile uint32_t *__theValue ); 347 348 349 /*! @abstract Atomic bitwise OR of two 32-bit values returning original. 350 @discussion 351 This function performs the bitwise OR of the value given by <code>__theMask</code> 352 with the value in the memory location referenced by <code>__theValue</code>, 353 storing the result back to that memory location atomically. 354 @result Returns the original value referenced by <code>__theValue</code>. 355 */ 356 OSATOMIC_DEPRECATED_REPLACE_WITH(atomic_fetch_or) 357 __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_3_2) 358 int32_t OSAtomicOr32Orig( uint32_t __theMask, volatile uint32_t *__theValue ); 359 360 361 /*! @abstract Atomic bitwise OR of two 32-bit values returning original with barrier. 362 @discussion 363 This function performs the bitwise OR of the value given by <code>__theMask</code> 364 with the value in the memory location referenced by <code>__theValue</code>, 365 storing the result back to that memory location atomically. 366 367 This function is equivalent to {@link OSAtomicOr32Orig} 368 except that it also introduces a barrier. 369 @result Returns the original value referenced by <code>__theValue</code>. 370 */ 371 OSATOMIC_BARRIER_DEPRECATED_REPLACE_WITH(atomic_fetch_or) 372 __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_3_2) 373 int32_t OSAtomicOr32OrigBarrier( uint32_t __theMask, volatile uint32_t *__theValue ); 374 375 376 377 378 /*! @abstract Atomic bitwise AND of two 32-bit values. 379 @discussion 380 This function performs the bitwise AND of the value given by <code>__theMask</code> 381 with the value in the memory location referenced by <code>__theValue</code>, 382 storing the result back to that memory location atomically. 383 @result Returns the new value. 384 */ 385 OSATOMIC_DEPRECATED_REPLACE_WITH(atomic_fetch_and) 386 __OSX_AVAILABLE_STARTING(__MAC_10_4, __IPHONE_2_0) 387 int32_t OSAtomicAnd32( uint32_t __theMask, volatile uint32_t *__theValue ); 388 389 390 /*! @abstract Atomic bitwise AND of two 32-bit values with barrier. 391 @discussion 392 This function performs the bitwise AND of the value given by <code>__theMask</code> 393 with the value in the memory location referenced by <code>__theValue</code>, 394 storing the result back to that memory location atomically. 395 396 This function is equivalent to {@link OSAtomicAnd32} 397 except that it also introduces a barrier. 398 @result Returns the new value. 399 */ 400 OSATOMIC_BARRIER_DEPRECATED_REPLACE_WITH(atomic_fetch_and) 401 __OSX_AVAILABLE_STARTING(__MAC_10_4, __IPHONE_2_0) 402 int32_t OSAtomicAnd32Barrier( uint32_t __theMask, volatile uint32_t *__theValue ); 403 404 405 /*! @abstract Atomic bitwise AND of two 32-bit values returning original. 406 @discussion 407 This function performs the bitwise AND of the value given by <code>__theMask</code> 408 with the value in the memory location referenced by <code>__theValue</code>, 409 storing the result back to that memory location atomically. 410 @result Returns the original value referenced by <code>__theValue</code>. 411 */ 412 OSATOMIC_DEPRECATED_REPLACE_WITH(atomic_fetch_and) 413 __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_3_2) 414 int32_t OSAtomicAnd32Orig( uint32_t __theMask, volatile uint32_t *__theValue ); 415 416 417 /*! @abstract Atomic bitwise AND of two 32-bit values returning original with barrier. 418 @discussion 419 This function performs the bitwise AND of the value given by <code>__theMask</code> 420 with the value in the memory location referenced by <code>__theValue</code>, 421 storing the result back to that memory location atomically. 422 423 This function is equivalent to {@link OSAtomicAnd32Orig} 424 except that it also introduces a barrier. 425 @result Returns the original value referenced by <code>__theValue</code>. 426 */ 427 OSATOMIC_BARRIER_DEPRECATED_REPLACE_WITH(atomic_fetch_and) 428 __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_3_2) 429 int32_t OSAtomicAnd32OrigBarrier( uint32_t __theMask, volatile uint32_t *__theValue ); 430 431 432 433 434 /*! @abstract Atomic bitwise XOR of two 32-bit values. 435 @discussion 436 This function performs the bitwise XOR of the value given by <code>__theMask</code> 437 with the value in the memory location referenced by <code>__theValue</code>, 438 storing the result back to that memory location atomically. 439 @result Returns the new value. 440 */ 441 OSATOMIC_DEPRECATED_REPLACE_WITH(atomic_fetch_xor) 442 __OSX_AVAILABLE_STARTING(__MAC_10_4, __IPHONE_2_0) 443 int32_t OSAtomicXor32( uint32_t __theMask, volatile uint32_t *__theValue ); 444 445 446 /*! @abstract Atomic bitwise XOR of two 32-bit values with barrier. 447 @discussion 448 This function performs the bitwise XOR of the value given by <code>__theMask</code> 449 with the value in the memory location referenced by <code>__theValue</code>, 450 storing the result back to that memory location atomically. 451 452 This function is equivalent to {@link OSAtomicXor32} 453 except that it also introduces a barrier. 454 @result Returns the new value. 455 */ 456 OSATOMIC_BARRIER_DEPRECATED_REPLACE_WITH(atomic_fetch_xor) 457 __OSX_AVAILABLE_STARTING(__MAC_10_4, __IPHONE_2_0) 458 int32_t OSAtomicXor32Barrier( uint32_t __theMask, volatile uint32_t *__theValue ); 459 460 461 /*! @abstract Atomic bitwise XOR of two 32-bit values returning original. 462 @discussion 463 This function performs the bitwise XOR of the value given by <code>__theMask</code> 464 with the value in the memory location referenced by <code>__theValue</code>, 465 storing the result back to that memory location atomically. 466 @result Returns the original value referenced by <code>__theValue</code>. 467 */ 468 OSATOMIC_DEPRECATED_REPLACE_WITH(atomic_fetch_xor) 469 __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_3_2) 470 int32_t OSAtomicXor32Orig( uint32_t __theMask, volatile uint32_t *__theValue ); 471 472 473 /*! @abstract Atomic bitwise XOR of two 32-bit values returning original with barrier. 474 @discussion 475 This function performs the bitwise XOR of the value given by <code>__theMask</code> 476 with the value in the memory location referenced by <code>__theValue</code>, 477 storing the result back to that memory location atomically. 478 479 This function is equivalent to {@link OSAtomicXor32Orig} 480 except that it also introduces a barrier. 481 @result Returns the original value referenced by <code>__theValue</code>. 482 */ 483 OSATOMIC_BARRIER_DEPRECATED_REPLACE_WITH(atomic_fetch_xor) 484 __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_3_2) 485 int32_t OSAtomicXor32OrigBarrier( uint32_t __theMask, volatile uint32_t *__theValue ); 486 487 488 /*! @group Compare and swap 489 * Functions in this group return true if the swap occured. There are several versions, 490 * depending on data type and on whether or not a barrier is used. 491 */ 492 493 494 /*! @abstract Compare and swap for 32-bit values. 495 @discussion 496 This function compares the value in <code>__oldValue</code> to the value 497 in the memory location referenced by <code>__theValue</code>. If the values 498 match, this function stores the value from <code>__newValue</code> into 499 that memory location atomically. 500 @result Returns TRUE on a match, FALSE otherwise. 501 */ 502 OSATOMIC_DEPRECATED_REPLACE_WITH(atomic_compare_exchange_strong) 503 __OSX_AVAILABLE_STARTING(__MAC_10_4, __IPHONE_2_0) 504 bool OSAtomicCompareAndSwap32( int32_t __oldValue, int32_t __newValue, volatile int32_t *__theValue ); 505 506 507 /*! @abstract Compare and swap for 32-bit values with barrier. 508 @discussion 509 This function compares the value in <code>__oldValue</code> to the value 510 in the memory location referenced by <code>__theValue</code>. If the values 511 match, this function stores the value from <code>__newValue</code> into 512 that memory location atomically. 513 514 This function is equivalent to {@link OSAtomicCompareAndSwap32} 515 except that it also introduces a barrier. 516 @result Returns TRUE on a match, FALSE otherwise. 517 */ 518 OSATOMIC_BARRIER_DEPRECATED_REPLACE_WITH(atomic_compare_exchange_strong) 519 __OSX_AVAILABLE_STARTING(__MAC_10_4, __IPHONE_2_0) 520 bool OSAtomicCompareAndSwap32Barrier( int32_t __oldValue, int32_t __newValue, volatile int32_t *__theValue ); 521 522 523 /*! @abstract Compare and swap pointers. 524 @discussion 525 This function compares the pointer stored in <code>__oldValue</code> to the pointer 526 in the memory location referenced by <code>__theValue</code>. If the pointers 527 match, this function stores the pointer from <code>__newValue</code> into 528 that memory location atomically. 529 @result Returns TRUE on a match, FALSE otherwise. 530 */ 531 OSATOMIC_DEPRECATED_REPLACE_WITH(atomic_compare_exchange_strong) 532 __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0) 533 bool OSAtomicCompareAndSwapPtr( void *__oldValue, void *__newValue, void * volatile *__theValue ); 534 535 536 /*! @abstract Compare and swap pointers with barrier. 537 @discussion 538 This function compares the pointer stored in <code>__oldValue</code> to the pointer 539 in the memory location referenced by <code>__theValue</code>. If the pointers 540 match, this function stores the pointer from <code>__newValue</code> into 541 that memory location atomically. 542 543 This function is equivalent to {@link OSAtomicCompareAndSwapPtr} 544 except that it also introduces a barrier. 545 @result Returns TRUE on a match, FALSE otherwise. 546 */ 547 OSATOMIC_BARRIER_DEPRECATED_REPLACE_WITH(atomic_compare_exchange_strong) 548 __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0) 549 bool OSAtomicCompareAndSwapPtrBarrier( void *__oldValue, void *__newValue, void * volatile *__theValue ); 550 551 552 /*! @abstract Compare and swap for <code>int</code> values. 553 @discussion 554 This function compares the value in <code>__oldValue</code> to the value 555 in the memory location referenced by <code>__theValue</code>. If the values 556 match, this function stores the value from <code>__newValue</code> into 557 that memory location atomically. 558 559 This function is equivalent to {@link OSAtomicCompareAndSwap32}. 560 @result Returns TRUE on a match, FALSE otherwise. 561 */ 562 OSATOMIC_DEPRECATED_REPLACE_WITH(atomic_compare_exchange_strong) 563 __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0) 564 bool OSAtomicCompareAndSwapInt( int __oldValue, int __newValue, volatile int *__theValue ); 565 566 567 /*! @abstract Compare and swap for <code>int</code> values. 568 @discussion 569 This function compares the value in <code>__oldValue</code> to the value 570 in the memory location referenced by <code>__theValue</code>. If the values 571 match, this function stores the value from <code>__newValue</code> into 572 that memory location atomically. 573 574 This function is equivalent to {@link OSAtomicCompareAndSwapInt} 575 except that it also introduces a barrier. 576 577 This function is equivalent to {@link OSAtomicCompareAndSwap32Barrier}. 578 @result Returns TRUE on a match, FALSE otherwise. 579 */ 580 OSATOMIC_BARRIER_DEPRECATED_REPLACE_WITH(atomic_compare_exchange_strong) 581 __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0) 582 bool OSAtomicCompareAndSwapIntBarrier( int __oldValue, int __newValue, volatile int *__theValue ); 583 584 585 /*! @abstract Compare and swap for <code>long</code> values. 586 @discussion 587 This function compares the value in <code>__oldValue</code> to the value 588 in the memory location referenced by <code>__theValue</code>. If the values 589 match, this function stores the value from <code>__newValue</code> into 590 that memory location atomically. 591 592 This function is equivalent to {@link OSAtomicCompareAndSwap32} on 32-bit architectures, 593 or {@link OSAtomicCompareAndSwap64} on 64-bit architectures. 594 @result Returns TRUE on a match, FALSE otherwise. 595 */ 596 OSATOMIC_DEPRECATED_REPLACE_WITH(atomic_compare_exchange_strong) 597 __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0) 598 bool OSAtomicCompareAndSwapLong( long __oldValue, long __newValue, volatile long *__theValue ); 599 600 601 /*! @abstract Compare and swap for <code>long</code> values. 602 @discussion 603 This function compares the value in <code>__oldValue</code> to the value 604 in the memory location referenced by <code>__theValue</code>. If the values 605 match, this function stores the value from <code>__newValue</code> into 606 that memory location atomically. 607 608 This function is equivalent to {@link OSAtomicCompareAndSwapLong} 609 except that it also introduces a barrier. 610 611 This function is equivalent to {@link OSAtomicCompareAndSwap32} on 32-bit architectures, 612 or {@link OSAtomicCompareAndSwap64} on 64-bit architectures. 613 @result Returns TRUE on a match, FALSE otherwise. 614 */ 615 OSATOMIC_BARRIER_DEPRECATED_REPLACE_WITH(atomic_compare_exchange_strong) 616 __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0) 617 bool OSAtomicCompareAndSwapLongBarrier( long __oldValue, long __newValue, volatile long *__theValue ); 618 619 620 /*! @abstract Compare and swap for <code>uint64_t</code> values. 621 @discussion 622 This function compares the value in <code>__oldValue</code> to the value 623 in the memory location referenced by <code>__theValue</code>. If the values 624 match, this function stores the value from <code>__newValue</code> into 625 that memory location atomically. 626 @result Returns TRUE on a match, FALSE otherwise. 627 */ 628 OSATOMIC_DEPRECATED_REPLACE_WITH(atomic_compare_exchange_strong) 629 __OSX_AVAILABLE_STARTING(__MAC_10_4, __IPHONE_2_0) 630 bool OSAtomicCompareAndSwap64( int64_t __oldValue, int64_t __newValue, 631 volatile OSAtomic_int64_aligned64_t *__theValue ); 632 633 634 /*! @abstract Compare and swap for <code>uint64_t</code> values. 635 @discussion 636 This function compares the value in <code>__oldValue</code> to the value 637 in the memory location referenced by <code>__theValue</code>. If the values 638 match, this function stores the value from <code>__newValue</code> into 639 that memory location atomically. 640 641 This function is equivalent to {@link OSAtomicCompareAndSwap64} 642 except that it also introduces a barrier. 643 @result Returns TRUE on a match, FALSE otherwise. 644 */ 645 OSATOMIC_BARRIER_DEPRECATED_REPLACE_WITH(atomic_compare_exchange_strong) 646 __OSX_AVAILABLE_STARTING(__MAC_10_4, __IPHONE_3_2) 647 bool OSAtomicCompareAndSwap64Barrier( int64_t __oldValue, int64_t __newValue, 648 volatile OSAtomic_int64_aligned64_t *__theValue ); 649 650 651 /* Test and set. 652 * They return the original value of the bit, and operate on bit (0x80>>(n&7)) 653 * in byte ((char*)theAddress + (n>>3)). 654 */ 655 /*! @abstract Atomic test and set 656 @discussion 657 This function tests a bit in the value referenced by 658 <code>__theAddress</code> and if it is not set, sets it. 659 660 The bit is chosen by the value of <code>__n</code> such that the 661 operation will be performed on bit <code>(0x80 >> (__n & 7))</code> 662 of byte <code>((char *)__theAddress + (n >> 3))</code>. 663 664 For example, if <code>__theAddress</code> points to a 64-bit value, 665 to compare the value of the most significant bit, you would specify 666 <code>56</code> for <code>__n</code>. 667 @result 668 Returns the original value of the bit being tested. 669 */ 670 OSATOMIC_DEPRECATED_REPLACE_WITH(atomic_fetch_or) 671 __OSX_AVAILABLE_STARTING(__MAC_10_4, __IPHONE_2_0) 672 bool OSAtomicTestAndSet( uint32_t __n, volatile void *__theAddress ); 673 674 675 /*! @abstract Atomic test and set with barrier 676 @discussion 677 This function tests a bit in the value referenced by <code>__theAddress</code> 678 and if it is not set, sets it. 679 680 The bit is chosen by the value of <code>__n</code> such that the 681 operation will be performed on bit <code>(0x80 >> (__n & 7))</code> 682 of byte <code>((char *)__theAddress + (n >> 3))</code>. 683 684 For example, if <code>__theAddress</code> points to a 64-bit value, 685 to compare the value of the most significant bit, you would specify 686 <code>56</code> for <code>__n</code>. 687 688 This function is equivalent to {@link OSAtomicTestAndSet} 689 except that it also introduces a barrier. 690 @result 691 Returns the original value of the bit being tested. 692 */ 693 OSATOMIC_BARRIER_DEPRECATED_REPLACE_WITH(atomic_fetch_or) 694 __OSX_AVAILABLE_STARTING(__MAC_10_4, __IPHONE_2_0) 695 bool OSAtomicTestAndSetBarrier( uint32_t __n, volatile void *__theAddress ); 696 697 698 699 /*! @abstract Atomic test and clear 700 @discussion 701 This function tests a bit in the value referenced by <code>__theAddress</code> 702 and if it is not cleared, clears it. 703 704 The bit is chosen by the value of <code>__n</code> such that the 705 operation will be performed on bit <code>(0x80 >> (__n & 7))</code> 706 of byte <code>((char *)__theAddress + (n >> 3))</code>. 707 708 For example, if <code>__theAddress</code> points to a 64-bit value, 709 to compare the value of the most significant bit, you would specify 710 <code>56</code> for <code>__n</code>. 711 712 @result 713 Returns the original value of the bit being tested. 714 */ 715 OSATOMIC_DEPRECATED_REPLACE_WITH(atomic_fetch_and) 716 __OSX_AVAILABLE_STARTING(__MAC_10_4, __IPHONE_2_0) 717 bool OSAtomicTestAndClear( uint32_t __n, volatile void *__theAddress ); 718 719 720 /*! @abstract Atomic test and clear 721 @discussion 722 This function tests a bit in the value referenced by <code>__theAddress</code> 723 and if it is not cleared, clears it. 724 725 The bit is chosen by the value of <code>__n</code> such that the 726 operation will be performed on bit <code>(0x80 >> (__n & 7))</code> 727 of byte <code>((char *)__theAddress + (n >> 3))</code>. 728 729 For example, if <code>__theAddress</code> points to a 64-bit value, 730 to compare the value of the most significant bit, you would specify 731 <code>56</code> for <code>__n</code>. 732 733 This function is equivalent to {@link OSAtomicTestAndSet} 734 except that it also introduces a barrier. 735 @result 736 Returns the original value of the bit being tested. 737 */ 738 OSATOMIC_BARRIER_DEPRECATED_REPLACE_WITH(atomic_fetch_and) 739 __OSX_AVAILABLE_STARTING(__MAC_10_4, __IPHONE_2_0) 740 bool OSAtomicTestAndClearBarrier( uint32_t __n, volatile void *__theAddress ); 741 742 743 /*! @group Memory barriers */ 744 745 /*! @abstract Memory barrier. 746 @discussion 747 This function serves as both a read and write barrier. 748 */ 749 OSATOMIC_BARRIER_DEPRECATED_REPLACE_WITH(atomic_thread_fence) 750 __OSX_AVAILABLE_STARTING(__MAC_10_4, __IPHONE_2_0) 751 void OSMemoryBarrier( void ); 752 753 __END_DECLS 754 755 #else // defined(OSATOMIC_USE_INLINED) && OSATOMIC_USE_INLINED 756 757 /* 758 * Inline implementations of the legacy OSAtomic interfaces in terms of 759 * C11 <stdatomic.h> resp. C++11 <atomic> primitives. 760 * Direct use of those primitives is preferred. 761 */ 762 763 #include <sys/cdefs.h> 764 765 #include <stddef.h> 766 #include <stdint.h> 767 #include <stdbool.h> 768 769 #ifdef __cplusplus 770 extern "C++" { 771 #if !(__has_include(<atomic>) && __has_extension(cxx_atomic)) 772 #error Cannot use inlined OSAtomic without <atomic> and C++11 atomics 773 #endif 774 #include <atomic> 775 typedef std::atomic<uint8_t> _OSAtomic_uint8_t; 776 typedef std::atomic<int32_t> _OSAtomic_int32_t; 777 typedef std::atomic<uint32_t> _OSAtomic_uint32_t; 778 typedef std::atomic<int64_t> _OSAtomic_int64_t; 779 typedef std::atomic<void*> _OSAtomic_void_ptr_t; 780 #define OSATOMIC_STD(_a) std::_a 781 __BEGIN_DECLS 782 #else 783 #if !(__has_include(<stdatomic.h>) && __has_extension(c_atomic)) 784 #error Cannot use inlined OSAtomic without <stdatomic.h> and C11 atomics 785 #endif 786 #include <stdatomic.h> 787 typedef _Atomic(uint8_t) _OSAtomic_uint8_t; 788 typedef _Atomic(int32_t) _OSAtomic_int32_t; 789 typedef _Atomic(uint32_t) _OSAtomic_uint32_t; 790 typedef _Atomic(int64_t) _OSAtomic_int64_t; 791 typedef _Atomic(void*) _OSAtomic_void_ptr_t; 792 #define OSATOMIC_STD(_a) _a 793 #endif 794 795 #if __has_extension(c_alignof) && __has_attribute(aligned) 796 typedef int64_t __attribute__((__aligned__(_Alignof(_OSAtomic_int64_t)))) 797 OSAtomic_int64_aligned64_t; 798 #elif __has_attribute(aligned) 799 typedef int64_t __attribute__((__aligned__((sizeof(_OSAtomic_int64_t))))) 800 OSAtomic_int64_aligned64_t; 801 #else 802 typedef int64_t OSAtomic_int64_aligned64_t; 803 #endif 804 805 #if __has_attribute(always_inline) 806 #define OSATOMIC_INLINE static __inline __attribute__((__always_inline__)) 807 #else 808 #define OSATOMIC_INLINE static __inline 809 #endif 810 811 OSATOMIC_INLINE 812 int32_t 813 OSAtomicAdd32(int32_t __theAmount, volatile int32_t *__theValue) 814 { 815 return (OSATOMIC_STD(atomic_fetch_add_explicit)( 816 (volatile _OSAtomic_int32_t*) __theValue, __theAmount, 817 OSATOMIC_STD(memory_order_relaxed)) + __theAmount); 818 } 819 820 OSATOMIC_INLINE 821 int32_t 822 OSAtomicAdd32Barrier(int32_t __theAmount, volatile int32_t *__theValue) 823 { 824 return (OSATOMIC_STD(atomic_fetch_add_explicit)( 825 (volatile _OSAtomic_int32_t*) __theValue, __theAmount, 826 OSATOMIC_STD(memory_order_seq_cst)) + __theAmount); 827 } 828 829 OSATOMIC_INLINE 830 int32_t 831 OSAtomicIncrement32(volatile int32_t *__theValue) 832 { 833 return OSAtomicAdd32(1, __theValue); 834 } 835 836 OSATOMIC_INLINE 837 int32_t 838 OSAtomicIncrement32Barrier(volatile int32_t *__theValue) 839 { 840 return OSAtomicAdd32Barrier(1, __theValue); 841 } 842 843 OSATOMIC_INLINE 844 int32_t 845 OSAtomicDecrement32(volatile int32_t *__theValue) 846 { 847 return OSAtomicAdd32(-1, __theValue); 848 } 849 850 OSATOMIC_INLINE 851 int32_t 852 OSAtomicDecrement32Barrier(volatile int32_t *__theValue) 853 { 854 return OSAtomicAdd32Barrier(-1, __theValue); 855 } 856 857 OSATOMIC_INLINE 858 int64_t 859 OSAtomicAdd64(int64_t __theAmount, 860 volatile OSAtomic_int64_aligned64_t *__theValue) 861 { 862 return (OSATOMIC_STD(atomic_fetch_add_explicit)( 863 (volatile _OSAtomic_int64_t*) __theValue, __theAmount, 864 OSATOMIC_STD(memory_order_relaxed)) + __theAmount); 865 } 866 867 OSATOMIC_INLINE 868 int64_t 869 OSAtomicAdd64Barrier(int64_t __theAmount, 870 volatile OSAtomic_int64_aligned64_t *__theValue) 871 { 872 return (OSATOMIC_STD(atomic_fetch_add_explicit)( 873 (volatile _OSAtomic_int64_t*) __theValue, __theAmount, 874 OSATOMIC_STD(memory_order_seq_cst)) + __theAmount); 875 } 876 877 OSATOMIC_INLINE 878 int64_t 879 OSAtomicIncrement64(volatile OSAtomic_int64_aligned64_t *__theValue) 880 { 881 return OSAtomicAdd64(1, __theValue); 882 } 883 884 OSATOMIC_INLINE 885 int64_t 886 OSAtomicIncrement64Barrier(volatile OSAtomic_int64_aligned64_t *__theValue) 887 { 888 return OSAtomicAdd64Barrier(1, __theValue); 889 } 890 891 OSATOMIC_INLINE 892 int64_t 893 OSAtomicDecrement64(volatile OSAtomic_int64_aligned64_t *__theValue) 894 { 895 return OSAtomicAdd64(-1, __theValue); 896 } 897 898 OSATOMIC_INLINE 899 int64_t 900 OSAtomicDecrement64Barrier(volatile OSAtomic_int64_aligned64_t *__theValue) 901 { 902 return OSAtomicAdd64Barrier(-1, __theValue); 903 } 904 905 OSATOMIC_INLINE 906 int32_t 907 OSAtomicOr32(uint32_t __theMask, volatile uint32_t *__theValue) 908 { 909 return (int32_t)(OSATOMIC_STD(atomic_fetch_or_explicit)( 910 (volatile _OSAtomic_uint32_t*)__theValue, __theMask, 911 OSATOMIC_STD(memory_order_relaxed)) | __theMask); 912 } 913 914 OSATOMIC_INLINE 915 int32_t 916 OSAtomicOr32Barrier(uint32_t __theMask, volatile uint32_t *__theValue) 917 { 918 return (int32_t)(OSATOMIC_STD(atomic_fetch_or_explicit)( 919 (volatile _OSAtomic_uint32_t*)__theValue, __theMask, 920 OSATOMIC_STD(memory_order_seq_cst)) | __theMask); 921 } 922 923 OSATOMIC_INLINE 924 int32_t 925 OSAtomicOr32Orig(uint32_t __theMask, volatile uint32_t *__theValue) 926 { 927 return (int32_t)(OSATOMIC_STD(atomic_fetch_or_explicit)( 928 (volatile _OSAtomic_uint32_t*)__theValue, __theMask, 929 OSATOMIC_STD(memory_order_relaxed))); 930 } 931 932 OSATOMIC_INLINE 933 int32_t 934 OSAtomicOr32OrigBarrier(uint32_t __theMask, volatile uint32_t *__theValue) 935 { 936 return (int32_t)(OSATOMIC_STD(atomic_fetch_or_explicit)( 937 (volatile _OSAtomic_uint32_t*)__theValue, __theMask, 938 OSATOMIC_STD(memory_order_seq_cst))); 939 } 940 941 OSATOMIC_INLINE 942 int32_t 943 OSAtomicAnd32(uint32_t __theMask, volatile uint32_t *__theValue) 944 { 945 return (int32_t)(OSATOMIC_STD(atomic_fetch_and_explicit)( 946 (volatile _OSAtomic_uint32_t*)__theValue, __theMask, 947 OSATOMIC_STD(memory_order_relaxed)) & __theMask); 948 } 949 950 OSATOMIC_INLINE 951 int32_t 952 OSAtomicAnd32Barrier(uint32_t __theMask, volatile uint32_t *__theValue) 953 { 954 return (int32_t)(OSATOMIC_STD(atomic_fetch_and_explicit)( 955 (volatile _OSAtomic_uint32_t*)__theValue, __theMask, 956 OSATOMIC_STD(memory_order_seq_cst)) & __theMask); 957 } 958 959 OSATOMIC_INLINE 960 int32_t 961 OSAtomicAnd32Orig(uint32_t __theMask, volatile uint32_t *__theValue) 962 { 963 return (int32_t)(OSATOMIC_STD(atomic_fetch_and_explicit)( 964 (volatile _OSAtomic_uint32_t*)__theValue, __theMask, 965 OSATOMIC_STD(memory_order_relaxed))); 966 } 967 968 OSATOMIC_INLINE 969 int32_t 970 OSAtomicAnd32OrigBarrier(uint32_t __theMask, volatile uint32_t *__theValue) 971 { 972 return (int32_t)(OSATOMIC_STD(atomic_fetch_and_explicit)( 973 (volatile _OSAtomic_uint32_t*)__theValue, __theMask, 974 OSATOMIC_STD(memory_order_seq_cst))); 975 } 976 977 OSATOMIC_INLINE 978 int32_t 979 OSAtomicXor32(uint32_t __theMask, volatile uint32_t *__theValue) 980 { 981 return (int32_t)(OSATOMIC_STD(atomic_fetch_xor_explicit)( 982 (volatile _OSAtomic_uint32_t*)__theValue, __theMask, 983 OSATOMIC_STD(memory_order_relaxed)) ^ __theMask); 984 } 985 986 OSATOMIC_INLINE 987 int32_t 988 OSAtomicXor32Barrier(uint32_t __theMask, volatile uint32_t *__theValue) 989 { 990 return (int32_t)(OSATOMIC_STD(atomic_fetch_xor_explicit)( 991 (volatile _OSAtomic_uint32_t*)__theValue, __theMask, 992 OSATOMIC_STD(memory_order_seq_cst)) ^ __theMask); 993 } 994 995 OSATOMIC_INLINE 996 int32_t 997 OSAtomicXor32Orig(uint32_t __theMask, volatile uint32_t *__theValue) 998 { 999 return (int32_t)(OSATOMIC_STD(atomic_fetch_xor_explicit)( 1000 (volatile _OSAtomic_uint32_t*)__theValue, __theMask, 1001 OSATOMIC_STD(memory_order_relaxed))); 1002 } 1003 1004 OSATOMIC_INLINE 1005 int32_t 1006 OSAtomicXor32OrigBarrier(uint32_t __theMask, volatile uint32_t *__theValue) 1007 { 1008 return (int32_t)(OSATOMIC_STD(atomic_fetch_xor_explicit)( 1009 (volatile _OSAtomic_uint32_t*)__theValue, __theMask, 1010 OSATOMIC_STD(memory_order_seq_cst))); 1011 } 1012 1013 OSATOMIC_INLINE 1014 bool 1015 OSAtomicCompareAndSwap32(int32_t __oldValue, int32_t __newValue, 1016 volatile int32_t *__theValue) 1017 { 1018 return (OSATOMIC_STD(atomic_compare_exchange_strong_explicit)( 1019 (volatile _OSAtomic_int32_t*)__theValue, &__oldValue, __newValue, 1020 OSATOMIC_STD(memory_order_relaxed), 1021 OSATOMIC_STD(memory_order_relaxed))); 1022 } 1023 1024 OSATOMIC_INLINE 1025 bool 1026 OSAtomicCompareAndSwap32Barrier(int32_t __oldValue, int32_t __newValue, 1027 volatile int32_t *__theValue) 1028 { 1029 return (OSATOMIC_STD(atomic_compare_exchange_strong_explicit)( 1030 (volatile _OSAtomic_int32_t*)__theValue, &__oldValue, __newValue, 1031 OSATOMIC_STD(memory_order_seq_cst), 1032 OSATOMIC_STD(memory_order_relaxed))); 1033 } 1034 1035 OSATOMIC_INLINE 1036 bool 1037 OSAtomicCompareAndSwapPtr(void *__oldValue, void *__newValue, 1038 void * volatile *__theValue) 1039 { 1040 return (OSATOMIC_STD(atomic_compare_exchange_strong_explicit)( 1041 (volatile _OSAtomic_void_ptr_t*)__theValue, &__oldValue, __newValue, 1042 OSATOMIC_STD(memory_order_relaxed), 1043 OSATOMIC_STD(memory_order_relaxed))); 1044 } 1045 1046 OSATOMIC_INLINE 1047 bool 1048 OSAtomicCompareAndSwapPtrBarrier(void *__oldValue, void *__newValue, 1049 void * volatile *__theValue) 1050 { 1051 return (OSATOMIC_STD(atomic_compare_exchange_strong_explicit)( 1052 (volatile _OSAtomic_void_ptr_t*)__theValue, &__oldValue, __newValue, 1053 OSATOMIC_STD(memory_order_seq_cst), 1054 OSATOMIC_STD(memory_order_relaxed))); 1055 } 1056 1057 OSATOMIC_INLINE 1058 bool 1059 OSAtomicCompareAndSwapInt(int __oldValue, int __newValue, 1060 volatile int *__theValue) 1061 { 1062 return (OSATOMIC_STD(atomic_compare_exchange_strong_explicit)( 1063 (volatile OSATOMIC_STD(atomic_int)*)__theValue, &__oldValue, 1064 __newValue, OSATOMIC_STD(memory_order_relaxed), 1065 OSATOMIC_STD(memory_order_relaxed))); 1066 } 1067 1068 OSATOMIC_INLINE 1069 bool 1070 OSAtomicCompareAndSwapIntBarrier(int __oldValue, int __newValue, 1071 volatile int *__theValue) 1072 { 1073 return (OSATOMIC_STD(atomic_compare_exchange_strong_explicit)( 1074 (volatile OSATOMIC_STD(atomic_int)*)__theValue, &__oldValue, 1075 __newValue, OSATOMIC_STD(memory_order_seq_cst), 1076 OSATOMIC_STD(memory_order_relaxed))); 1077 } 1078 1079 OSATOMIC_INLINE 1080 bool 1081 OSAtomicCompareAndSwapLong(long __oldValue, long __newValue, 1082 volatile long *__theValue) 1083 { 1084 return (OSATOMIC_STD(atomic_compare_exchange_strong_explicit)( 1085 (volatile OSATOMIC_STD(atomic_long)*)__theValue, &__oldValue, 1086 __newValue, OSATOMIC_STD(memory_order_relaxed), 1087 OSATOMIC_STD(memory_order_relaxed))); 1088 } 1089 1090 OSATOMIC_INLINE 1091 bool 1092 OSAtomicCompareAndSwapLongBarrier(long __oldValue, long __newValue, 1093 volatile long *__theValue) 1094 { 1095 return (OSATOMIC_STD(atomic_compare_exchange_strong_explicit)( 1096 (volatile OSATOMIC_STD(atomic_long)*)__theValue, &__oldValue, 1097 __newValue, OSATOMIC_STD(memory_order_seq_cst), 1098 OSATOMIC_STD(memory_order_relaxed))); 1099 } 1100 1101 OSATOMIC_INLINE 1102 bool 1103 OSAtomicCompareAndSwap64(int64_t __oldValue, int64_t __newValue, 1104 volatile OSAtomic_int64_aligned64_t *__theValue) 1105 { 1106 return (OSATOMIC_STD(atomic_compare_exchange_strong_explicit)( 1107 (volatile _OSAtomic_int64_t*)__theValue, &__oldValue, __newValue, 1108 OSATOMIC_STD(memory_order_relaxed), 1109 OSATOMIC_STD(memory_order_relaxed))); 1110 } 1111 1112 OSATOMIC_INLINE 1113 bool 1114 OSAtomicCompareAndSwap64Barrier(int64_t __oldValue, int64_t __newValue, 1115 volatile OSAtomic_int64_aligned64_t *__theValue) 1116 { 1117 return (OSATOMIC_STD(atomic_compare_exchange_strong_explicit)( 1118 (volatile _OSAtomic_int64_t*)__theValue, &__oldValue, __newValue, 1119 OSATOMIC_STD(memory_order_seq_cst), 1120 OSATOMIC_STD(memory_order_relaxed))); 1121 } 1122 1123 OSATOMIC_INLINE 1124 bool 1125 OSAtomicTestAndSet(uint32_t __n, volatile void *__theAddress) 1126 { 1127 uintptr_t a = (uintptr_t)__theAddress + (__n >> 3); 1128 uint8_t v = (0x80u >> (__n & 7)); 1129 return (OSATOMIC_STD(atomic_fetch_or_explicit)((_OSAtomic_uint8_t*)a, v, 1130 OSATOMIC_STD(memory_order_relaxed)) & v); 1131 } 1132 1133 OSATOMIC_INLINE 1134 bool 1135 OSAtomicTestAndSetBarrier(uint32_t __n, volatile void *__theAddress) 1136 { 1137 uintptr_t a = (uintptr_t)__theAddress + (__n >> 3); 1138 uint8_t v = (0x80u >> (__n & 7)); 1139 return (OSATOMIC_STD(atomic_fetch_or_explicit)((_OSAtomic_uint8_t*)a, v, 1140 OSATOMIC_STD(memory_order_seq_cst)) & v); 1141 } 1142 1143 OSATOMIC_INLINE 1144 bool 1145 OSAtomicTestAndClear(uint32_t __n, volatile void *__theAddress) 1146 { 1147 uintptr_t a = (uintptr_t)__theAddress + (__n >> 3); 1148 uint8_t v = (0x80u >> (__n & 7)); 1149 return (OSATOMIC_STD(atomic_fetch_and_explicit)((_OSAtomic_uint8_t*)a, 1150 (uint8_t)~v, OSATOMIC_STD(memory_order_relaxed)) & v); 1151 } 1152 1153 OSATOMIC_INLINE 1154 bool 1155 OSAtomicTestAndClearBarrier(uint32_t __n, volatile void *__theAddress) 1156 { 1157 uintptr_t a = (uintptr_t)__theAddress + (__n >> 3); 1158 uint8_t v = (0x80u >> (__n & 7)); 1159 return (OSATOMIC_STD(atomic_fetch_and_explicit)((_OSAtomic_uint8_t*)a, 1160 (uint8_t)~v, OSATOMIC_STD(memory_order_seq_cst)) & v); 1161 } 1162 1163 OSATOMIC_INLINE 1164 void 1165 OSMemoryBarrier(void) 1166 { 1167 OSATOMIC_STD(atomic_thread_fence)(OSATOMIC_STD(memory_order_seq_cst)); 1168 } 1169 1170 #undef OSATOMIC_INLINE 1171 #undef OSATOMIC_STD 1172 #ifdef __cplusplus 1173 __END_DECLS 1174 } // extern "C++" 1175 #endif 1176 1177 #endif // defined(OSATOMIC_USE_INLINED) && OSATOMIC_USE_INLINED 1178 1179 #if TARGET_OS_OSX || TARGET_OS_DRIVERKIT 1180 1181 __BEGIN_DECLS 1182 1183 /*! @group Lockless atomic fifo enqueue and dequeue 1184 * These routines manipulate singly-linked FIFO lists. 1185 * 1186 * This API is deprecated and no longer recommended 1187 */ 1188 1189 /*! @abstract The data structure for a fifo queue head. 1190 @discussion 1191 You should always initialize a fifo queue head structure with the 1192 initialization vector {@link OS_ATOMIC_FIFO_QUEUE_INIT} before use. 1193 */ 1194 #if defined(__LP64__) 1195 1196 typedef volatile struct { 1197 void *opaque1; 1198 void *opaque2; 1199 int opaque3; 1200 } __attribute__ ((aligned (16))) OSFifoQueueHead; 1201 1202 #else 1203 1204 typedef volatile struct { 1205 void *opaque1; 1206 void *opaque2; 1207 int opaque3; 1208 } OSFifoQueueHead; 1209 1210 #endif 1211 /*! @abstract The initialization vector for a fifo queue head. */ 1212 #define OS_ATOMIC_FIFO_QUEUE_INIT { NULL, NULL, 0 } 1213 1214 /*! @abstract Enqueue an element onto a list. 1215 @discussion 1216 Memory barriers are incorporated as needed to permit thread-safe access 1217 to the queue element. 1218 @param __list 1219 The list on which you want to enqueue the element. 1220 @param __new 1221 The element to add. 1222 @param __offset 1223 The "offset" parameter is the offset (in bytes) of the link field 1224 from the beginning of the data structure being queued (<code>__new</code>). 1225 The link field should be a pointer type. 1226 The <code>__offset</code> value needs to be same for all enqueuing and 1227 dequeuing operations on the same list, even if different structure types 1228 are enqueued on that list. The use of <code>offsetset()</code>, defined in 1229 <code>stddef.h</code> is the common way to specify the <code>__offset</code> 1230 value. 1231 1232 @note 1233 This API is deprecated and no longer recommended 1234 */ 1235 __API_DEPRECATED("No longer supported", macos(10.7, 11.0)) 1236 void OSAtomicFifoEnqueue( OSFifoQueueHead *__list, void *__new, size_t __offset); 1237 1238 /*! @abstract Dequeue an element from a list. 1239 @discussion 1240 Memory barriers are incorporated as needed to permit thread-safe access 1241 to the queue element. 1242 @param __list 1243 The list from which you want to dequeue an element. 1244 @param __offset 1245 The "offset" parameter is the offset (in bytes) of the link field 1246 from the beginning of the data structure being dequeued (<code>__new</code>). 1247 The link field should be a pointer type. 1248 The <code>__offset</code> value needs to be same for all enqueuing and 1249 dequeuing operations on the same list, even if different structure types 1250 are enqueued on that list. The use of <code>offsetset()</code>, defined in 1251 <code>stddef.h</code> is the common way to specify the <code>__offset</code> 1252 value. 1253 @result 1254 Returns the oldest enqueued element, or <code>NULL</code> if the 1255 list is empty. 1256 1257 @note 1258 This API is deprecated and no longer recommended 1259 */ 1260 __API_DEPRECATED("No longer supported", macos(10.7, 11.0)) 1261 void* OSAtomicFifoDequeue( OSFifoQueueHead *__list, size_t __offset); 1262 1263 __END_DECLS 1264 1265 #endif /* TARGET_OS_OSX || TARGET_OS_DRIVERKIT */ 1266 1267 #endif /* _OSATOMIC_DEPRECATED_H_ */