master
   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)
 129typedef int64_t __attribute__((__aligned__((sizeof(int64_t)))))
 130		OSAtomic_int64_aligned64_t;
 131#else
 132typedef 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 */
 146OSATOMIC_DEPRECATED_REPLACE_WITH(atomic_fetch_add)
 147__OSX_AVAILABLE_STARTING(__MAC_10_4, __IPHONE_2_0)
 148int32_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 */
 161OSATOMIC_BARRIER_DEPRECATED_REPLACE_WITH(atomic_fetch_add)
 162__OSX_AVAILABLE_STARTING(__MAC_10_4, __IPHONE_2_0)
 163int32_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 */
 171OSATOMIC_DEPRECATED_REPLACE_WITH(atomic_fetch_add)
 172__OSX_AVAILABLE_STARTING(__MAC_10_10, __IPHONE_7_1)
 173int32_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 */
 182OSATOMIC_BARRIER_DEPRECATED_REPLACE_WITH(atomic_fetch_add)
 183__OSX_AVAILABLE_STARTING(__MAC_10_10, __IPHONE_7_1)
 184int32_t	OSAtomicIncrement32Barrier( volatile int32_t *__theValue );
 185
 186
 187/*! @abstract Atomically decrements a 32-bit value.
 188    @result Returns the new value.
 189 */
 190OSATOMIC_DEPRECATED_REPLACE_WITH(atomic_fetch_sub)
 191__OSX_AVAILABLE_STARTING(__MAC_10_10, __IPHONE_7_1)
 192int32_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 */
 201OSATOMIC_BARRIER_DEPRECATED_REPLACE_WITH(atomic_fetch_sub)
 202__OSX_AVAILABLE_STARTING(__MAC_10_10, __IPHONE_7_1)
 203int32_t	OSAtomicDecrement32Barrier( volatile int32_t *__theValue );
 204
 205#else
 206__inline static
 207int32_t	OSAtomicIncrement32( volatile int32_t *__theValue )
 208            { return OSAtomicAdd32(  1, __theValue); }
 209
 210__inline static
 211int32_t	OSAtomicIncrement32Barrier( volatile int32_t *__theValue )
 212            { return OSAtomicAdd32Barrier(  1, __theValue); }
 213
 214__inline static
 215int32_t	OSAtomicDecrement32( volatile int32_t *__theValue )
 216            { return OSAtomicAdd32( -1, __theValue); }
 217
 218__inline static
 219int32_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 */
 231OSATOMIC_DEPRECATED_REPLACE_WITH(atomic_fetch_add)
 232__OSX_AVAILABLE_STARTING(__MAC_10_4, __IPHONE_2_0)
 233int64_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 */
 247OSATOMIC_BARRIER_DEPRECATED_REPLACE_WITH(atomic_fetch_add)
 248__OSX_AVAILABLE_STARTING(__MAC_10_4, __IPHONE_3_2)
 249int64_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 */
 258OSATOMIC_DEPRECATED_REPLACE_WITH(atomic_fetch_add)
 259__OSX_AVAILABLE_STARTING(__MAC_10_10, __IPHONE_7_1)
 260int64_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 */
 269OSATOMIC_BARRIER_DEPRECATED_REPLACE_WITH(atomic_fetch_add)
 270__OSX_AVAILABLE_STARTING(__MAC_10_10, __IPHONE_7_1)
 271int64_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 */
 277OSATOMIC_DEPRECATED_REPLACE_WITH(atomic_fetch_sub)
 278__OSX_AVAILABLE_STARTING(__MAC_10_10, __IPHONE_7_1)
 279int64_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 */
 288OSATOMIC_BARRIER_DEPRECATED_REPLACE_WITH(atomic_fetch_sub)
 289__OSX_AVAILABLE_STARTING(__MAC_10_10, __IPHONE_7_1)
 290int64_t	OSAtomicDecrement64Barrier( volatile OSAtomic_int64_aligned64_t *__theValue );
 291
 292#else
 293__inline static
 294int64_t	OSAtomicIncrement64( volatile OSAtomic_int64_aligned64_t *__theValue )
 295            { return OSAtomicAdd64(  1, __theValue); }
 296
 297__inline static
 298int64_t	OSAtomicIncrement64Barrier( volatile OSAtomic_int64_aligned64_t *__theValue )
 299            { return OSAtomicAdd64Barrier(  1, __theValue); }
 300
 301__inline static
 302int64_t	OSAtomicDecrement64( volatile OSAtomic_int64_aligned64_t *__theValue )
 303            { return OSAtomicAdd64( -1, __theValue); }
 304
 305__inline static
 306int64_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 */
 329OSATOMIC_DEPRECATED_REPLACE_WITH(atomic_fetch_or)
 330__OSX_AVAILABLE_STARTING(__MAC_10_4, __IPHONE_2_0)
 331int32_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 */
 344OSATOMIC_BARRIER_DEPRECATED_REPLACE_WITH(atomic_fetch_or)
 345__OSX_AVAILABLE_STARTING(__MAC_10_4, __IPHONE_2_0)
 346int32_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 */
 356OSATOMIC_DEPRECATED_REPLACE_WITH(atomic_fetch_or)
 357__OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_3_2)
 358int32_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 */
 371OSATOMIC_BARRIER_DEPRECATED_REPLACE_WITH(atomic_fetch_or)
 372__OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_3_2)
 373int32_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 */
 385OSATOMIC_DEPRECATED_REPLACE_WITH(atomic_fetch_and)
 386__OSX_AVAILABLE_STARTING(__MAC_10_4, __IPHONE_2_0)
 387int32_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 */
 400OSATOMIC_BARRIER_DEPRECATED_REPLACE_WITH(atomic_fetch_and)
 401__OSX_AVAILABLE_STARTING(__MAC_10_4, __IPHONE_2_0)
 402int32_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 */
 412OSATOMIC_DEPRECATED_REPLACE_WITH(atomic_fetch_and)
 413__OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_3_2)
 414int32_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 */
 427OSATOMIC_BARRIER_DEPRECATED_REPLACE_WITH(atomic_fetch_and)
 428__OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_3_2)
 429int32_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 */
 441OSATOMIC_DEPRECATED_REPLACE_WITH(atomic_fetch_xor)
 442__OSX_AVAILABLE_STARTING(__MAC_10_4, __IPHONE_2_0)
 443int32_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 */
 456OSATOMIC_BARRIER_DEPRECATED_REPLACE_WITH(atomic_fetch_xor)
 457__OSX_AVAILABLE_STARTING(__MAC_10_4, __IPHONE_2_0)
 458int32_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 */
 468OSATOMIC_DEPRECATED_REPLACE_WITH(atomic_fetch_xor)
 469__OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_3_2)
 470int32_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 */
 483OSATOMIC_BARRIER_DEPRECATED_REPLACE_WITH(atomic_fetch_xor)
 484__OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_3_2)
 485int32_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 */
 502OSATOMIC_DEPRECATED_REPLACE_WITH(atomic_compare_exchange_strong)
 503__OSX_AVAILABLE_STARTING(__MAC_10_4, __IPHONE_2_0)
 504bool    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 */
 518OSATOMIC_BARRIER_DEPRECATED_REPLACE_WITH(atomic_compare_exchange_strong)
 519__OSX_AVAILABLE_STARTING(__MAC_10_4, __IPHONE_2_0)
 520bool    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 */
 531OSATOMIC_DEPRECATED_REPLACE_WITH(atomic_compare_exchange_strong)
 532__OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0)
 533bool	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 */
 547OSATOMIC_BARRIER_DEPRECATED_REPLACE_WITH(atomic_compare_exchange_strong)
 548__OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0)
 549bool	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 */
 562OSATOMIC_DEPRECATED_REPLACE_WITH(atomic_compare_exchange_strong)
 563__OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0)
 564bool	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 */
 580OSATOMIC_BARRIER_DEPRECATED_REPLACE_WITH(atomic_compare_exchange_strong)
 581__OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0)
 582bool	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 */
 596OSATOMIC_DEPRECATED_REPLACE_WITH(atomic_compare_exchange_strong)
 597__OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0)
 598bool	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 */
 615OSATOMIC_BARRIER_DEPRECATED_REPLACE_WITH(atomic_compare_exchange_strong)
 616__OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0)
 617bool	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 */
 628OSATOMIC_DEPRECATED_REPLACE_WITH(atomic_compare_exchange_strong)
 629__OSX_AVAILABLE_STARTING(__MAC_10_4, __IPHONE_2_0)
 630bool    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 */
 645OSATOMIC_BARRIER_DEPRECATED_REPLACE_WITH(atomic_compare_exchange_strong)
 646__OSX_AVAILABLE_STARTING(__MAC_10_4, __IPHONE_3_2)
 647bool    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 */
 670OSATOMIC_DEPRECATED_REPLACE_WITH(atomic_fetch_or)
 671__OSX_AVAILABLE_STARTING(__MAC_10_4, __IPHONE_2_0)
 672bool    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 */
 693OSATOMIC_BARRIER_DEPRECATED_REPLACE_WITH(atomic_fetch_or)
 694__OSX_AVAILABLE_STARTING(__MAC_10_4, __IPHONE_2_0)
 695bool    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 */
 715OSATOMIC_DEPRECATED_REPLACE_WITH(atomic_fetch_and)
 716__OSX_AVAILABLE_STARTING(__MAC_10_4, __IPHONE_2_0)
 717bool    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 */
 738OSATOMIC_BARRIER_DEPRECATED_REPLACE_WITH(atomic_fetch_and)
 739__OSX_AVAILABLE_STARTING(__MAC_10_4, __IPHONE_2_0)
 740bool    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 */
 749OSATOMIC_BARRIER_DEPRECATED_REPLACE_WITH(atomic_thread_fence)
 750__OSX_AVAILABLE_STARTING(__MAC_10_4, __IPHONE_2_0)
 751void    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
 770extern "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>
 775typedef std::atomic<uint8_t> _OSAtomic_uint8_t;
 776typedef std::atomic<int32_t> _OSAtomic_int32_t;
 777typedef std::atomic<uint32_t> _OSAtomic_uint32_t;
 778typedef std::atomic<int64_t> _OSAtomic_int64_t;
 779typedef 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>
 787typedef _Atomic(uint8_t) _OSAtomic_uint8_t;
 788typedef _Atomic(int32_t) _OSAtomic_int32_t;
 789typedef _Atomic(uint32_t) _OSAtomic_uint32_t;
 790typedef _Atomic(int64_t) _OSAtomic_int64_t;
 791typedef _Atomic(void*) _OSAtomic_void_ptr_t;
 792#define OSATOMIC_STD(_a) _a
 793#endif
 794
 795#if __has_extension(c_alignof) && __has_attribute(aligned)
 796typedef int64_t __attribute__((__aligned__(_Alignof(_OSAtomic_int64_t))))
 797		OSAtomic_int64_aligned64_t;
 798#elif __has_attribute(aligned)
 799typedef int64_t __attribute__((__aligned__((sizeof(_OSAtomic_int64_t)))))
 800		OSAtomic_int64_aligned64_t;
 801#else
 802typedef 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
 811OSATOMIC_INLINE
 812int32_t
 813OSAtomicAdd32(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
 820OSATOMIC_INLINE
 821int32_t
 822OSAtomicAdd32Barrier(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
 829OSATOMIC_INLINE
 830int32_t
 831OSAtomicIncrement32(volatile int32_t *__theValue)
 832{
 833	return OSAtomicAdd32(1, __theValue);
 834}
 835
 836OSATOMIC_INLINE
 837int32_t
 838OSAtomicIncrement32Barrier(volatile int32_t *__theValue)
 839{
 840	return OSAtomicAdd32Barrier(1, __theValue);
 841}
 842
 843OSATOMIC_INLINE
 844int32_t
 845OSAtomicDecrement32(volatile int32_t *__theValue)
 846{
 847	return OSAtomicAdd32(-1, __theValue);
 848}
 849
 850OSATOMIC_INLINE
 851int32_t
 852OSAtomicDecrement32Barrier(volatile int32_t *__theValue)
 853{
 854	return OSAtomicAdd32Barrier(-1, __theValue);
 855}
 856
 857OSATOMIC_INLINE
 858int64_t
 859OSAtomicAdd64(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
 867OSATOMIC_INLINE
 868int64_t
 869OSAtomicAdd64Barrier(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
 877OSATOMIC_INLINE
 878int64_t
 879OSAtomicIncrement64(volatile OSAtomic_int64_aligned64_t *__theValue)
 880{
 881	return OSAtomicAdd64(1, __theValue);
 882}
 883
 884OSATOMIC_INLINE
 885int64_t
 886OSAtomicIncrement64Barrier(volatile OSAtomic_int64_aligned64_t *__theValue)
 887{
 888	return OSAtomicAdd64Barrier(1, __theValue);
 889}
 890
 891OSATOMIC_INLINE
 892int64_t
 893OSAtomicDecrement64(volatile OSAtomic_int64_aligned64_t *__theValue)
 894{
 895	return OSAtomicAdd64(-1, __theValue);
 896}
 897
 898OSATOMIC_INLINE
 899int64_t
 900OSAtomicDecrement64Barrier(volatile OSAtomic_int64_aligned64_t *__theValue)
 901{
 902	return OSAtomicAdd64Barrier(-1, __theValue);
 903}
 904
 905OSATOMIC_INLINE
 906int32_t
 907OSAtomicOr32(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
 914OSATOMIC_INLINE
 915int32_t
 916OSAtomicOr32Barrier(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
 923OSATOMIC_INLINE
 924int32_t
 925OSAtomicOr32Orig(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
 932OSATOMIC_INLINE
 933int32_t
 934OSAtomicOr32OrigBarrier(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
 941OSATOMIC_INLINE
 942int32_t
 943OSAtomicAnd32(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
 950OSATOMIC_INLINE
 951int32_t
 952OSAtomicAnd32Barrier(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
 959OSATOMIC_INLINE
 960int32_t
 961OSAtomicAnd32Orig(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
 968OSATOMIC_INLINE
 969int32_t
 970OSAtomicAnd32OrigBarrier(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
 977OSATOMIC_INLINE
 978int32_t
 979OSAtomicXor32(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
 986OSATOMIC_INLINE
 987int32_t
 988OSAtomicXor32Barrier(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
 995OSATOMIC_INLINE
 996int32_t
 997OSAtomicXor32Orig(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
1004OSATOMIC_INLINE
1005int32_t
1006OSAtomicXor32OrigBarrier(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
1013OSATOMIC_INLINE
1014bool
1015OSAtomicCompareAndSwap32(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
1024OSATOMIC_INLINE
1025bool
1026OSAtomicCompareAndSwap32Barrier(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
1035OSATOMIC_INLINE
1036bool
1037OSAtomicCompareAndSwapPtr(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
1046OSATOMIC_INLINE
1047bool
1048OSAtomicCompareAndSwapPtrBarrier(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
1057OSATOMIC_INLINE
1058bool
1059OSAtomicCompareAndSwapInt(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
1068OSATOMIC_INLINE
1069bool
1070OSAtomicCompareAndSwapIntBarrier(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
1079OSATOMIC_INLINE
1080bool
1081OSAtomicCompareAndSwapLong(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
1090OSATOMIC_INLINE
1091bool
1092OSAtomicCompareAndSwapLongBarrier(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
1101OSATOMIC_INLINE
1102bool
1103OSAtomicCompareAndSwap64(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
1112OSATOMIC_INLINE
1113bool
1114OSAtomicCompareAndSwap64Barrier(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
1123OSATOMIC_INLINE
1124bool
1125OSAtomicTestAndSet(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
1133OSATOMIC_INLINE
1134bool
1135OSAtomicTestAndSetBarrier(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
1143OSATOMIC_INLINE
1144bool
1145OSAtomicTestAndClear(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
1153OSATOMIC_INLINE
1154bool
1155OSAtomicTestAndClearBarrier(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
1163OSATOMIC_INLINE
1164void
1165OSMemoryBarrier(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
1196typedef	volatile struct {
1197	void	*opaque1;
1198	void	*opaque2;
1199	int	 opaque3;
1200} __attribute__ ((aligned (16))) OSFifoQueueHead;
1201
1202#else
1203
1204typedef	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))
1236void  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))
1261void* 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_ */