]> git.saurik.com Git - apple/libc.git/blame - sys/atomic.3
Libc-498.1.5.tar.gz
[apple/libc.git] / sys / atomic.3
CommitLineData
59e0d9fe
A
1.Dd May 26, 2004
2.Dt ATOMIC 3
3.Os Darwin
4.Sh NAME
5.Nm OSAtomicAdd32 ,
3d9156a7 6.Nm OSAtomicAdd32Barrier ,
59e0d9fe 7.Nm OSAtomicIncrement32 ,
3d9156a7 8.Nm OSAtomicIncrement32Barrier ,
59e0d9fe 9.Nm OSAtomicDecrement32 ,
3d9156a7 10.Nm OSAtomicDecrement32Barrier ,
59e0d9fe 11.Nm OSAtomicOr32 ,
3d9156a7 12.Nm OSAtomicOr32Barrier ,
224c7076
A
13.Nm OSAtomicOr32Orig ,
14.Nm OSAtomicOr32OrigBarrier ,
59e0d9fe 15.Nm OSAtomicAnd32 ,
3d9156a7 16.Nm OSAtomicAnd32Barrier ,
224c7076
A
17.Nm OSAtomicAnd32Orig ,
18.Nm OSAtomicAnd32OrigBarrier ,
59e0d9fe 19.Nm OSAtomicXor32 ,
3d9156a7 20.Nm OSAtomicXor32Barrier ,
224c7076
A
21.Nm OSAtomicXor32Orig ,
22.Nm OSAtomicXor32OrigBarrier ,
59e0d9fe 23.Nm OSAtomicAdd64 ,
3d9156a7 24.Nm OSAtomicAdd64Barrier ,
59e0d9fe 25.Nm OSAtomicIncrement64 ,
3d9156a7 26.Nm OSAtomicIncrement64Barrier ,
59e0d9fe 27.Nm OSAtomicDecrement64 ,
3d9156a7 28.Nm OSAtomicDecrement64Barrier ,
224c7076
A
29.Nm OSAtomicCompareAndSwapInt ,
30.Nm OSAtomicCompareAndSwapIntBarrier ,
31.Nm OSAtomicCompareAndSwapLong ,
32.Nm OSAtomicCompareAndSwapLongBarrier ,
33.Nm OSAtomicCompareAndSwapPtr ,
34.Nm OSAtomicCompareAndSwapPtrBarrier ,
59e0d9fe 35.Nm OSAtomicCompareAndSwap32 ,
3d9156a7 36.Nm OSAtomicCompareAndSwap32Barrier ,
59e0d9fe 37.Nm OSAtomicCompareAndSwap64 ,
3d9156a7 38.Nm OSAtomicCompareAndSwap64Barrier ,
59e0d9fe 39.Nm OSAtomicTestAndSet ,
3d9156a7
A
40.Nm OSAtomicTestAndSetBarrier ,
41.Nm OSAtomicTestAndClear ,
224c7076
A
42.Nm OSAtomicTestAndClearBarrier ,
43.Nm OSSpinLockTry ,
44.Nm OSSpinLockLock ,
45.Nm OSSpinLockUnlock ,
46.Nm OSAtomicEnqueue ,
47.Nm OSAtomicDequeue
48.Nd atomic add, increment, decrement, or, and, xor, compare and swap, test and set, test and clear, spinlocks, and lockless queues
59e0d9fe
A
49.Sh LIBRARY
50.Lb libc
51.Sh SYNOPSIS
52.In libkern/OSAtomic.h
53.Ft int32_t
224c7076 54.Fn OSAtomicAdd32 "int32_t theAmount" "volatile int32_t *theValue"
59e0d9fe 55.Ft int32_t
224c7076 56.Fn OSAtomicAdd32Barrier "int32_t theAmount" "volatile int32_t *theValue"
3d9156a7 57.Ft int32_t
224c7076 58.Fn OSAtomicIncrement32 "volatile int32_t *theValue"
59e0d9fe 59.Ft int32_t
224c7076 60.Fn OSAtomicIncrement32Barrier "volatile int32_t *theValue"
3d9156a7 61.Ft int32_t
224c7076 62.Fn OSAtomicDecrement32 "volatile int32_t *theValue"
59e0d9fe 63.Ft int32_t
224c7076 64.Fn OSAtomicDecrement32Barrier "volatile int32_t *theValue"
3d9156a7 65.Ft int32_t
224c7076 66.Fn OSAtomicOr32 "uint32_t theMask" "volatile uint32_t *theValue"
59e0d9fe 67.Ft int32_t
224c7076 68.Fn OSAtomicOr32Barrier "uint32_t theMask" "volatile uint32_t *theValue"
3d9156a7 69.Ft int32_t
224c7076 70.Fn OSAtomicAnd32 "uint32_t theMask" "volatile uint32_t *theValue"
59e0d9fe 71.Ft int32_t
224c7076 72.Fn OSAtomicAnd32Barrier "uint32_t theMask" "volatile uint32_t *theValue"
3d9156a7 73.Ft int32_t
224c7076 74.Fn OSAtomicXor32 "uint32_t theMask" "volatile uint32_t *theValue"
3d9156a7 75.Ft int32_t
224c7076
A
76.Fn OSAtomicXor32Barrier "uint32_t theMask" "volatile uint32_t *theValue"
77.Ft int32_t
78.Fn OSAtomicOr32Orig "uint32_t theMask" "volatile uint32_t *theValue"
79.Ft int32_t
80.Fn OSAtomicOr32OrigBarrier "uint32_t theMask" "volatile uint32_t *theValue"
81.Ft int32_t
82.Fn OSAtomicAnd32Orig "uint32_t theMask" "volatile uint32_t *theValue"
83.Ft int32_t
84.Fn OSAtomicAnd32OrigBarrier "uint32_t theMask" "volatile uint32_t *theValue"
85.Ft int32_t
86.Fn OSAtomicXor32Orig "uint32_t theMask" "volatile uint32_t *theValue"
87.Ft int32_t
88.Fn OSAtomicXor32OrigBarrier "uint32_t theMask" "volatile uint32_t *theValue"
59e0d9fe 89.Ft int64_t
224c7076 90.Fn OSAtomicAdd64 "int64_t theAmount" "volatile int64_t *theValue"
59e0d9fe 91.Ft int64_t
224c7076 92.Fn OSAtomicAdd64Barrier "int64_t theAmount" "volatile int64_t *theValue"
3d9156a7 93.Ft int64_t
224c7076 94.Fn OSAtomicIncrement64 "volatile int64_t *theValue"
59e0d9fe 95.Ft int64_t
224c7076 96.Fn OSAtomicIncrement64Barrier "volatile int64_t *theValue"
3d9156a7 97.Ft int64_t
224c7076 98.Fn OSAtomicDecrement64 "volatile int64_t *theValue"
3d9156a7 99.Ft int64_t
224c7076
A
100.Fn OSAtomicDecrement64Barrier "volatile int64_t *theValue"
101.Ft bool
102.Fn OSAtomicCompareAndSwapInt "int oldValue" "int newValue" "volatile int *theValue"
103.Ft bool
104.Fn OSAtomicCompareAndSwapIntBarrier "int oldValue" "int newValue" "volatile int *theValue"
105.Ft bool
106.Fn OSAtomicCompareAndSwapLong "long oldValue" "long newValue" "volatile long *theValue"
59e0d9fe 107.Ft bool
224c7076 108.Fn OSAtomicCompareAndSwapLongBarrier "long oldValue" "long newValue" "volatile long *theValue"
59e0d9fe 109.Ft bool
224c7076 110.Fn OSAtomicCompareAndSwapPtr "void* oldValue" "void* newValue" "void* volatile *theValue"
3d9156a7 111.Ft bool
224c7076 112.Fn OSAtomicCompareAndSwapPtrBarrier "void* oldValue" "void* newValue" "void* volatile *theValue"
59e0d9fe 113.Ft bool
224c7076 114.Fn OSAtomicCompareAndSwap32 "int32_t oldValue" "int32_t newValue" "volatile int32_t *theValue"
3d9156a7 115.Ft bool
224c7076 116.Fn OSAtomicCompareAndSwap32Barrier "int32_t oldValue" "int32_t newValue" "volatile int32_t *theValue"
59e0d9fe 117.Ft bool
224c7076 118.Fn OSAtomicCompareAndSwap64 "int64_t oldValue" "int64_t newValue" "volatile int64_t *theValue"
3d9156a7 119.Ft bool
224c7076 120.Fn OSAtomicCompareAndSwap64Barrier "int64_t oldValue" "int64_t newValue" "volatile int64_t *theValue"
3d9156a7 121.Ft bool
224c7076
A
122.Fn OSAtomicTestAndSet "uint32_t n" "volatile void *theAddress"
123.Ft bool
124.Fn OSAtomicTestAndSetBarrier "uint32_t n" "volatile void *theAddress"
125.Ft bool
126.Fn OSAtomicTestAndClear "uint32_t n" "volatile void *theAddress"
127.Ft bool
128.Fn OSAtomicTestAndClearBarrier "uint32_t n" "volatile void *theAddress"
129.Ft bool
130.Fn OSSpinLockTry "OSSpinLock *lock"
131.Ft void
132.Fn OSSpinLockLock "OSSpinLock *lock"
133.Ft void
134.Fn OSSpinLockUnlock "OSSpinLock *lock"
135.Ft void
136.Fn OSAtomicEnqueue "OSQueueHead *list" "void *new" "size_t offset"
137.Ft void*
138.Fn OSAtomicDequeue "OSQueueHead *list" "size_t offset"
59e0d9fe 139.Sh DESCRIPTION
3d9156a7 140These functions are thread and multiprocessor safe. For each function, there
224c7076 141is a version that does and another that does not incorporate a memory barrier.
3d9156a7
A
142Barriers strictly order memory access on a weakly-ordered
143architecture such as PPC. All loads and stores executed in sequential program
144order before the barrier will complete before any load or store executed after
145the barrier. On a uniprocessor, the barrier operation is typically a nop.
146On a multiprocessor, the barrier can be quite expensive.
147.Pp
148Most code will want to use the barrier functions to insure that memory shared
149between threads is properly synchronized. For example, if you want to initialize
150a shared data structure and then atomically increment a variable to indicate
224c7076 151that the initialization is complete, then you must use OSAtomicIncrement32Barrier()
3d9156a7 152to ensure that the stores to your data structure complete before the atomic add.
224c7076 153Likewise, the consumer of that data structure must use OSAtomicDecrement32Barrier(),
3d9156a7
A
154in order to ensure that their loads of the structure are not executed before
155the atomic decrement. On the other hand,
156if you are simply incrementing a global counter, then it is safe and potentially much
157faster to use OSAtomicIncrement32(). If you are unsure which version to use, prefer
158the barrier variants as they are safer.
159.Pp
160The logical (and, or, xor) and bit test operations are layered on top of the
59e0d9fe 161.Fn OSAtomicCompareAndSwap
224c7076
A
162primitives. There are four versions of each logical operation, depending on whether
163or not there is a barrier, and whether the return value is the result of the
164operation (eg,
165.Fn OSAtomicOr32
166) or the original value before the operation (eg,
167.Fn OSAtomicOr32Orig
168).
3d9156a7
A
169.Pp
170The memory address
59e0d9fe
A
171.Fa theValue
172must be naturally aligned, ie 32-bit aligned for 32-bit operations and 64-bit
3d9156a7
A
173aligned for 64-bit operations.
174.Pp
224c7076 175The 64-bit operations are not implemented for 32-bit processes on PPC platforms.
59e0d9fe 176.Pp
224c7076
A
177The
178.Fn OSAtomicCompareAndSwap
179operations compare
59e0d9fe
A
180.Fa oldValue
181to
182.Fa *theValue ,
183and set
184.Fa *theValue
185to
186.Fa newValue
187if the comparison is equal. The comparison and assignment
188occur as one atomic operation.
189.Pp
190.Fn OSAtomicTestAndSet
191and
192.Fn OSAtomicTestAndClear
193operate on bit (0x80 >> (
194.Fa n
195& 7)) of byte ((char*)
196.Fa theAddress
197+ (
198.Fa n
199>> 3)). They set the named bit to either 1 or 0, respectively.
200.Fa theAddress
201need not be aligned.
224c7076
A
202.Pp
203The routines
204.Fn OSAtomicEnqueue
205and
206.Fn OSAtomicDequeue
207operate on singly linked LIFO queues. Ie, a dequeue operation will return the
208most recently enqueued element, or NULL if the list is empty. The operations
209are lockless, and barriers are used as necessary to permit thread-safe access to
210the queue element.
211.Fa offset
212is the offset in bytes to the link field in the queue element. For example:
213.Bd -literal -offset indent
214 typedef struct elem {
215 long data1;
216 struct elem *link;
217 int data2;
218 } elem_t;
219
220 elem_t fred, mary, *p;
221
222 OSQueueHead q = OS_ATOMIC_QUEUE_INIT;
223
224 OSAtomicEnqueue( &q, &fred, offsetof(elem_t,link) );
225 OSAtomicEnqueue( &q, &mary, offsetof(elem_t,link) );
226
227 p = OSAtomicDequeue( &q, offsetof(elem_t,link) );
228
229.Ed
230In this example, the call of
231.Fn OSAtomicDequeue
232will return a ptr to mary.
59e0d9fe 233.Sh RETURN VALUES
224c7076
A
234The arithmetic operations return the new value, after the operation has been performed.
235The boolean operations come in two styles, one of which returns the new value, and one
236of which (the "Orig" versions) returns the old.
59e0d9fe
A
237The compare-and-swap operations return true if the comparison was equal, ie if the swap occured.
238The bit test and set/clear operations return the original value of the bit.
224c7076 239The dequeue operation returns the most recently enqueued element, or NULL if the list in empty.
59e0d9fe 240.Sh SEE ALSO
59e0d9fe
A
241.Xr spinlock 3 ,
242.Xr barrier 3
224c7076
A
243.Sh HISTORY
244Most of these functions first appeared in Mac OS 10.4 (Tiger). The "Orig" forms of the
245boolean operations, the "int", "long" and "ptr" forms of compare-and-swap, and lockless
246enqueue/dequeue first appeared in Mac OS 10.5 (Leopard).