]>
Commit | Line | Data |
---|---|---|
e45b4692 | 1 | .Dd Mar 7, 2016 |
ada7c492 A |
2 | .Dt ATOMIC_DEPRECATED 3 |
3 | .Os Darwin | |
4 | .Sh NAME | |
5 | .Nm OSAtomicAdd32 , | |
6 | .Nm OSAtomicAdd32Barrier , | |
7 | .Nm OSAtomicIncrement32 , | |
8 | .Nm OSAtomicIncrement32Barrier , | |
9 | .Nm OSAtomicDecrement32 , | |
10 | .Nm OSAtomicDecrement32Barrier , | |
11 | .Nm OSAtomicOr32 , | |
12 | .Nm OSAtomicOr32Barrier , | |
13 | .Nm OSAtomicOr32Orig , | |
14 | .Nm OSAtomicOr32OrigBarrier , | |
15 | .Nm OSAtomicAnd32 , | |
16 | .Nm OSAtomicAnd32Barrier , | |
17 | .Nm OSAtomicAnd32Orig , | |
18 | .Nm OSAtomicAnd32OrigBarrier , | |
19 | .Nm OSAtomicXor32 , | |
20 | .Nm OSAtomicXor32Barrier , | |
21 | .Nm OSAtomicXor32Orig , | |
22 | .Nm OSAtomicXor32OrigBarrier , | |
23 | .Nm OSAtomicAdd64 , | |
24 | .Nm OSAtomicAdd64Barrier , | |
25 | .Nm OSAtomicIncrement64 , | |
26 | .Nm OSAtomicIncrement64Barrier , | |
27 | .Nm OSAtomicDecrement64 , | |
28 | .Nm OSAtomicDecrement64Barrier , | |
29 | .Nm OSAtomicCompareAndSwapInt , | |
30 | .Nm OSAtomicCompareAndSwapIntBarrier , | |
31 | .Nm OSAtomicCompareAndSwapLong , | |
32 | .Nm OSAtomicCompareAndSwapLongBarrier , | |
33 | .Nm OSAtomicCompareAndSwapPtr , | |
34 | .Nm OSAtomicCompareAndSwapPtrBarrier , | |
35 | .Nm OSAtomicCompareAndSwap32 , | |
36 | .Nm OSAtomicCompareAndSwap32Barrier , | |
37 | .Nm OSAtomicCompareAndSwap64 , | |
38 | .Nm OSAtomicCompareAndSwap64Barrier , | |
39 | .Nm OSAtomicTestAndSet , | |
40 | .Nm OSAtomicTestAndSetBarrier , | |
41 | .Nm OSAtomicTestAndClear , | |
42 | .Nm OSAtomicTestAndClearBarrier , | |
43 | .Nm OSMemoryBarrier | |
44 | .Nd deprecated atomic add, increment, decrement, or, and, xor, compare and swap, test and set, test and clear, and memory barrier | |
45 | .Sh SYNOPSIS | |
46 | .In libkern/OSAtomic.h | |
47 | .Ft int32_t | |
48 | .Fn OSAtomicAdd32 "int32_t theAmount" "volatile int32_t *theValue" | |
49 | .Ft int32_t | |
50 | .Fn OSAtomicAdd32Barrier "int32_t theAmount" "volatile int32_t *theValue" | |
51 | .Ft int32_t | |
52 | .Fn OSAtomicIncrement32 "volatile int32_t *theValue" | |
53 | .Ft int32_t | |
54 | .Fn OSAtomicIncrement32Barrier "volatile int32_t *theValue" | |
55 | .Ft int32_t | |
56 | .Fn OSAtomicDecrement32 "volatile int32_t *theValue" | |
57 | .Ft int32_t | |
58 | .Fn OSAtomicDecrement32Barrier "volatile int32_t *theValue" | |
59 | .Ft int32_t | |
60 | .Fn OSAtomicOr32 "uint32_t theMask" "volatile uint32_t *theValue" | |
61 | .Ft int32_t | |
62 | .Fn OSAtomicOr32Barrier "uint32_t theMask" "volatile uint32_t *theValue" | |
63 | .Ft int32_t | |
64 | .Fn OSAtomicAnd32 "uint32_t theMask" "volatile uint32_t *theValue" | |
65 | .Ft int32_t | |
66 | .Fn OSAtomicAnd32Barrier "uint32_t theMask" "volatile uint32_t *theValue" | |
67 | .Ft int32_t | |
68 | .Fn OSAtomicXor32 "uint32_t theMask" "volatile uint32_t *theValue" | |
69 | .Ft int32_t | |
70 | .Fn OSAtomicXor32Barrier "uint32_t theMask" "volatile uint32_t *theValue" | |
71 | .Ft int32_t | |
72 | .Fn OSAtomicOr32Orig "uint32_t theMask" "volatile uint32_t *theValue" | |
73 | .Ft int32_t | |
74 | .Fn OSAtomicOr32OrigBarrier "uint32_t theMask" "volatile uint32_t *theValue" | |
75 | .Ft int32_t | |
76 | .Fn OSAtomicAnd32Orig "uint32_t theMask" "volatile uint32_t *theValue" | |
77 | .Ft int32_t | |
78 | .Fn OSAtomicAnd32OrigBarrier "uint32_t theMask" "volatile uint32_t *theValue" | |
79 | .Ft int32_t | |
80 | .Fn OSAtomicXor32Orig "uint32_t theMask" "volatile uint32_t *theValue" | |
81 | .Ft int32_t | |
82 | .Fn OSAtomicXor32OrigBarrier "uint32_t theMask" "volatile uint32_t *theValue" | |
83 | .Ft int64_t | |
84 | .Fn OSAtomicAdd64 "int64_t theAmount" "volatile OSAtomic_int64_aligned64_t *theValue" | |
85 | .Ft int64_t | |
86 | .Fn OSAtomicAdd64Barrier "int64_t theAmount" "volatile OSAtomic_int64_aligned64_t *theValue" | |
87 | .Ft int64_t | |
88 | .Fn OSAtomicIncrement64 "volatile OSAtomic_int64_aligned64_t *theValue" | |
89 | .Ft int64_t | |
90 | .Fn OSAtomicIncrement64Barrier "volatile OSAtomic_int64_aligned64_t *theValue" | |
91 | .Ft int64_t | |
92 | .Fn OSAtomicDecrement64 "volatile OSAtomic_int64_aligned64_t *theValue" | |
93 | .Ft int64_t | |
94 | .Fn OSAtomicDecrement64Barrier "volatile OSAtomic_int64_aligned64_t *theValue" | |
95 | .Ft bool | |
96 | .Fn OSAtomicCompareAndSwapInt "int oldValue" "int newValue" "volatile int *theValue" | |
97 | .Ft bool | |
98 | .Fn OSAtomicCompareAndSwapIntBarrier "int oldValue" "int newValue" "volatile int *theValue" | |
99 | .Ft bool | |
100 | .Fn OSAtomicCompareAndSwapLong "long oldValue" "long newValue" "volatile long *theValue" | |
101 | .Ft bool | |
102 | .Fn OSAtomicCompareAndSwapLongBarrier "long oldValue" "long newValue" "volatile long *theValue" | |
103 | .Ft bool | |
104 | .Fn OSAtomicCompareAndSwapPtr "void* oldValue" "void* newValue" "void* volatile *theValue" | |
105 | .Ft bool | |
106 | .Fn OSAtomicCompareAndSwapPtrBarrier "void* oldValue" "void* newValue" "void* volatile *theValue" | |
107 | .Ft bool | |
108 | .Fn OSAtomicCompareAndSwap32 "int32_t oldValue" "int32_t newValue" "volatile int32_t *theValue" | |
109 | .Ft bool | |
110 | .Fn OSAtomicCompareAndSwap32Barrier "int32_t oldValue" "int32_t newValue" "volatile int32_t *theValue" | |
111 | .Ft bool | |
112 | .Fn OSAtomicCompareAndSwap64 "int64_t oldValue" "int64_t newValue" "volatile OSAtomic_int64_aligned64_t *theValue" | |
113 | .Ft bool | |
114 | .Fn OSAtomicCompareAndSwap64Barrier "int64_t oldValue" "int64_t newValue" "volatile OSAtomic_int64_aligned64_t *theValue" | |
115 | .Ft bool | |
116 | .Fn OSAtomicTestAndSet "uint32_t n" "volatile void *theAddress" | |
117 | .Ft bool | |
118 | .Fn OSAtomicTestAndSetBarrier "uint32_t n" "volatile void *theAddress" | |
119 | .Ft bool | |
120 | .Fn OSAtomicTestAndClear "uint32_t n" "volatile void *theAddress" | |
121 | .Ft bool | |
122 | .Fn OSAtomicTestAndClearBarrier "uint32_t n" "volatile void *theAddress" | |
123 | .Ft bool | |
124 | .Fn OSAtomicEnqueue "OSQueueHead *list" "void *new" "size_t offset" | |
125 | .Ft void* | |
126 | .Fn OSAtomicDequeue "OSQueueHead *list" "size_t offset" | |
127 | .Ft void | |
128 | .Fn OSMemoryBarrier "void" | |
129 | .Sh DESCRIPTION | |
130 | .Bf -symbolic | |
131 | These are deprecated interfaces for atomic and synchronization | |
132 | operations, provided for compatibility with legacy code. New code should use | |
133 | the C11 | |
134 | .In stdatomic.h | |
e45b4692 A |
135 | interfaces described in |
136 | .Xr stdatomic 3 . | |
ada7c492 A |
137 | .Ef |
138 | .Pp | |
139 | These functions are thread and multiprocessor safe. For each function, there | |
140 | is a version which incorporates a memory barrier and another version which does | |
141 | not. | |
142 | Barriers strictly order memory access on a weakly-ordered architecture such as | |
143 | ARM. All loads and stores executed in sequential program | |
144 | order before the barrier will complete before any load or store executed after | |
145 | the barrier. | |
146 | On some platforms, such as ARM, the barrier operation can be quite expensive. | |
147 | .Pp | |
148 | Most code will want to use the barrier functions to ensure that memory shared | |
149 | between threads is properly synchronized. For example, if you want to | |
150 | initialize a shared data structure and then atomically increment a variable to | |
151 | indicate that the initialization is complete, then you must use | |
152 | .Fn OSAtomicIncrement32Barrier | |
153 | to ensure that the stores to your data structure complete before the atomic add. | |
154 | Likewise, the consumer of that data structure must use | |
155 | .Fn OSAtomicDecrement32Barrier , | |
156 | in order to ensure that their loads of the structure are not executed before | |
157 | the atomic decrement. On the other hand, if you are simply incrementing a | |
158 | global counter, then it is safe and potentially much faster to use | |
159 | .Fn OSAtomicIncrement32 . | |
160 | If you are unsure which version to use, prefer the barrier variants as they are | |
161 | safer. | |
162 | .Pp | |
163 | The logical (and, or, xor) and bit test operations are layered on top of the | |
164 | .Fn OSAtomicCompareAndSwap | |
165 | primitives. There are four versions of each logical operation, depending on | |
166 | whether or not there is a barrier, and whether the return value is the result | |
167 | of the operation (eg, | |
168 | .Fn OSAtomicOr32 | |
169 | ) or the original value before the operation (eg, | |
170 | .Fn OSAtomicOr32Orig | |
171 | ). | |
172 | .Pp | |
173 | The memory address | |
174 | .Fa theValue | |
175 | must be "naturally aligned", i.e. 32-bit aligned for 32-bit operations and | |
176 | 64-bit aligned for 64-bit operations. Note that this is not the default alignment | |
177 | of the | |
178 | .Vt int64_t | |
179 | in the iOS ARMv7 ABI, the | |
180 | .Vt OSAtomic_int64_aligned64_t | |
181 | type can be used to declare variables with the required alignment. | |
182 | .Pp | |
183 | The | |
184 | .Fn OSAtomicCompareAndSwap | |
185 | operations compare | |
186 | .Fa oldValue | |
187 | to | |
188 | .Fa *theValue , | |
189 | and set | |
190 | .Fa *theValue | |
191 | to | |
192 | .Fa newValue | |
193 | if the comparison is equal. The comparison and assignment | |
194 | occur as one atomic operation. | |
195 | .Pp | |
196 | .Fn OSAtomicTestAndSet | |
197 | and | |
198 | .Fn OSAtomicTestAndClear | |
199 | operate on bit (0x80 >> ( | |
200 | .Fa n | |
201 | & 7)) of byte ((char*) | |
202 | .Fa theAddress | |
203 | + ( | |
204 | .Fa n | |
205 | >> 3)). They set the named bit to either 1 or 0, respectively. | |
206 | .Fa theAddress | |
207 | need not be aligned. | |
208 | .Pp | |
209 | The | |
210 | .Fn OSMemoryBarrier | |
211 | function strictly orders memory accesses in a weakly ordered memory model such | |
212 | as with ARM, by creating a barrier. | |
213 | All loads and stores executed in sequential program order before the barrier | |
214 | will complete with respect to the memory coherence mechanism, before any load | |
215 | or store executed after the barrier. Used with an atomic operation, the barrier | |
216 | can be used to create custom synchronization protocols as an alternative to the | |
217 | spinlock or queue/dequeue operations. Note that this barrier does not order | |
218 | uncached loads and stores. On a uniprocessor, the barrier operation is | |
219 | typically optimized into a no-op. | |
220 | .Sh RETURN VALUES | |
221 | The arithmetic operations return the new value, after the operation has been | |
222 | performed. The boolean operations come in two styles, one of which returns the | |
223 | new value, and one of which (the "Orig" versions) returns the old. | |
224 | The compare-and-swap operations return true if the comparison was equal, ie if | |
225 | the swap occured. The bit test and set/clear operations return the original | |
226 | value of the bit. | |
227 | .Sh SEE ALSO | |
e45b4692 | 228 | .Xr stdatomic 3 , |
ada7c492 A |
229 | .Xr atomic 3 , |
230 | .Xr spinlock_deprecated 3 | |
231 | .Sh HISTORY | |
232 | Most of these functions first appeared in Mac OS 10.4 (Tiger). The "Orig" | |
233 | forms of the boolean operations, the "int", "long" and "ptr" forms of | |
234 | compare-and-swap first appeared in Mac OS 10.5 (Leopard). |