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