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