Chameleon

Chameleon Svn Source Tree

Root/branches/cparm/i386/modules/include/libkern/OSAtomic.h

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

Archive Download this file

Revision: 2182