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