]> git.saurik.com Git - apple/xnu.git/blob - libkern/libkern/OSAtomic.h
19fe32cc4286a5a85fba2a06576a0f98d044a6b7
[apple/xnu.git] / libkern / libkern / OSAtomic.h
1 /*
2 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_OSREFERENCE_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. The rights granted to you under the License
10 * may not be used to create, or enable the creation or redistribution of,
11 * unlawful or unlicensed copies of an Apple operating system, or to
12 * circumvent, violate, or enable the circumvention or violation of, any
13 * terms of an Apple operating system software license agreement.
14 *
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
17 *
18 * The Original Code and all software distributed under the License are
19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23 * Please see the License for the specific language governing rights and
24 * limitations under the License.
25 *
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
27 */
28 /*
29 * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
30 *
31 * HISTORY
32 *
33 */
34
35 #ifndef _OS_OSATOMIC_H
36 #define _OS_OSATOMIC_H
37
38 #include <libkern/OSBase.h>
39
40 #if defined(__cplusplus)
41 extern "C" {
42 #endif
43
44 #if defined(__i386__)
45
46 /*! @function OSCompareAndSwap64
47 @abstract 64-bit compare and swap operation.
48 @discussion See OSCompareAndSwap.
49 */
50 extern Boolean OSCompareAndSwap64(UInt64 oldValue, UInt64 newValue,
51 volatile UInt64 *address);
52
53 /*! @function OSAddAtomic64
54 @abstract 64-bit atomic add operation.
55 @discussion See OSAddAtomic.
56 */
57 extern SInt64 OSAddAtomic64(SInt64 theAmount, volatile SInt64 *address);
58
59 /*! @function OSIncrementAtomic64
60 @abstract 64-bit increment.
61 @discussion See OSIncrementAtomic.
62 */
63 inline static SInt64 OSIncrementAtomic64(volatile SInt64 *address)
64 {
65 return OSAddAtomic64(1, address);
66 }
67
68 /*! @function OSDecrementAtomic64
69 @abstract 64-bit decrement.
70 @discussion See OSDecrementAtomic.
71 */
72 inline static SInt64 OSDecrementAtomic64(volatile SInt64 *address)
73 {
74 return OSAddAtomic64(-1, address);
75 }
76
77 #endif /* defined(__i386__) */
78
79 /*! @function OSCompareAndSwap
80 @abstract Compare and swap operation, performed atomically with respect to all devices that participate in the coherency architecture of the platform.
81 @discussion The OSCompareAndSwap function compares the value at the specified address with oldVal. The value of newValue is written to the address only if oldValue and the value at the address are equal. OSCompareAndSwap returns true if newValue is written to the address; otherwise, it returns false.
82
83 This function guarantees atomicity only with main system memory. It is specifically unsuitable for use on noncacheable memory such as that in devices; this function cannot guarantee atomicity, for example, on memory mapped from a PCI device.
84 @param oldValue The value to compare at address.
85 @param newValue The value to write to address if oldValue compares true.
86 @param address The 4-byte aligned address of the data to update atomically.
87 @result true if newValue was written to the address. */
88
89 extern Boolean OSCompareAndSwap(UInt32 oldValue, UInt32 newValue,
90 volatile UInt32 *address);
91
92 /*! @function OSAddAtomic
93 @abstract 32-bit add operation, performed atomically with respect to all devices that participate in the coherency architecture of the platform.
94 @discussion The OSAddAtomic function adds the specified amount to the value at the specified address and returns the original value.
95
96 This function guarantees atomicity only with main system memory. It is specifically unsuitable for use on noncacheable memory such as that in devices; this function cannot guarantee atomicity, for example, on memory mapped from a PCI device.
97 @param amount The amount to add.
98 @param address The 4-byte aligned address of the value to update atomically.
99 @result The value before the addition */
100
101 extern SInt32 OSAddAtomic(SInt32 amount, volatile SInt32 * address);
102
103 /*! @function OSAddAtomic16
104 @abstract 16-bit add operation, performed atomically with respect to all devices that participate in the coherency architecture of the platform.
105 @discussion The OSAddAtomic16 function adds the specified amount to the value at the specified address and returns the original value.
106
107 This function guarantees atomicity only with main system memory. It is specifically unsuitable for use on noncacheable memory such as that in devices; this function cannot guarantee atomicity, for example, on memory mapped from a PCI device.
108 @param amount The amount to add.
109 @param address The 2-byte aligned address of the value to update atomically.
110 @result The value before the addition */
111
112 extern SInt16 OSAddAtomic16(SInt32 amount, volatile SInt16 * address);
113
114 /*! @function OSAddAtomic8
115 @abstract 8-bit add operation, performed atomically with respect to all devices that participate in the coherency architecture of the platform.
116 @discussion The OSAddAtomic8 function adds the specified amount to the value at the specified address and returns the original value.
117
118 This function guarantees atomicity only with main system memory. It is specifically unsuitable for use on noncacheable memory such as that in devices; this function cannot guarantee atomicity, for example, on memory mapped from a PCI device.
119 @param amount The amount to add.
120 @param address The address of the value to update atomically.
121 @result The value before the addition */
122
123 extern SInt8 OSAddAtomic8(SInt32 amount, volatile SInt8 * address);
124
125 /*! @function OSIncrementAtomic
126 @abstract 32-bit increment operation, performed atomically with respect to all devices that participate in the coherency architecture of the platform.
127 @discussion The OSIncrementAtomic function increments the value at the specified address by one and returns the original value.
128
129 This function guarantees atomicity only with main system memory. It is specifically unsuitable for use on noncacheable memory such as that in devices; this function cannot guarantee atomicity, for example, on memory mapped from a PCI device.
130 @param address The 4-byte aligned address of the value to update atomically.
131 @result The value before the increment. */
132
133 extern SInt32 OSIncrementAtomic(volatile SInt32 * address);
134
135 /*! @function OSIncrementAtomic16
136 @abstract 16-bit increment operation, performed atomically with respect to all devices that participate in the coherency architecture of the platform.
137 @discussion The OSIncrementAtomic16 function increments the value at the specified address by one and returns the original value.
138
139 This function guarantees atomicity only with main system memory. It is specifically unsuitable for use on noncacheable memory such as that in devices; this function cannot guarantee atomicity, for example, on memory mapped from a PCI device.
140 @param address The 2-byte aligned address of the value to update atomically.
141 @result The value before the increment. */
142
143 extern SInt16 OSIncrementAtomic16(volatile SInt16 * address);
144
145 /*! @function OSIncrementAtomic8
146 @abstract 8-bit increment operation, performed atomically with respect to all devices that participate in the coherency architecture of the platform.
147 @discussion The OSIncrementAtomic8 function increments the value at the specified address by one and returns the original value.
148
149 This function guarantees atomicity only with main system memory. It is specifically unsuitable for use on noncacheable memory such as that in devices; this function cannot guarantee atomicity, for example, on memory mapped from a PCI device.
150 @param address The address of the value to update atomically.
151 @result The value before the increment. */
152
153 extern SInt8 OSIncrementAtomic8(volatile SInt8 * address);
154
155 /*! @function OSDecrementAtomic
156 @abstract 32-bit decrement operation, performed atomically with respect to all devices that participate in the coherency architecture of the platform.
157 @discussion The OSDecrementAtomic function decrements the value at the specified address by one and returns the original value.
158
159 This function guarantees atomicity only with main system memory. It is specifically unsuitable for use on noncacheable memory such as that in devices; this function cannot guarantee atomicity, for example, on memory mapped from a PCI device.
160 @param address The 4-byte aligned address of the value to update atomically.
161 @result The value before the decrement. */
162
163 extern SInt32 OSDecrementAtomic(volatile SInt32 * address);
164
165 /*! @function OSDecrementAtomic16
166 @abstract 16-bit decrement operation, performed atomically with respect to all devices that participate in the coherency architecture of the platform.
167 @discussion The OSDecrementAtomic16 function decrements the value at the specified address by one and returns the original value.
168
169 This function guarantees atomicity only with main system memory. It is specifically unsuitable for use on noncacheable memory such as that in devices; this function cannot guarantee atomicity, for example, on memory mapped from a PCI device.
170 @param address The 2-byte aligned address of the value to update atomically.
171 @result The value before the decrement. */
172
173 extern SInt16 OSDecrementAtomic16(volatile SInt16 * address);
174
175 /*! @function OSDecrementAtomic8
176 @abstract 8-bit decrement operation, performed atomically with respect to all devices that participate in the coherency architecture of the platform.
177 @discussion The OSDecrementAtomic8 function decrements the value at the specified address by one and returns the original value.
178
179 This function guarantees atomicity only with main system memory. It is specifically unsuitable for use on noncacheable memory such as that in devices; this function cannot guarantee atomicity, for example, on memory mapped from a PCI device.
180 @param address The address of the value to update atomically.
181 @result The value before the decrement. */
182
183 extern SInt8 OSDecrementAtomic8(volatile SInt8 * address);
184
185 /*! @function OSBitAndAtomic
186 @abstract 32-bit logical and operation, performed atomically with respect to all devices that participate in the coherency architecture of the platform.
187 @discussion The OSBitAndAtomic function logically ands the bits of the specified mask into the value at the specified address and returns the original value.
188
189 This function guarantees atomicity only with main system memory. It is specifically unsuitable for use on noncacheable memory such as that in devices; this function cannot guarantee atomicity, for example, on memory mapped from a PCI device.
190 @param mask The mask to logically and with the value.
191 @param address The 4-byte aligned address of the value to update atomically.
192 @result The value before the bitwise operation */
193
194 extern UInt32 OSBitAndAtomic(UInt32 mask, volatile UInt32 * address);
195
196 /*! @function OSBitAndAtomic16
197 @abstract 16-bit logical and operation, performed atomically with respect to all devices that participate in the coherency architecture of the platform.
198 @discussion The OSBitAndAtomic16 function logically ands the bits of the specified mask into the value at the specified address and returns the original value.
199
200 This function guarantees atomicity only with main system memory. It is specifically unsuitable for use on noncacheable memory such as that in devices; this function cannot guarantee atomicity, for example, on memory mapped from a PCI device.
201 @param mask The mask to logically and with the value.
202 @param address The 2-byte aligned address of the value to update atomically.
203 @result The value before the bitwise operation. */
204
205 extern UInt16 OSBitAndAtomic16(UInt32 mask, volatile UInt16 * address);
206
207 /*! @function OSBitAndAtomic8
208 @abstract 8-bit logical and operation, performed atomically with respect to all devices that participate in the coherency architecture of the platform.
209 @discussion The OSBitAndAtomic8 function logically ands the bits of the specified mask into the value at the specified address and returns the original value.
210
211 This function guarantees atomicity only with main system memory. It is specifically unsuitable for use on noncacheable memory such as that in devices; this function cannot guarantee atomicity, for example, on memory mapped from a PCI device.
212 @param mask The mask to logically and with the value.
213 @param address The address of the value to update atomically.
214 @result The value before the bitwise operation. */
215
216 extern UInt8 OSBitAndAtomic8(UInt32 mask, volatile UInt8 * address);
217
218 /*! @function OSBitOrAtomic
219 @abstract 32-bit logical or operation, performed atomically with respect to all devices that participate in the coherency architecture of the platform.
220 @discussion The OSBitOrAtomic function logically ors the bits of the specified mask into the value at the specified address and returns the original value.
221
222 This function guarantees atomicity only with main system memory. It is specifically unsuitable for use on noncacheable memory such as that in devices; this function cannot guarantee atomicity, for example, on memory mapped from a PCI device.
223 @param mask The mask to logically or with the value.
224 @param address The 4-byte aligned address of the value to update atomically.
225 @result The value before the bitwise operation. */
226
227 extern UInt32 OSBitOrAtomic(UInt32 mask, volatile UInt32 * address);
228
229 /*! @function OSBitOrAtomic16
230 @abstract 16-bit logical or operation, performed atomically with respect to all devices that participate in the coherency architecture of the platform.
231 @discussion The OSBitOrAtomic16 function logically ors the bits of the specified mask into the value at the specified address and returns the original value.
232
233 This function guarantees atomicity only with main system memory. It is specifically unsuitable for use on noncacheable memory such as that in devices; this function cannot guarantee atomicity, for example, on memory mapped from a PCI device.
234 @param mask The mask to logically or with the value.
235 @param address The 2-byte aligned address of the value to update atomically.
236 @result The value before the bitwise operation. */
237
238 extern UInt16 OSBitOrAtomic16(UInt32 mask, volatile UInt16 * address);
239
240 /*! @function OSBitOrAtomic8
241 @abstract 8-bit logical or operation, performed atomically with respect to all devices that participate in the coherency architecture of the platform.
242
243 This function guarantees atomicity only with main system memory. It is specifically unsuitable for use on noncacheable memory such as that in devices; this function cannot guarantee atomicity, for example, on memory mapped from a PCI device.
244 @discussion The OSBitOrAtomic8 function logically ors the bits of the specified mask into the value at the specified address and returns the original value.
245 @param mask The mask to logically or with the value.
246 @param address The address of the value to update atomically.
247 @result The value before the bitwise operation. */
248
249 extern UInt8 OSBitOrAtomic8(UInt32 mask, volatile UInt8 * address);
250
251 /*! @function OSBitXorAtomic
252 @abstract 32-bit logical xor operation, performed atomically with respect to all devices that participate in the coherency architecture of the platform.
253
254 This function guarantees atomicity only with main system memory. It is specifically unsuitable for use on noncacheable memory such as that in devices; this function cannot guarantee atomicity, for example, on memory mapped from a PCI device.
255 @discussion The OSBitXorAtomic function logically xors the bits of the specified mask into the value at the specified address and returns the original value.
256 @param mask The mask to logically or with the value.
257 @param address The 4-byte aligned address of the value to update atomically.
258 @result The value before the bitwise operation. */
259
260 extern UInt32 OSBitXorAtomic(UInt32 mask, volatile UInt32 * address);
261
262 /*! @function OSBitXorAtomic16
263 @abstract 16-bit logical xor operation, performed atomically with respect to all devices that participate in the coherency architecture of the platform.
264 @discussion The OSBitXorAtomic16 function logically xors the bits of the specified mask into the value at the specified address and returns the original value.
265
266 This function guarantees atomicity only with main system memory. It is specifically unsuitable for use on noncacheable memory such as that in devices; this function cannot guarantee atomicity, for example, on memory mapped from a PCI device.
267 @param mask The mask to logically or with the value.
268 @param address The 2-byte aligned address of the value to update atomically.
269 @result The value before the bitwise operation. */
270
271 extern UInt16 OSBitXorAtomic16(UInt32 mask, volatile UInt16 * address);
272
273 /*! @function OSBitXorAtomic8
274 @abstract 8-bit logical xor operation, performed atomically with respect to all devices that participate in the coherency architecture of the platform.
275
276 This function guarantees atomicity only with main system memory. It is specifically unsuitable for use on noncacheable memory such as that in devices; this function cannot guarantee atomicity, for example, on memory mapped from a PCI device.
277 @discussion The OSBitXorAtomic8 function logically xors the bits of the specified mask into the value at the specified address and returns the original value.
278 @param mask The mask to logically or with the value.
279 @param address The address of the value to update atomically.
280 @result The value before the bitwise operation. */
281
282 extern UInt8 OSBitXorAtomic8(UInt32 mask, volatile UInt8 * address);
283
284 /*! @function OSTestAndSet
285 @abstract Bit test and set operation, performed atomically with respect to all devices that participate in the coherency architecture of the platform.
286
287 This function guarantees atomicity only with main system memory. It is specifically unsuitable for use on noncacheable memory such as that in devices; this function cannot guarantee atomicity, for example, on memory mapped from a PCI device.
288 @discussion The OSTestAndSet function sets a single bit in a byte at a specified address. It returns true if the bit was already set, false otherwise.
289 @param bit The bit number in the range 0 through 7.
290 @param address The address of the byte to update atomically.
291 @result true if the bit was already set, false otherwise. */
292
293 extern Boolean OSTestAndSet(UInt32 bit, volatile UInt8 * startAddress);
294
295 /*! @function OSTestAndClear
296 @abstract Bit test and clear operation, performed atomically with respect to all devices that participate in the coherency architecture of the platform.
297 @discussion The OSTestAndClear function clears a single bit in a byte at a specified address. It returns true if the bit was already clear, false otherwise.
298
299 This function guarantees atomicity only with main system memory. It is specifically unsuitable for use on noncacheable memory such as that in devices; this function cannot guarantee atomicity, for example, on memory mapped from a PCI device.
300 @param bit The bit number in the range 0 through 7.
301 @param address The address of the byte to update atomically.
302 @result true if the bit was already clear, false otherwise. */
303
304 extern Boolean OSTestAndClear(UInt32 bit, volatile UInt8 * startAddress);
305
306 #ifdef __ppc__
307 /*! @function OSEnqueueAtomic
308 @abstract Singly linked list head insertion, performed atomically with respect to all devices that participate in the coherency architecture of the platform.
309 @discussion The OSEnqueueAtomic function places an element at the head of a single linked list, which is specified with the address of a head pointer, listHead. The element structure has a next field whose offset is specified.
310
311 This function guarantees atomicity only with main system memory. It is specifically unsuitable for use on noncacheable memory such as that in devices; this function cannot guarantee atomicity, for example, on memory mapped from a PCI device.
312 @param listHead The address of a head pointer for the list .
313 @param element The list element to insert at the head of the list.
314 @param elementNextFieldOffset The byte offset into the element where a pointer to the next element in the list is stored. */
315
316 extern void OSEnqueueAtomic(void * volatile * listHead, void * element,
317 SInt32 elementNextFieldOffset);
318
319 /*! @function OSDequeueAtomic
320 @abstract Singly linked list element head removal, performed atomically with respect to all devices that participate in the coherency architecture of the platform.
321 @discussion The OSDequeueAtomic function removes an element from the head of a single linked list, which is specified with the address of a head pointer, listHead. The element structure has a next field whose offset is specified.
322
323 This function guarantees atomicity only with main system memory. It is specifically unsuitable for use on noncacheable memory such as that in devices; this function cannot guarantee atomicity, for example, on memory mapped from a PCI device.
324 @param listHead The address of a head pointer for the list .
325 @param elementNextFieldOffset The byte offset into the element where a pointer to the next element in the list is stored.
326 @result A removed element, or zero if the list is empty. */
327
328 extern void * OSDequeueAtomic(void * volatile * listHead,
329 SInt32 elementNextFieldOffset);
330 #endif /* __ppc__ */
331
332 /*! @function OSSynchronizeIO
333 @abstract The OSSynchronizeIO routine ensures orderly load and store operations to noncached memory mapped I/O devices.
334 @discussion The OSSynchronizeIO routine ensures orderly load and store operations to noncached memory mapped I/O devices. It executes the eieio instruction on PowerPC processors. */
335
336 #if defined(__arm__) && defined(__thumb__)
337 extern void OSSynchronizeIO(void);
338 #else
339 static __inline__ void OSSynchronizeIO(void)
340 {
341 #if defined(__ppc__)
342 __asm__ ("eieio");
343 #endif
344 #if defined(__arm__)
345 UInt32 temp = 0;
346 __asm__ volatile("mcr p15, 0, %0, c7, c10, 4" : : "r" (temp));
347 #endif
348 }
349 #endif
350
351 #if defined(__cplusplus)
352 }
353 #endif
354
355 #endif /* ! _OS_OSATOMIC_H */