1 /*
2 * Copyright (c) 2004-2006 Apple Computer, 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_H_
25 #define _OSATOMIC_H_
26
27 #include <stddef.h>
28 #include <sys/cdefs.h>
29 #include <stdint.h>
30 #include <stdbool.h>
31
32 #include <Availability.h>
33
34 /*! @header
35 * These are the preferred atomic and synchronization operations.
36 *
37 * Their implementation is customized at boot time for the platform, including
38 * late-breaking errata fixes as necessary. They are thread safe.
39 *
40 * WARNING: all addresses passed to these functions must be "naturally aligned",
41 * i.e. * <code>int32_t</code> pointers must be 32-bit aligned (low 2 bits of
42 * address are zeroes), and <code>int64_t</code> pointers must be 64-bit aligned
43 * (low 3 bits of address are zeroes.)
44 *
45 * Note that some versions of the atomic functions incorporate memory barriers
46 * and some do not. Barriers strictly order memory access on weakly-ordered
47 * architectures such as ARM. All loads and stores that appear (in sequential
48 * program order) before the barrier are guaranteed to complete before any
49 * load or store that appears after the barrier.
50 *
51 * The barrier operation is typically a no-op on uniprocessor systems and
52 * fully enabled on multiprocessor systems. On some platforms, such as ARM,
53 * the barrier can be quite expensive.
54 *
55 * Most code should use the barrier functions to ensure that memory shared
56 * between threads is properly synchronized. For example, if you want to
57 * initialize a shared data structure and then atomically increment a variable
58 * to indicate that the initialization is complete, you must use
59 * {@link OSAtomicIncrement32Barrier} to ensure that the stores to your data
60 * structure complete before the atomic increment.
61 *
62 * Likewise, the consumer of that data structure must use
63 * {@link OSAtomicDecrement32Barrier},
64 * in order to ensure that their loads of the structure are not executed before
65 * the atomic decrement. On the other hand, if you are simply incrementing a
66 * global counter, then it is safe and potentially faster to use
67 * {@link OSAtomicIncrement32}.
68 *
69 * If you are unsure which version to use, prefer the barrier variants as they
70 * are safer.
71 *
72 * The spinlock and queue operations always incorporate a barrier.
73 *
74 * For the kernel-space version of this header, see
75 * {@link //apple_ref/doc/header/OSAtomic.h OSAtomic.h (Kernel Framework)}
76 *
77 * @apiuid //apple_ref/doc/header/user_space_OSAtomic.h
78 */
79 __BEGIN_DECLS
80
81
82 /*! @group Arithmetic functions
83 All functions in this group return the new value.
84 */
85
86 /*! @abstract Atomically adds two 32-bit values.
87 @discussion
88 This function adds the value given by <code>__theAmount</code> to the
89 value in the memory location referenced by <code>__theValue</code>,
90 storing the result back to that memory location atomically.
91 @result Returns the new value.
92 */
93 __OSX_AVAILABLE_STARTING(__MAC_10_4, __IPHONE_2_0)
94 int32_t OSAtomicAdd32( int32_t __theAmount, volatile int32_t *__theValue );
95
96
97 /*! @abstract Atomically adds two 32-bit values.
98 @discussion
99 This function adds the value given by <code>__theAmount</code> to the
100 value in the memory location referenced by <code>__theValue</code>,
101 storing the result back to that memory location atomically.
102
103 This function is equivalent to {@link OSAtomicAdd32}
104 except that it also introduces a barrier.
105 @result Returns the new value.
106 */
107 __OSX_AVAILABLE_STARTING(__MAC_10_4, __IPHONE_2_0)
108 int32_t OSAtomicAdd32Barrier( int32_t __theAmount, volatile int32_t *__theValue );
109
110
111 #if __IPHONE_OS_VERSION_MIN_REQUIRED >= __IPHONE_7_1
112
113 /*! @abstract Atomically increments a 32-bit value.
114 @result Returns the new value.
115 */
116 __OSX_AVAILABLE_STARTING(__MAC_NA, __IPHONE_7_1)
117 int32_t OSAtomicIncrement32( volatile int32_t *__theValue );
118
119
120 /*! @abstract Atomically increments a 32-bit value with a barrier.
121 @discussion
122 This function is equivalent to {@link OSAtomicIncrement32}
123 except that it also introduces a barrier.
124 @result Returns the new value.
125 */
126 __OSX_AVAILABLE_STARTING(__MAC_NA, __IPHONE_7_1)
127 int32_t OSAtomicIncrement32Barrier( volatile int32_t *__theValue );
128
129
130 /*! @abstract Atomically decrements a 32-bit value.
131 @result Returns the new value.
132 */
133 __OSX_AVAILABLE_STARTING(__MAC_NA, __IPHONE_7_1)
134 int32_t OSAtomicDecrement32( volatile int32_t *__theValue );
135
136
137 /*! @abstract Atomically decrements a 32-bit value with a barrier.
138 @discussion
139 This function is equivalent to {@link OSAtomicDecrement32}
140 except that it also introduces a barrier.
141 @result Returns the new value.
142 */
143 __OSX_AVAILABLE_STARTING(__MAC_NA, __IPHONE_7_1)
144 int32_t OSAtomicDecrement32Barrier( volatile int32_t *__theValue );
145
146 #else
147 __inline static
OSAtomicIncrement32(volatile int32_t * __theValue)148 int32_t OSAtomicIncrement32( volatile int32_t *__theValue )
149 { return OSAtomicAdd32( 1, __theValue); }
150
151 __inline static
OSAtomicIncrement32Barrier(volatile int32_t * __theValue)152 int32_t OSAtomicIncrement32Barrier( volatile int32_t *__theValue )
153 { return OSAtomicAdd32Barrier( 1, __theValue); }
154
155 __inline static
OSAtomicDecrement32(volatile int32_t * __theValue)156 int32_t OSAtomicDecrement32( volatile int32_t *__theValue )
157 { return OSAtomicAdd32( -1, __theValue); }
158
159 __inline static
OSAtomicDecrement32Barrier(volatile int32_t * __theValue)160 int32_t OSAtomicDecrement32Barrier( volatile int32_t *__theValue )
161 { return OSAtomicAdd32Barrier( -1, __theValue); }
162 #endif
163
164
165 /*! @abstract Atomically adds two 64-bit values.
166 @discussion
167 This function adds the value given by <code>__theAmount</code> to the
168 value in the memory location referenced by <code>__theValue</code>,
169 storing the result back to that memory location atomically.
170 @result Returns the new value.
171 */
172 __OSX_AVAILABLE_STARTING(__MAC_10_4, __IPHONE_2_0)
173 int64_t OSAtomicAdd64( int64_t __theAmount, volatile int64_t *__theValue );
174
175
176 /*! @abstract Atomically adds two 64-bit values with a barrier.
177 @discussion
178 This function adds the value given by <code>__theAmount</code> to the
179 value in the memory location referenced by <code>__theValue</code>,
180 storing the result back to that memory location atomically.
181
182 This function is equivalent to {@link OSAtomicAdd64}
183 except that it also introduces a barrier.
184 @result Returns the new value.
185 */
186 __OSX_AVAILABLE_STARTING(__MAC_10_4, __IPHONE_3_2)
187 int64_t OSAtomicAdd64Barrier( int64_t __theAmount, volatile int64_t *__theValue );
188
189
190 #if __IPHONE_OS_VERSION_MIN_REQUIRED >= __IPHONE_7_1
191
192 /*! @abstract Atomically increments a 64-bit value.
193 @result Returns the new value.
194 */
195 __OSX_AVAILABLE_STARTING(__MAC_NA, __IPHONE_7_1)
196 int64_t OSAtomicIncrement64( volatile int64_t *__theValue );
197
198
199 /*! @abstract Atomically increments a 64-bit value with a barrier.
200 @discussion
201 This function is equivalent to {@link OSAtomicIncrement64}
202 except that it also introduces a barrier.
203 @result Returns the new value.
204 */
205 __OSX_AVAILABLE_STARTING(__MAC_NA, __IPHONE_7_1)
206 int64_t OSAtomicIncrement64Barrier( volatile int64_t *__theValue );
207
208
209 /*! @abstract Atomically decrements a 64-bit value.
210 @result Returns the new value.
211 */
212 __OSX_AVAILABLE_STARTING(__MAC_NA, __IPHONE_7_1)
213 int64_t OSAtomicDecrement64( volatile int64_t *__theValue );
214
215
216 /*! @abstract Atomically decrements a 64-bit value with a barrier.
217 @discussion
218 This function is equivalent to {@link OSAtomicDecrement64}
219 except that it also introduces a barrier.
220 @result Returns the new value.
221 */
222 __OSX_AVAILABLE_STARTING(__MAC_NA, __IPHONE_7_1)
223 int64_t OSAtomicDecrement64Barrier( volatile int64_t *__theValue );
224
225 #else
226 __inline static
OSAtomicIncrement64(volatile int64_t * __theValue)227 int64_t OSAtomicIncrement64( volatile int64_t *__theValue )
228 { return OSAtomicAdd64( 1, __theValue); }
229
230 __inline static
OSAtomicIncrement64Barrier(volatile int64_t * __theValue)231 int64_t OSAtomicIncrement64Barrier( volatile int64_t *__theValue )
232 { return OSAtomicAdd64Barrier( 1, __theValue); }
233
234 __inline static
OSAtomicDecrement64(volatile int64_t * __theValue)235 int64_t OSAtomicDecrement64( volatile int64_t *__theValue )
236 { return OSAtomicAdd64( -1, __theValue); }
237
238 __inline static
OSAtomicDecrement64Barrier(volatile int64_t * __theValue)239 int64_t OSAtomicDecrement64Barrier( volatile int64_t *__theValue )
240 { return OSAtomicAdd64Barrier( -1, __theValue); }
241 #endif
242
243
244 /*! @group Boolean functions (AND, OR, XOR)
245 *
246 * @discussion Functions in this group come in four variants for each operation:
247 * with and without barriers, and functions that return the original value or
248 * the result value of the operation.
249 *
250 * The "Orig" versions return the original value, (before the operation); the non-Orig
251 * versions return the value after the operation. All are layered on top of
252 * {@link OSAtomicCompareAndSwap32} and similar.
253 */
254
255 /*! @abstract Atomic bitwise OR of two 32-bit values.
256 @discussion
257 This function performs the bitwise OR of the value given by <code>__theMask</code>
258 with the value in the memory location referenced by <code>__theValue</code>,
259 storing the result back to that memory location atomically.
260 @result Returns the new value.
261 */
262 __OSX_AVAILABLE_STARTING(__MAC_10_4, __IPHONE_2_0)
263 int32_t OSAtomicOr32( uint32_t __theMask, volatile uint32_t *__theValue );
264
265
266 /*! @abstract Atomic bitwise OR of two 32-bit values with barrier.
267 @discussion
268 This function performs the bitwise OR of the value given by <code>__theMask</code>
269 with the value in the memory location referenced by <code>__theValue</code>,
270 storing the result back to that memory location atomically.
271
272 This function is equivalent to {@link OSAtomicOr32}
273 except that it also introduces a barrier.
274 @result Returns the new value.
275 */
276 __OSX_AVAILABLE_STARTING(__MAC_10_4, __IPHONE_2_0)
277 int32_t OSAtomicOr32Barrier( uint32_t __theMask, volatile uint32_t *__theValue );
278
279
280 /*! @abstract Atomic bitwise OR of two 32-bit values returning original.
281 @discussion
282 This function performs the bitwise OR of the value given by <code>__theMask</code>
283 with the value in the memory location referenced by <code>__theValue</code>,
284 storing the result back to that memory location atomically.
285 @result Returns the original value referenced by <code>__theValue</code>.
286 */
287 __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_3_2)
288 int32_t OSAtomicOr32Orig( uint32_t __theMask, volatile uint32_t *__theValue );
289
290
291 /*! @abstract Atomic bitwise OR of two 32-bit values returning original with barrier.
292 @discussion
293 This function performs the bitwise OR of the value given by <code>__theMask</code>
294 with the value in the memory location referenced by <code>__theValue</code>,
295 storing the result back to that memory location atomically.
296
297 This function is equivalent to {@link OSAtomicOr32Orig}
298 except that it also introduces a barrier.
299 @result Returns the original value referenced by <code>__theValue</code>.
300 */
301 __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_3_2)
302 int32_t OSAtomicOr32OrigBarrier( uint32_t __theMask, volatile uint32_t *__theValue );
303
304
305
306
307 /*! @abstract Atomic bitwise AND of two 32-bit values.
308 @discussion
309 This function performs the bitwise AND of the value given by <code>__theMask</code>
310 with the value in the memory location referenced by <code>__theValue</code>,
311 storing the result back to that memory location atomically.
312 @result Returns the new value.
313 */
314 __OSX_AVAILABLE_STARTING(__MAC_10_4, __IPHONE_2_0)
315 int32_t OSAtomicAnd32( uint32_t __theMask, volatile uint32_t *__theValue );
316
317
318 /*! @abstract Atomic bitwise AND of two 32-bit values with barrier.
319 @discussion
320 This function performs the bitwise AND of the value given by <code>__theMask</code>
321 with the value in the memory location referenced by <code>__theValue</code>,
322 storing the result back to that memory location atomically.
323
324 This function is equivalent to {@link OSAtomicAnd32}
325 except that it also introduces a barrier.
326 @result Returns the new value.
327 */
328 __OSX_AVAILABLE_STARTING(__MAC_10_4, __IPHONE_2_0)
329 int32_t OSAtomicAnd32Barrier( uint32_t __theMask, volatile uint32_t *__theValue );
330
331
332 /*! @abstract Atomic bitwise AND of two 32-bit values returning original.
333 @discussion
334 This function performs the bitwise AND 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 @result Returns the original value referenced by <code>__theValue</code>.
338 */
339 __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_3_2)
340 int32_t OSAtomicAnd32Orig( uint32_t __theMask, volatile uint32_t *__theValue );
341
342
343 /*! @abstract Atomic bitwise AND of two 32-bit values returning original with barrier.
344 @discussion
345 This function performs the bitwise AND of the value given by <code>__theMask</code>
346 with the value in the memory location referenced by <code>__theValue</code>,
347 storing the result back to that memory location atomically.
348
349 This function is equivalent to {@link OSAtomicAnd32Orig}
350 except that it also introduces a barrier.
351 @result Returns the original value referenced by <code>__theValue</code>.
352 */
353 __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_3_2)
354 int32_t OSAtomicAnd32OrigBarrier( uint32_t __theMask, volatile uint32_t *__theValue );
355
356
357
358
359 /*! @abstract Atomic bitwise XOR of two 32-bit values.
360 @discussion
361 This function performs the bitwise XOR 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 @result Returns the new value.
365 */
366 __OSX_AVAILABLE_STARTING(__MAC_10_4, __IPHONE_2_0)
367 int32_t OSAtomicXor32( uint32_t __theMask, volatile uint32_t *__theValue );
368
369
370 /*! @abstract Atomic bitwise XOR of two 32-bit values with barrier.
371 @discussion
372 This function performs the bitwise XOR of the value given by <code>__theMask</code>
373 with the value in the memory location referenced by <code>__theValue</code>,
374 storing the result back to that memory location atomically.
375
376 This function is equivalent to {@link OSAtomicXor32}
377 except that it also introduces a barrier.
378 @result Returns the new value.
379 */
380 __OSX_AVAILABLE_STARTING(__MAC_10_4, __IPHONE_2_0)
381 int32_t OSAtomicXor32Barrier( uint32_t __theMask, volatile uint32_t *__theValue );
382
383
384 /*! @abstract Atomic bitwise XOR of two 32-bit values returning original.
385 @discussion
386 This function performs the bitwise XOR of the value given by <code>__theMask</code>
387 with the value in the memory location referenced by <code>__theValue</code>,
388 storing the result back to that memory location atomically.
389 @result Returns the original value referenced by <code>__theValue</code>.
390 */
391 __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_3_2)
392 int32_t OSAtomicXor32Orig( uint32_t __theMask, volatile uint32_t *__theValue );
393
394
395 /*! @abstract Atomic bitwise XOR of two 32-bit values returning original with barrier.
396 @discussion
397 This function performs the bitwise XOR of the value given by <code>__theMask</code>
398 with the value in the memory location referenced by <code>__theValue</code>,
399 storing the result back to that memory location atomically.
400
401 This function is equivalent to {@link OSAtomicXor32Orig}
402 except that it also introduces a barrier.
403 @result Returns the original value referenced by <code>__theValue</code>.
404 */
405 __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_3_2)
406 int32_t OSAtomicXor32OrigBarrier( uint32_t __theMask, volatile uint32_t *__theValue );
407
408
409 /*! @group Compare and swap
410 * Functions in this group return true if the swap occured. There are several versions,
411 * depending on data type and on whether or not a barrier is used.
412 */
413
414
415 /*! @abstract Compare and swap for 32-bit values.
416 @discussion
417 This function compares the value in <code>__oldValue</code> to the value
418 in the memory location referenced by <code>__theValue</code>. If the values
419 match, this function stores the value from <code>__newValue</code> into
420 that memory location atomically.
421 @result Returns TRUE on a match, FALSE otherwise.
422 */
423 __OSX_AVAILABLE_STARTING(__MAC_10_4, __IPHONE_2_0)
424 bool OSAtomicCompareAndSwap32( int32_t __oldValue, int32_t __newValue, volatile int32_t *__theValue );
425
426
427 /*! @abstract Compare and swap for 32-bit values with barrier.
428 @discussion
429 This function compares the value in <code>__oldValue</code> to the value
430 in the memory location referenced by <code>__theValue</code>. If the values
431 match, this function stores the value from <code>__newValue</code> into
432 that memory location atomically.
433
434 This function is equivalent to {@link OSAtomicCompareAndSwap32}
435 except that it also introduces a barrier.
436 @result Returns TRUE on a match, FALSE otherwise.
437 */
438 __OSX_AVAILABLE_STARTING(__MAC_10_4, __IPHONE_2_0)
439 bool OSAtomicCompareAndSwap32Barrier( int32_t __oldValue, int32_t __newValue, volatile int32_t *__theValue );
440
441
442 /*! @abstract Compare and swap pointers.
443 @discussion
444 This function compares the pointer stored in <code>__oldValue</code> to the pointer
445 in the memory location referenced by <code>__theValue</code>. If the pointers
446 match, this function stores the pointer from <code>__newValue</code> into
447 that memory location atomically.
448 @result Returns TRUE on a match, FALSE otherwise.
449 */
450 __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0)
451 bool OSAtomicCompareAndSwapPtr( void *__oldValue, void *__newValue, void * volatile *__theValue );
452
453
454 /*! @abstract Compare and swap pointers with barrier.
455 @discussion
456 This function compares the pointer stored in <code>__oldValue</code> to the pointer
457 in the memory location referenced by <code>__theValue</code>. If the pointers
458 match, this function stores the pointer from <code>__newValue</code> into
459 that memory location atomically.
460
461 This function is equivalent to {@link OSAtomicCompareAndSwapPtr}
462 except that it also introduces a barrier.
463 @result Returns TRUE on a match, FALSE otherwise.
464 */
465 __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0)
466 bool OSAtomicCompareAndSwapPtrBarrier( void *__oldValue, void *__newValue, void * volatile *__theValue );
467
468
469 /*! @abstract Compare and swap for <code>int</code> values.
470 @discussion
471 This function compares the value in <code>__oldValue</code> to the value
472 in the memory location referenced by <code>__theValue</code>. If the values
473 match, this function stores the value from <code>__newValue</code> into
474 that memory location atomically.
475
476 This function is equivalent to {@link OSAtomicCompareAndSwap32}.
477 @result Returns TRUE on a match, FALSE otherwise.
478 */
479 __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0)
480 bool OSAtomicCompareAndSwapInt( int __oldValue, int __newValue, volatile int *__theValue );
481
482
483 /*! @abstract Compare and swap for <code>int</code> values.
484 @discussion
485 This function compares the value in <code>__oldValue</code> to the value
486 in the memory location referenced by <code>__theValue</code>. If the values
487 match, this function stores the value from <code>__newValue</code> into
488 that memory location atomically.
489
490 This function is equivalent to {@link OSAtomicCompareAndSwapInt}
491 except that it also introduces a barrier.
492
493 This function is equivalent to {@link OSAtomicCompareAndSwap32Barrier}.
494 @result Returns TRUE on a match, FALSE otherwise.
495 */
496 __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0)
497 bool OSAtomicCompareAndSwapIntBarrier( int __oldValue, int __newValue, volatile int *__theValue );
498
499
500 /*! @abstract Compare and swap for <code>long</code> values.
501 @discussion
502 This function compares the value in <code>__oldValue</code> to the value
503 in the memory location referenced by <code>__theValue</code>. If the values
504 match, this function stores the value from <code>__newValue</code> into
505 that memory location atomically.
506
507 This function is equivalent to {@link OSAtomicCompareAndSwap32} on 32-bit architectures,
508 or {@link OSAtomicCompareAndSwap64} on 64-bit architectures.
509 @result Returns TRUE on a match, FALSE otherwise.
510 */
511 __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0)
512 bool OSAtomicCompareAndSwapLong( long __oldValue, long __newValue, volatile long *__theValue );
513
514
515 /*! @abstract Compare and swap for <code>long</code> values.
516 @discussion
517 This function compares the value in <code>__oldValue</code> to the value
518 in the memory location referenced by <code>__theValue</code>. If the values
519 match, this function stores the value from <code>__newValue</code> into
520 that memory location atomically.
521
522 This function is equivalent to {@link OSAtomicCompareAndSwapLong}
523 except that it also introduces a barrier.
524
525 This function is equivalent to {@link OSAtomicCompareAndSwap32} on 32-bit architectures,
526 or {@link OSAtomicCompareAndSwap64} on 64-bit architectures.
527 @result Returns TRUE on a match, FALSE otherwise.
528 */
529 __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0)
530 bool OSAtomicCompareAndSwapLongBarrier( long __oldValue, long __newValue, volatile long *__theValue );
531
532
533 /*! @abstract Compare and swap for <code>uint64_t</code> values.
534 @discussion
535 This function compares the value in <code>__oldValue</code> to the value
536 in the memory location referenced by <code>__theValue</code>. If the values
537 match, this function stores the value from <code>__newValue</code> into
538 that memory location atomically.
539 @result Returns TRUE on a match, FALSE otherwise.
540 */
541 __OSX_AVAILABLE_STARTING(__MAC_10_4, __IPHONE_2_0)
542 bool OSAtomicCompareAndSwap64( int64_t __oldValue, int64_t __newValue, volatile int64_t *__theValue );
543
544
545 /*! @abstract Compare and swap for <code>uint64_t</code> values.
546 @discussion
547 This function compares the value in <code>__oldValue</code> to the value
548 in the memory location referenced by <code>__theValue</code>. If the values
549 match, this function stores the value from <code>__newValue</code> into
550 that memory location atomically.
551
552 This function is equivalent to {@link OSAtomicCompareAndSwap64}
553 except that it also introduces a barrier.
554 @result Returns TRUE on a match, FALSE otherwise.
555 */
556 __OSX_AVAILABLE_STARTING(__MAC_10_4, __IPHONE_3_2)
557 bool OSAtomicCompareAndSwap64Barrier( int64_t __oldValue, int64_t __newValue, volatile int64_t *__theValue );
558
559
560 /* Test and set.
561 * They return the original value of the bit, and operate on bit (0x80>>(n&7))
562 * in byte ((char*)theAddress + (n>>3)).
563 */
564 /*! @abstract Atomic test and set
565 @discussion
566 This function tests a bit in the value referenced by
567 <code>__theAddress</code> and if it is not set, sets it.
568
569 The bit is chosen by the value of <code>__n</code> such that the
570 operation will be performed on bit <code>(0x80 >> (__n & 7))</code>
571 of byte <code>((char *)__theAddress + (n >> 3))</code>.
572
573 For example, if <code>__theAddress</code> points to a 64-bit value,
574 to compare the value of the most significant bit, you would specify
575 <code>56</code> for <code>__n</code>.
576 @result
577 Returns the original value of the bit being tested.
578 */
579 __OSX_AVAILABLE_STARTING(__MAC_10_4, __IPHONE_2_0)
580 bool OSAtomicTestAndSet( uint32_t __n, volatile void *__theAddress );
581
582
583 /*! @abstract Atomic test and set with barrier
584 @discussion
585 This function tests a bit in the value referenced by <code>__theAddress</code>
586 and if it is not set, sets it.
587
588 The bit is chosen by the value of <code>__n</code> such that the
589 operation will be performed on bit <code>(0x80 >> (__n & 7))</code>
590 of byte <code>((char *)__theAddress + (n >> 3))</code>.
591
592 For example, if <code>__theAddress</code> points to a 64-bit value,
593 to compare the value of the most significant bit, you would specify
594 <code>56</code> for <code>__n</code>.
595
596 This function is equivalent to {@link OSAtomicTestAndSet}
597 except that it also introduces a barrier.
598 @result
599 Returns the original value of the bit being tested.
600 */
601 __OSX_AVAILABLE_STARTING(__MAC_10_4, __IPHONE_2_0)
602 bool OSAtomicTestAndSetBarrier( uint32_t __n, volatile void *__theAddress );
603
604
605
606 /*! @abstract Atomic test and clear
607 @discussion
608 This function tests a bit in the value referenced by <code>__theAddress</code>
609 and if it is not cleared, clears it.
610
611 The bit is chosen by the value of <code>__n</code> such that the
612 operation will be performed on bit <code>(0x80 >> (__n & 7))</code>
613 of byte <code>((char *)__theAddress + (n >> 3))</code>.
614
615 For example, if <code>__theAddress</code> points to a 64-bit value,
616 to compare the value of the most significant bit, you would specify
617 <code>56</code> for <code>__n</code>.
618
619 @result
620 Returns the original value of the bit being tested.
621 */
622 __OSX_AVAILABLE_STARTING(__MAC_10_4, __IPHONE_2_0)
623 bool OSAtomicTestAndClear( uint32_t __n, volatile void *__theAddress );
624
625
626 /*! @abstract Atomic test and clear
627 @discussion
628 This function tests a bit in the value referenced by <code>__theAddress</code>
629 and if it is not cleared, clears it.
630
631 The bit is chosen by the value of <code>__n</code> such that the
632 operation will be performed on bit <code>(0x80 >> (__n & 7))</code>
633 of byte <code>((char *)__theAddress + (n >> 3))</code>.
634
635 For example, if <code>__theAddress</code> points to a 64-bit value,
636 to compare the value of the most significant bit, you would specify
637 <code>56</code> for <code>__n</code>.
638
639 This function is equivalent to {@link OSAtomicTestAndSet}
640 except that it also introduces a barrier.
641 @result
642 Returns the original value of the bit being tested.
643 */
644 __OSX_AVAILABLE_STARTING(__MAC_10_4, __IPHONE_2_0)
645 bool OSAtomicTestAndClearBarrier( uint32_t __n, volatile void *__theAddress );
646
647
648 /*! @group Spinlocks
649 * These spinlocks use memory barriers as required to synchronize access to shared
650 * memory protected by the lock.
651 */
652
653 /*! @abstract The default value for an <code>OSSpinLock</code>.
654 @discussion
655 The convention is that unlocked is zero, locked is nonzero.
656 */
657 #define OS_SPINLOCK_INIT 0
658
659
660 /*! @abstract Data type for a spinlock.
661 @discussion
662 You should always initialize a spinlock to {@link OS_SPINLOCK_INIT} before
663 using it.
664 */
665 typedef int32_t OSSpinLock;
666
667
668 /*! @abstract Locks a spinlock if it would not block
669 @result
670 Returns <code>false</code> if the lock was already held by another thread,
671 <code>true</code> if it took the lock successfully.
672 */
673 __OSX_AVAILABLE_STARTING(__MAC_10_4, __IPHONE_2_0)
674 bool OSSpinLockTry( volatile OSSpinLock *__lock );
675
676
677 /*! @abstract Locks a spinlock
678 @discussion
679 Although the lock operation spins, it employs various strategies
680 to back off if the lock is held, making it immune to most priority-inversion
681 livelocks.
682 */
683 __OSX_AVAILABLE_STARTING(__MAC_10_4, __IPHONE_2_0)
684 void OSSpinLockLock( volatile OSSpinLock *__lock );
685
686
687 /*! @abstract Unlocks a spinlock */
688 __OSX_AVAILABLE_STARTING(__MAC_10_4, __IPHONE_2_0)
689 void OSSpinLockUnlock( volatile OSSpinLock *__lock );
690
691
692 /*! @group Lockless atomic enqueue and dequeue
693 * These routines manipulate singly-linked LIFO lists.
694 */
695
696 /*! @abstract The data structure for a queue head.
697 @discussion
698 You should always initialize a queue head structure with the
699 initialization vector {@link OS_ATOMIC_QUEUE_INIT} before use.
700 */
701 #if defined(__x86_64__)
702
703 typedef volatile struct {
704 void *opaque1;
705 long opaque2;
706 } __attribute__ ((aligned (16))) OSQueueHead;
707
708 #else
709
710 typedef volatile struct {
711 void *opaque1;
712 long opaque2;
713 } OSQueueHead;
714
715 #endif
716
717 /*! @abstract The initialization vector for a queue head. */
718 #define OS_ATOMIC_QUEUE_INIT { NULL, 0 }
719
720 /*! @abstract Enqueue an item onto a list.
721 @discussion
722 Memory barriers are incorporated as needed to permit thread-safe access
723 to the queue element.
724 @param __list
725 The list on which you want to enqueue the item.
726 @param __new
727 The item to add.
728 @param __offset
729 The "offset" parameter is the offset (in bytes) of the link field
730 from the beginning of the data structure being queued (<code>__new</code>).
731 The link field should be a pointer type.
732 The <code>__offset</code> value needs to be same for all enqueuing and
733 dequeuing operations on the same queue, even if different structure types
734 are enqueued on that queue. The use of <code>offsetset()</code>, defined in
735 <code>stddef.h</code> is the common way to specify the <code>__offset</code>
736 value.
737 */
738 __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_4_0)
739 void OSAtomicEnqueue( OSQueueHead *__list, void *__new, size_t __offset);
740
741
742 /*! @abstract Dequeue an item from a list.
743 @discussion
744 Memory barriers are incorporated as needed to permit thread-safe access
745 to the queue element.
746 @param __list
747 The list on which you want to enqueue the item.
748 @param __offset
749 The "offset" parameter is the offset (in bytes) of the link field
750 from the beginning of the data structure being queued (<code>__new</code>).
751 The link field should be a pointer type.
752 The <code>__offset</code> value needs to be same for all enqueuing and
753 dequeuing operations on the same queue, even if different structure types
754 are enqueued on that queue. The use of <code>offsetset()</code>, defined in
755 <code>stddef.h</code> is the common way to specify the <code>__offset</code>
756 value.
757 @result
758 Returns the most recently enqueued element, or <code>NULL</code> if the
759 list is empty.
760 */
761 __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_4_0)
762 void* OSAtomicDequeue( OSQueueHead *__list, size_t __offset);
763
764 #if defined(__x86_64__) || defined(__i386__)
765
766 /*! @group Lockless atomic fifo enqueue and dequeue
767 * These routines manipulate singly-linked FIFO lists.
768 */
769
770 /*! @abstract The data structure for a fifo queue head.
771 @discussion
772 You should always initialize a fifo queue head structure with the
773 initialization vector {@link OS_ATOMIC_FIFO_QUEUE_INIT} before use.
774 */
775 #if defined(__x86_64__)
776
777 typedef volatile struct {
778 void *opaque1;
779 void *opaque2;
780 int opaque3;
781 } __attribute__ ((aligned (16))) OSFifoQueueHead;
782
783 #else
784
785 typedef volatile struct {
786 void *opaque1;
787 void *opaque2;
788 int opaque3;
789 } OSFifoQueueHead;
790
791 #endif
792
793 /*! @abstract The initialization vector for a fifo queue head. */
794 #define OS_ATOMIC_FIFO_QUEUE_INIT { NULL, NULL, 0 }
795
796 /*! @abstract Enqueue an item onto a list.
797 @discussion
798 Memory barriers are incorporated as needed to permit thread-safe access
799 to the queue element.
800 @param __list
801 The list on which you want to enqueue the item.
802 @param __new
803 The item to add.
804 @param __offset
805 The "offset" parameter is the offset (in bytes) of the link field
806 from the beginning of the data structure being queued (<code>__new</code>).
807 The link field should be a pointer type.
808 The <code>__offset</code> value needs to be same for all enqueuing and
809 dequeuing operations on the same queue, even if different structure types
810 are enqueued on that queue. The use of <code>offsetset()</code>, defined in
811 <code>stddef.h</code> is the common way to specify the <code>__offset</code>
812 value.
813 */
814 __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_NA)
815 void OSAtomicFifoEnqueue( OSFifoQueueHead *__list, void *__new, size_t __offset);
816
817 /*! @abstract Dequeue an item from a list.
818 @discussion
819 Memory barriers are incorporated as needed to permit thread-safe access
820 to the queue element.
821 @param __list
822 The list on which you want to enqueue the item.
823 @param __offset
824 The "offset" parameter is the offset (in bytes) of the link field
825 from the beginning of the data structure being queued (<code>__new</code>).
826 The link field should be a pointer type.
827 The <code>__offset</code> value needs to be same for all enqueuing and
828 dequeuing operations on the same queue, even if different structure types
829 are enqueued on that queue. The use of <code>offsetset()</code>, defined in
830 <code>stddef.h</code> is the common way to specify the <code>__offset</code>
831 value.
832 @result
833 Returns the oldest enqueued element, or <code>NULL</code> if the
834 list is empty.
835 */
836 __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_NA)
837 void* OSAtomicFifoDequeue( OSFifoQueueHead *__list, size_t __offset);
838
839 #endif /* __i386__ || __x86_64__ */
840
841 /*! @group Memory barriers */
842
843 /*! @abstract Memory barrier.
844 @discussion
845 This function serves as both a read and write barrier.
846 */
847 __OSX_AVAILABLE_STARTING(__MAC_10_4, __IPHONE_2_0)
848 void OSMemoryBarrier( void );
849
850 __END_DECLS
851
852 #endif /* _OSATOMIC_H_ */
853