]> git.saurik.com Git - apple/libplatform.git/blame - include/libkern/OSAtomicDeprecated.h
libplatform-254.40.4.tar.gz
[apple/libplatform.git] / include / libkern / OSAtomicDeprecated.h
CommitLineData
ada7c492
A
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
442fbc9d
A
38#include <Availability.h>
39
ada7c492
A
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>
ada7c492
A
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)
128typedef int64_t __attribute__((__aligned__((sizeof(int64_t)))))
129 OSAtomic_int64_aligned64_t;
130#else
131typedef 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 */
145OSATOMIC_DEPRECATED_REPLACE_WITH(atomic_fetch_add)
146__OSX_AVAILABLE_STARTING(__MAC_10_4, __IPHONE_2_0)
147int32_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 */
160OSATOMIC_BARRIER_DEPRECATED_REPLACE_WITH(atomic_fetch_add)
161__OSX_AVAILABLE_STARTING(__MAC_10_4, __IPHONE_2_0)
162int32_t OSAtomicAdd32Barrier( int32_t __theAmount, volatile int32_t *__theValue );
163
164
442fbc9d 165#if __MAC_OS_X_VERSION_MIN_REQUIRED >= __MAC_10_10 || __IPHONE_OS_VERSION_MIN_REQUIRED >= __IPHONE_7_1 || TARGET_OS_DRIVERKIT
ada7c492
A
166
167/*! @abstract Atomically increments a 32-bit value.
168 @result Returns the new value.
169 */
170OSATOMIC_DEPRECATED_REPLACE_WITH(atomic_fetch_add)
171__OSX_AVAILABLE_STARTING(__MAC_10_10, __IPHONE_7_1)
172int32_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 */
181OSATOMIC_BARRIER_DEPRECATED_REPLACE_WITH(atomic_fetch_add)
182__OSX_AVAILABLE_STARTING(__MAC_10_10, __IPHONE_7_1)
183int32_t OSAtomicIncrement32Barrier( volatile int32_t *__theValue );
184
185
186/*! @abstract Atomically decrements a 32-bit value.
187 @result Returns the new value.
188 */
189OSATOMIC_DEPRECATED_REPLACE_WITH(atomic_fetch_sub)
190__OSX_AVAILABLE_STARTING(__MAC_10_10, __IPHONE_7_1)
191int32_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 */
200OSATOMIC_BARRIER_DEPRECATED_REPLACE_WITH(atomic_fetch_sub)
201__OSX_AVAILABLE_STARTING(__MAC_10_10, __IPHONE_7_1)
202int32_t OSAtomicDecrement32Barrier( volatile int32_t *__theValue );
203
204#else
205__inline static
206int32_t OSAtomicIncrement32( volatile int32_t *__theValue )
207 { return OSAtomicAdd32( 1, __theValue); }
208
209__inline static
210int32_t OSAtomicIncrement32Barrier( volatile int32_t *__theValue )
211 { return OSAtomicAdd32Barrier( 1, __theValue); }
212
213__inline static
214int32_t OSAtomicDecrement32( volatile int32_t *__theValue )
215 { return OSAtomicAdd32( -1, __theValue); }
216
217__inline static
218int32_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 */
230OSATOMIC_DEPRECATED_REPLACE_WITH(atomic_fetch_add)
231__OSX_AVAILABLE_STARTING(__MAC_10_4, __IPHONE_2_0)
232int64_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 */
246OSATOMIC_BARRIER_DEPRECATED_REPLACE_WITH(atomic_fetch_add)
247__OSX_AVAILABLE_STARTING(__MAC_10_4, __IPHONE_3_2)
248int64_t OSAtomicAdd64Barrier( int64_t __theAmount,
249 volatile OSAtomic_int64_aligned64_t *__theValue );
250
251
442fbc9d 252#if __MAC_OS_X_VERSION_MIN_REQUIRED >= __MAC_10_10 || __IPHONE_OS_VERSION_MIN_REQUIRED >= __IPHONE_7_1 || TARGET_OS_DRIVERKIT
ada7c492
A
253
254/*! @abstract Atomically increments a 64-bit value.
255 @result Returns the new value.
256 */
257OSATOMIC_DEPRECATED_REPLACE_WITH(atomic_fetch_add)
258__OSX_AVAILABLE_STARTING(__MAC_10_10, __IPHONE_7_1)
259int64_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 */
268OSATOMIC_BARRIER_DEPRECATED_REPLACE_WITH(atomic_fetch_add)
269__OSX_AVAILABLE_STARTING(__MAC_10_10, __IPHONE_7_1)
270int64_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 */
276OSATOMIC_DEPRECATED_REPLACE_WITH(atomic_fetch_sub)
277__OSX_AVAILABLE_STARTING(__MAC_10_10, __IPHONE_7_1)
278int64_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 */
287OSATOMIC_BARRIER_DEPRECATED_REPLACE_WITH(atomic_fetch_sub)
288__OSX_AVAILABLE_STARTING(__MAC_10_10, __IPHONE_7_1)
289int64_t OSAtomicDecrement64Barrier( volatile OSAtomic_int64_aligned64_t *__theValue );
290
291#else
292__inline static
293int64_t OSAtomicIncrement64( volatile OSAtomic_int64_aligned64_t *__theValue )
294 { return OSAtomicAdd64( 1, __theValue); }
295
296__inline static
297int64_t OSAtomicIncrement64Barrier( volatile OSAtomic_int64_aligned64_t *__theValue )
298 { return OSAtomicAdd64Barrier( 1, __theValue); }
299
300__inline static
301int64_t OSAtomicDecrement64( volatile OSAtomic_int64_aligned64_t *__theValue )
302 { return OSAtomicAdd64( -1, __theValue); }
303
304__inline static
305int64_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 */
328OSATOMIC_DEPRECATED_REPLACE_WITH(atomic_fetch_or)
329__OSX_AVAILABLE_STARTING(__MAC_10_4, __IPHONE_2_0)
330int32_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 */
343OSATOMIC_BARRIER_DEPRECATED_REPLACE_WITH(atomic_fetch_or)
344__OSX_AVAILABLE_STARTING(__MAC_10_4, __IPHONE_2_0)
345int32_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 */
355OSATOMIC_DEPRECATED_REPLACE_WITH(atomic_fetch_or)
356__OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_3_2)
357int32_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.
442fbc9d 365
ada7c492
A
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 */
370OSATOMIC_BARRIER_DEPRECATED_REPLACE_WITH(atomic_fetch_or)
371__OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_3_2)
372int32_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 */
384OSATOMIC_DEPRECATED_REPLACE_WITH(atomic_fetch_and)
385__OSX_AVAILABLE_STARTING(__MAC_10_4, __IPHONE_2_0)
386int32_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 */
399OSATOMIC_BARRIER_DEPRECATED_REPLACE_WITH(atomic_fetch_and)
400__OSX_AVAILABLE_STARTING(__MAC_10_4, __IPHONE_2_0)
401int32_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 */
411OSATOMIC_DEPRECATED_REPLACE_WITH(atomic_fetch_and)
412__OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_3_2)
413int32_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 */
426OSATOMIC_BARRIER_DEPRECATED_REPLACE_WITH(atomic_fetch_and)
427__OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_3_2)
428int32_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 */
440OSATOMIC_DEPRECATED_REPLACE_WITH(atomic_fetch_xor)
441__OSX_AVAILABLE_STARTING(__MAC_10_4, __IPHONE_2_0)
442int32_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 */
455OSATOMIC_BARRIER_DEPRECATED_REPLACE_WITH(atomic_fetch_xor)
456__OSX_AVAILABLE_STARTING(__MAC_10_4, __IPHONE_2_0)
457int32_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 */
467OSATOMIC_DEPRECATED_REPLACE_WITH(atomic_fetch_xor)
468__OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_3_2)
469int32_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 */
482OSATOMIC_BARRIER_DEPRECATED_REPLACE_WITH(atomic_fetch_xor)
483__OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_3_2)
484int32_t OSAtomicXor32OrigBarrier( uint32_t __theMask, volatile uint32_t *__theValue );
442fbc9d 485
ada7c492
A
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 */
501OSATOMIC_DEPRECATED_REPLACE_WITH(atomic_compare_exchange_strong)
502__OSX_AVAILABLE_STARTING(__MAC_10_4, __IPHONE_2_0)
503bool 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 */
517OSATOMIC_BARRIER_DEPRECATED_REPLACE_WITH(atomic_compare_exchange_strong)
518__OSX_AVAILABLE_STARTING(__MAC_10_4, __IPHONE_2_0)
519bool 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 */
530OSATOMIC_DEPRECATED_REPLACE_WITH(atomic_compare_exchange_strong)
531__OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0)
532bool 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 */
546OSATOMIC_BARRIER_DEPRECATED_REPLACE_WITH(atomic_compare_exchange_strong)
547__OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0)
548bool 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 */
561OSATOMIC_DEPRECATED_REPLACE_WITH(atomic_compare_exchange_strong)
562__OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0)
563bool 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 */
579OSATOMIC_BARRIER_DEPRECATED_REPLACE_WITH(atomic_compare_exchange_strong)
580__OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0)
581bool 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
442fbc9d 591 This function is equivalent to {@link OSAtomicCompareAndSwap32} on 32-bit architectures,
ada7c492
A
592 or {@link OSAtomicCompareAndSwap64} on 64-bit architectures.
593 @result Returns TRUE on a match, FALSE otherwise.
594 */
595OSATOMIC_DEPRECATED_REPLACE_WITH(atomic_compare_exchange_strong)
596__OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0)
597bool 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
442fbc9d 610 This function is equivalent to {@link OSAtomicCompareAndSwap32} on 32-bit architectures,
ada7c492
A
611 or {@link OSAtomicCompareAndSwap64} on 64-bit architectures.
612 @result Returns TRUE on a match, FALSE otherwise.
613 */
614OSATOMIC_BARRIER_DEPRECATED_REPLACE_WITH(atomic_compare_exchange_strong)
615__OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0)
616bool 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 */
627OSATOMIC_DEPRECATED_REPLACE_WITH(atomic_compare_exchange_strong)
628__OSX_AVAILABLE_STARTING(__MAC_10_4, __IPHONE_2_0)
629bool 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 */
644OSATOMIC_BARRIER_DEPRECATED_REPLACE_WITH(atomic_compare_exchange_strong)
645__OSX_AVAILABLE_STARTING(__MAC_10_4, __IPHONE_3_2)
646bool 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 */
669OSATOMIC_DEPRECATED_REPLACE_WITH(atomic_fetch_or)
670__OSX_AVAILABLE_STARTING(__MAC_10_4, __IPHONE_2_0)
671bool 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 */
692OSATOMIC_BARRIER_DEPRECATED_REPLACE_WITH(atomic_fetch_or)
693__OSX_AVAILABLE_STARTING(__MAC_10_4, __IPHONE_2_0)
694bool 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>.
442fbc9d 710
ada7c492
A
711 @result
712 Returns the original value of the bit being tested.
713 */
714OSATOMIC_DEPRECATED_REPLACE_WITH(atomic_fetch_and)
715__OSX_AVAILABLE_STARTING(__MAC_10_4, __IPHONE_2_0)
716bool 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.
442fbc9d 723
ada7c492
A
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>.
442fbc9d 727
ada7c492
A
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>.
442fbc9d 731
ada7c492
A
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 */
737OSATOMIC_BARRIER_DEPRECATED_REPLACE_WITH(atomic_fetch_and)
738__OSX_AVAILABLE_STARTING(__MAC_10_4, __IPHONE_2_0)
739bool OSAtomicTestAndClearBarrier( uint32_t __n, volatile void *__theAddress );
442fbc9d 740
ada7c492
A
741
742/*! @group Memory barriers */
743
744/*! @abstract Memory barrier.
745 @discussion
746 This function serves as both a read and write barrier.
747 */
748OSATOMIC_BARRIER_DEPRECATED_REPLACE_WITH(atomic_thread_fence)
749__OSX_AVAILABLE_STARTING(__MAC_10_4, __IPHONE_2_0)
750void 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
769extern "C++" {
e39c3b4b 770#if !(__has_include(<atomic>) && __has_extension(cxx_atomic))
ada7c492
A
771#error Cannot use inlined OSAtomic without <atomic> and C++11 atomics
772#endif
773#include <atomic>
774typedef std::atomic<uint8_t> _OSAtomic_uint8_t;
775typedef std::atomic<int32_t> _OSAtomic_int32_t;
776typedef std::atomic<uint32_t> _OSAtomic_uint32_t;
777typedef std::atomic<int64_t> _OSAtomic_int64_t;
778typedef 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>
786typedef _Atomic(uint8_t) _OSAtomic_uint8_t;
787typedef _Atomic(int32_t) _OSAtomic_int32_t;
788typedef _Atomic(uint32_t) _OSAtomic_uint32_t;
789typedef _Atomic(int64_t) _OSAtomic_int64_t;
790typedef _Atomic(void*) _OSAtomic_void_ptr_t;
791#define OSATOMIC_STD(_a) _a
792#endif
793
794#if __has_extension(c_alignof) && __has_attribute(aligned)
795typedef int64_t __attribute__((__aligned__(_Alignof(_OSAtomic_int64_t))))
796 OSAtomic_int64_aligned64_t;
797#elif __has_attribute(aligned)
798typedef int64_t __attribute__((__aligned__((sizeof(_OSAtomic_int64_t)))))
799 OSAtomic_int64_aligned64_t;
800#else
801typedef int64_t OSAtomic_int64_aligned64_t;
802#endif
803
804#if __has_attribute(always_inline)
ada7c492 805#define OSATOMIC_INLINE static __inline __attribute__((__always_inline__))
89154bfb
A
806#else
807#define OSATOMIC_INLINE static __inline
ada7c492
A
808#endif
809
810OSATOMIC_INLINE
811int32_t
812OSAtomicAdd32(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
819OSATOMIC_INLINE
820int32_t
821OSAtomicAdd32Barrier(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
828OSATOMIC_INLINE
829int32_t
830OSAtomicIncrement32(volatile int32_t *__theValue)
831{
832 return OSAtomicAdd32(1, __theValue);
833}
834
835OSATOMIC_INLINE
836int32_t
837OSAtomicIncrement32Barrier(volatile int32_t *__theValue)
838{
839 return OSAtomicAdd32Barrier(1, __theValue);
840}
841
842OSATOMIC_INLINE
843int32_t
844OSAtomicDecrement32(volatile int32_t *__theValue)
845{
846 return OSAtomicAdd32(-1, __theValue);
847}
848
849OSATOMIC_INLINE
850int32_t
851OSAtomicDecrement32Barrier(volatile int32_t *__theValue)
852{
853 return OSAtomicAdd32Barrier(-1, __theValue);
854}
855
856OSATOMIC_INLINE
857int64_t
858OSAtomicAdd64(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
866OSATOMIC_INLINE
867int64_t
868OSAtomicAdd64Barrier(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
876OSATOMIC_INLINE
877int64_t
878OSAtomicIncrement64(volatile OSAtomic_int64_aligned64_t *__theValue)
879{
880 return OSAtomicAdd64(1, __theValue);
881}
882
883OSATOMIC_INLINE
884int64_t
885OSAtomicIncrement64Barrier(volatile OSAtomic_int64_aligned64_t *__theValue)
886{
887 return OSAtomicAdd64Barrier(1, __theValue);
888}
889
890OSATOMIC_INLINE
891int64_t
892OSAtomicDecrement64(volatile OSAtomic_int64_aligned64_t *__theValue)
893{
894 return OSAtomicAdd64(-1, __theValue);
895}
896
897OSATOMIC_INLINE
898int64_t
899OSAtomicDecrement64Barrier(volatile OSAtomic_int64_aligned64_t *__theValue)
900{
901 return OSAtomicAdd64Barrier(-1, __theValue);
902}
903
904OSATOMIC_INLINE
905int32_t
906OSAtomicOr32(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
913OSATOMIC_INLINE
914int32_t
915OSAtomicOr32Barrier(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
922OSATOMIC_INLINE
923int32_t
924OSAtomicOr32Orig(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
931OSATOMIC_INLINE
932int32_t
933OSAtomicOr32OrigBarrier(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
940OSATOMIC_INLINE
941int32_t
942OSAtomicAnd32(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
949OSATOMIC_INLINE
950int32_t
951OSAtomicAnd32Barrier(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
958OSATOMIC_INLINE
959int32_t
960OSAtomicAnd32Orig(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
967OSATOMIC_INLINE
968int32_t
969OSAtomicAnd32OrigBarrier(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
976OSATOMIC_INLINE
977int32_t
978OSAtomicXor32(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
985OSATOMIC_INLINE
986int32_t
987OSAtomicXor32Barrier(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
994OSATOMIC_INLINE
995int32_t
996OSAtomicXor32Orig(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
1003OSATOMIC_INLINE
1004int32_t
1005OSAtomicXor32OrigBarrier(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
1012OSATOMIC_INLINE
1013bool
1014OSAtomicCompareAndSwap32(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
1023OSATOMIC_INLINE
1024bool
1025OSAtomicCompareAndSwap32Barrier(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
1034OSATOMIC_INLINE
1035bool
1036OSAtomicCompareAndSwapPtr(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
1045OSATOMIC_INLINE
1046bool
1047OSAtomicCompareAndSwapPtrBarrier(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
1056OSATOMIC_INLINE
1057bool
1058OSAtomicCompareAndSwapInt(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
1067OSATOMIC_INLINE
1068bool
1069OSAtomicCompareAndSwapIntBarrier(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
1078OSATOMIC_INLINE
1079bool
1080OSAtomicCompareAndSwapLong(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
1089OSATOMIC_INLINE
1090bool
1091OSAtomicCompareAndSwapLongBarrier(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
1100OSATOMIC_INLINE
1101bool
1102OSAtomicCompareAndSwap64(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
1111OSATOMIC_INLINE
1112bool
1113OSAtomicCompareAndSwap64Barrier(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
1122OSATOMIC_INLINE
1123bool
1124OSAtomicTestAndSet(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
1132OSATOMIC_INLINE
1133bool
1134OSAtomicTestAndSetBarrier(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
1142OSATOMIC_INLINE
1143bool
1144OSAtomicTestAndClear(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
1152OSATOMIC_INLINE
1153bool
1154OSAtomicTestAndClearBarrier(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
1162OSATOMIC_INLINE
1163void
1164OSMemoryBarrier(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
442fbc9d
A
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
1195typedef volatile struct {
1196 void *opaque1;
1197 void *opaque2;
1198 int opaque3;
1199} __attribute__ ((aligned (16))) OSFifoQueueHead;
1200
1201#else
1202
1203typedef 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, 10.16))
1235void 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, 10.16))
1260void* OSAtomicFifoDequeue( OSFifoQueueHead *__list, size_t __offset);
1261
1262__END_DECLS
1263
1264#endif /* TARGET_OS_OSX || TARGET_OS_DRIVERKIT */
1265
ada7c492 1266#endif /* _OSATOMIC_DEPRECATED_H_ */