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