xref: /NextBSD/include/libkern/OSAtomic.h (revision 33da5adc555b3bc29986eeadca03829e4ad06b1e)
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