2 * Copyright (c) 2011 Apple Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
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
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.
21 * @APPLE_LICENSE_HEADER_END@
24 // OSAtomic.h is included by files that include this C file.
25 /* #include "OSAtomic.h" */
27 int32_t OSAtomicAdd32(int32_t v
, volatile int32_t *p
) _OSATOMIC_VARIANT_B(OSAtomicAdd32
);
28 int32_t OSAtomicAdd32(int32_t v
, volatile int32_t *p
)
30 _OSATOMIC_ALIAS_NB(OSAtomicAdd32
);
34 _osatomic_store_barrier();
36 _osatomic_load_exclusive(p
, r
);
38 _osatomic_store_exclusive(p
, r
, t
);
39 } while (slowpath(t
));
45 int64_t OSAtomicAdd64(int64_t v
, volatile int64_t *p
) _OSATOMIC_VARIANT_B(OSAtomicAdd64
);
46 int64_t OSAtomicAdd64(int64_t v
, volatile int64_t *p
)
48 _OSATOMIC_ALIAS_NB(OSAtomicAdd64
);
53 _osatomic_store_barrier();
55 _osatomic_load_exclusive64(p
, r
);
57 _osatomic_store_exclusive64(p
, r
, t
);
58 } while (slowpath(t
));
64 int32_t OSAtomicOr32(int32_t v
, volatile int32_t *p
) _OSATOMIC_VARIANT_B(OSAtomicOr32
);
65 int32_t OSAtomicOr32(int32_t v
, volatile int32_t *p
)
67 _OSATOMIC_ALIAS_NB(OSAtomicOr32
);
71 _osatomic_store_barrier();
73 _osatomic_load_exclusive(p
, r
);
75 _osatomic_store_exclusive(p
, r
, t
);
76 } while (slowpath(t
));
82 int32_t OSAtomicOr32Orig(int32_t v
, volatile int32_t *p
) _OSATOMIC_VARIANT_B(OSAtomicOr32Orig
);
83 int32_t OSAtomicOr32Orig(int32_t v
, volatile int32_t *p
)
85 _OSATOMIC_ALIAS_NB(OSAtomicOr32Orig
);
89 _osatomic_store_barrier();
91 _osatomic_load_exclusive(p
, r
);
93 _osatomic_store_exclusive(p
, n
, t
);
94 } while (slowpath(t
));
100 int32_t OSAtomicAnd32(int32_t v
, volatile int32_t *p
) _OSATOMIC_VARIANT_B(OSAtomicAnd32
);
101 int32_t OSAtomicAnd32(int32_t v
, volatile int32_t *p
)
103 _OSATOMIC_ALIAS_NB(OSAtomicAnd32
);
107 _osatomic_store_barrier();
109 _osatomic_load_exclusive(p
, r
);
111 _osatomic_store_exclusive(p
, r
, t
);
112 } while (slowpath(t
));
118 int32_t OSAtomicAnd32Orig(int32_t v
, volatile int32_t *p
) _OSATOMIC_VARIANT_B(OSAtomicAnd32Orig
);
119 int32_t OSAtomicAnd32Orig(int32_t v
, volatile int32_t *p
)
121 _OSATOMIC_ALIAS_NB(OSAtomicAnd32Orig
);
125 _osatomic_store_barrier();
127 _osatomic_load_exclusive(p
, r
);
129 _osatomic_store_exclusive(p
, n
, t
);
130 } while (slowpath(t
));
136 int32_t OSAtomicXor32(int32_t v
, volatile int32_t *p
) _OSATOMIC_VARIANT_B(OSAtomicXor32
);
137 int32_t OSAtomicXor32(int32_t v
, volatile int32_t *p
)
139 _OSATOMIC_ALIAS_NB(OSAtomicXor32
);
143 _osatomic_store_barrier();
145 _osatomic_load_exclusive(p
, r
);
147 _osatomic_store_exclusive(p
, r
, t
);
148 } while (slowpath(t
));
154 int32_t OSAtomicXor32Orig(int32_t v
, volatile int32_t *p
) _OSATOMIC_VARIANT_B(OSAtomicXor32Orig
);
155 int32_t OSAtomicXor32Orig(int32_t v
, volatile int32_t *p
)
157 _OSATOMIC_ALIAS_NB(OSAtomicXor32Orig
);
161 _osatomic_store_barrier();
163 _osatomic_load_exclusive(p
, r
);
165 _osatomic_store_exclusive(p
, n
, t
);
166 } while (slowpath(t
));
172 bool OSAtomicCompareAndSwap32(int32_t o
, int32_t n
, volatile int32_t *p
) _OSATOMIC_VARIANT_B(OSAtomicCompareAndSwap32
);
173 bool OSAtomicCompareAndSwap32(int32_t o
, int32_t n
, volatile int32_t *p
)
175 _OSATOMIC_ALIAS_B(OSAtomicCompareAndSwapInt
, OSAtomicCompareAndSwap32
);
177 _OSATOMIC_ALIAS_NB(OSAtomicCompareAndSwap32
);
178 _OSATOMIC_ALIAS_NB(OSAtomicCompareAndSwapInt
);
180 _OSATOMIC_ALIAS_B(OSAtomicCompareAndSwapLong
, OSAtomicCompareAndSwap32
);
181 _OSATOMIC_ALIAS_B(OSAtomicCompareAndSwapPtr
, OSAtomicCompareAndSwap32
);
182 _OSATOMIC_ALIAS_NB(OSAtomicCompareAndSwapLong
);
183 _OSATOMIC_ALIAS_NB(OSAtomicCompareAndSwapPtr
);
190 _osatomic_load_exclusive(p
, r
);
191 if (r
!= o
) return false;
192 _osatomic_store_barrier();
193 _osatomic_store_exclusive(p
, n
, t
);
194 } while (slowpath(t
));
200 bool OSAtomicCompareAndSwap64(int64_t o
, int64_t n
, volatile int64_t *p
) _OSATOMIC_VARIANT_B(OSAtomicCompareAndSwap64
);
201 bool OSAtomicCompareAndSwap64(int64_t o
, int64_t n
, volatile int64_t *p
)
203 _OSATOMIC_ALIAS_NB(OSAtomicCompareAndSwap64
);
205 _OSATOMIC_ALIAS_B(OSAtomicCompareAndSwapLong
, OSAtomicCompareAndSwap64
);
206 _OSATOMIC_ALIAS_B(OSAtomicCompareAndSwapPtr
, OSAtomicCompareAndSwap64
);
207 _OSATOMIC_ALIAS_NB(OSAtomicCompareAndSwapLong
);
208 _OSATOMIC_ALIAS_NB(OSAtomicCompareAndSwapPtr
);
215 _osatomic_load_exclusive64(p
, r
);
216 if (r
!= o
) return false;
217 _osatomic_store_barrier();
218 _osatomic_store_exclusive64(p
, n
, t
);
219 } while (slowpath(t
));
225 #if defined(_OSATOMIC_EXTRAS)
227 void OSMemoryBarrier(void) _OSATOMIC_VARIANT(OSMemoryBarrier
);
228 void OSMemoryBarrier(void)
233 typedef volatile struct {
238 void OSAtomicEnqueue(OSQueueHead
*l
, void *n
, size_t o
) _OSATOMIC_VARIANT(OSAtomicEnqueue
);
239 void OSAtomicEnqueue(OSQueueHead
*l
, void *n
, size_t o
)
241 void ** r
= (void **)((char *)n
+ o
);
242 void * volatile * i
= (void **)&(l
->item
);
246 _osatomic_store_barrier();
248 _osatomic_load_exclusive(i
, q
);
250 _osatomic_store_exclusive(i
, n
, t
);
251 } while (slowpath(t
));
255 void* OSAtomicDequeue(OSQueueHead
*l
, size_t o
) _OSATOMIC_VARIANT(OSAtomicDequeue
);
256 void* OSAtomicDequeue(OSQueueHead
*l
, size_t o
)
260 void * volatile * i
= (void **)&(l
->item
);
263 _osatomic_store_barrier();
265 _osatomic_load_exclusive(i
, r
);
267 h
= *(void **)((char *)r
+ o
);
268 _osatomic_store_exclusive(i
, h
, t
);
269 } while (slowpath(t
));
277 bool OSAtomicTestAndSet(uint32_t n
, volatile void * p
) _OSATOMIC_VARIANT_B(OSAtomicTestAndSet
);
278 bool OSAtomicTestAndSet(uint32_t n
, volatile void * p
)
280 _OSATOMIC_ALIAS_NB(OSAtomicTestAndSet
);
281 uint32_t * ptr
= (uint32_t *)((char *)p
+ (4 * (n
/ 32)));
284 n
= (0x80 >> (n
& 7)) << (n
& ~7 & 31);
286 _osatomic_store_barrier();
288 _osatomic_load_exclusive(ptr
, r
);
291 _osatomic_store_exclusive(ptr
, i
, t
);
292 } while (slowpath(t
));
295 return ((r
& n
) != 0);
298 bool OSAtomicTestAndClear(uint32_t n
, volatile void * p
) _OSATOMIC_VARIANT_B(OSAtomicTestAndClear
);
299 bool OSAtomicTestAndClear(uint32_t n
, volatile void * p
)
301 _OSATOMIC_ALIAS_NB(OSAtomicTestAndClear
);
302 uint32_t * ptr
= (uint32_t *)((char *)p
+ (4 * (n
/ 32)));
305 n
= (0x80 >> (n
& 7)) << (n
& ~7 & 31);
307 _osatomic_store_barrier();
309 _osatomic_load_exclusive(ptr
, r
);
312 _osatomic_store_exclusive(ptr
, i
, t
);
313 } while (slowpath(t
));
316 return ((r
& n
) != 0);