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