OLD | NEW |
| (Empty) |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 // This file is an internal atomic implementation, use base/atomicops.h instead. | |
6 | |
7 #ifndef BASE_ATOMICOPS_INTERNALS_MAC_H_ | |
8 #define BASE_ATOMICOPS_INTERNALS_MAC_H_ | |
9 | |
10 #include <libkern/OSAtomic.h> | |
11 | |
12 namespace base { | |
13 namespace subtle { | |
14 | |
15 inline Atomic32 NoBarrier_CompareAndSwap(volatile Atomic32* ptr, | |
16 Atomic32 old_value, | |
17 Atomic32 new_value) { | |
18 Atomic32 prev_value; | |
19 do { | |
20 if (OSAtomicCompareAndSwap32(old_value, new_value, | |
21 const_cast<Atomic32*>(ptr))) { | |
22 return old_value; | |
23 } | |
24 prev_value = *ptr; | |
25 } while (prev_value == old_value); | |
26 return prev_value; | |
27 } | |
28 | |
29 inline Atomic32 NoBarrier_AtomicExchange(volatile Atomic32* ptr, | |
30 Atomic32 new_value) { | |
31 Atomic32 old_value; | |
32 do { | |
33 old_value = *ptr; | |
34 } while (!OSAtomicCompareAndSwap32(old_value, new_value, | |
35 const_cast<Atomic32*>(ptr))); | |
36 return old_value; | |
37 } | |
38 | |
39 inline Atomic32 NoBarrier_AtomicIncrement(volatile Atomic32* ptr, | |
40 Atomic32 increment) { | |
41 return OSAtomicAdd32(increment, const_cast<Atomic32*>(ptr)); | |
42 } | |
43 | |
44 inline Atomic32 Barrier_AtomicIncrement(volatile Atomic32* ptr, | |
45 Atomic32 increment) { | |
46 return OSAtomicAdd32Barrier(increment, const_cast<Atomic32*>(ptr)); | |
47 } | |
48 | |
49 inline void MemoryBarrier() { | |
50 OSMemoryBarrier(); | |
51 } | |
52 | |
53 inline Atomic32 Acquire_CompareAndSwap(volatile Atomic32* ptr, | |
54 Atomic32 old_value, | |
55 Atomic32 new_value) { | |
56 Atomic32 prev_value; | |
57 do { | |
58 if (OSAtomicCompareAndSwap32Barrier(old_value, new_value, | |
59 const_cast<Atomic32*>(ptr))) { | |
60 return old_value; | |
61 } | |
62 prev_value = *ptr; | |
63 } while (prev_value == old_value); | |
64 return prev_value; | |
65 } | |
66 | |
67 inline Atomic32 Release_CompareAndSwap(volatile Atomic32* ptr, | |
68 Atomic32 old_value, | |
69 Atomic32 new_value) { | |
70 return Acquire_CompareAndSwap(ptr, old_value, new_value); | |
71 } | |
72 | |
73 inline void NoBarrier_Store(volatile Atomic32* ptr, Atomic32 value) { | |
74 *ptr = value; | |
75 } | |
76 | |
77 inline void Acquire_Store(volatile Atomic32* ptr, Atomic32 value) { | |
78 *ptr = value; | |
79 MemoryBarrier(); | |
80 } | |
81 | |
82 inline void Release_Store(volatile Atomic32* ptr, Atomic32 value) { | |
83 MemoryBarrier(); | |
84 *ptr = value; | |
85 } | |
86 | |
87 inline Atomic32 NoBarrier_Load(volatile const Atomic32* ptr) { | |
88 return *ptr; | |
89 } | |
90 | |
91 inline Atomic32 Acquire_Load(volatile const Atomic32* ptr) { | |
92 Atomic32 value = *ptr; | |
93 MemoryBarrier(); | |
94 return value; | |
95 } | |
96 | |
97 inline Atomic32 Release_Load(volatile const Atomic32* ptr) { | |
98 MemoryBarrier(); | |
99 return *ptr; | |
100 } | |
101 | |
102 #ifdef __LP64__ | |
103 | |
104 // 64-bit implementation on 64-bit platform | |
105 | |
106 inline Atomic64 NoBarrier_CompareAndSwap(volatile Atomic64* ptr, | |
107 Atomic64 old_value, | |
108 Atomic64 new_value) { | |
109 Atomic64 prev_value; | |
110 do { | |
111 if (OSAtomicCompareAndSwap64(old_value, new_value, | |
112 reinterpret_cast<volatile int64_t*>(ptr))) { | |
113 return old_value; | |
114 } | |
115 prev_value = *ptr; | |
116 } while (prev_value == old_value); | |
117 return prev_value; | |
118 } | |
119 | |
120 inline Atomic64 NoBarrier_AtomicExchange(volatile Atomic64* ptr, | |
121 Atomic64 new_value) { | |
122 Atomic64 old_value; | |
123 do { | |
124 old_value = *ptr; | |
125 } while (!OSAtomicCompareAndSwap64(old_value, new_value, | |
126 reinterpret_cast<volatile int64_t*>(ptr))); | |
127 return old_value; | |
128 } | |
129 | |
130 inline Atomic64 NoBarrier_AtomicIncrement(volatile Atomic64* ptr, | |
131 Atomic64 increment) { | |
132 return OSAtomicAdd64(increment, reinterpret_cast<volatile int64_t*>(ptr)); | |
133 } | |
134 | |
135 inline Atomic64 Barrier_AtomicIncrement(volatile Atomic64* ptr, | |
136 Atomic64 increment) { | |
137 return OSAtomicAdd64Barrier(increment, | |
138 reinterpret_cast<volatile int64_t*>(ptr)); | |
139 } | |
140 | |
141 inline Atomic64 Acquire_CompareAndSwap(volatile Atomic64* ptr, | |
142 Atomic64 old_value, | |
143 Atomic64 new_value) { | |
144 Atomic64 prev_value; | |
145 do { | |
146 if (OSAtomicCompareAndSwap64Barrier( | |
147 old_value, new_value, reinterpret_cast<volatile int64_t*>(ptr))) { | |
148 return old_value; | |
149 } | |
150 prev_value = *ptr; | |
151 } while (prev_value == old_value); | |
152 return prev_value; | |
153 } | |
154 | |
155 inline Atomic64 Release_CompareAndSwap(volatile Atomic64* ptr, | |
156 Atomic64 old_value, | |
157 Atomic64 new_value) { | |
158 // The lib kern interface does not distinguish between | |
159 // Acquire and Release memory barriers; they are equivalent. | |
160 return Acquire_CompareAndSwap(ptr, old_value, new_value); | |
161 } | |
162 | |
163 inline void NoBarrier_Store(volatile Atomic64* ptr, Atomic64 value) { | |
164 *ptr = value; | |
165 } | |
166 | |
167 inline void Acquire_Store(volatile Atomic64* ptr, Atomic64 value) { | |
168 *ptr = value; | |
169 MemoryBarrier(); | |
170 } | |
171 | |
172 inline void Release_Store(volatile Atomic64* ptr, Atomic64 value) { | |
173 MemoryBarrier(); | |
174 *ptr = value; | |
175 } | |
176 | |
177 inline Atomic64 NoBarrier_Load(volatile const Atomic64* ptr) { | |
178 return *ptr; | |
179 } | |
180 | |
181 inline Atomic64 Acquire_Load(volatile const Atomic64* ptr) { | |
182 Atomic64 value = *ptr; | |
183 MemoryBarrier(); | |
184 return value; | |
185 } | |
186 | |
187 inline Atomic64 Release_Load(volatile const Atomic64* ptr) { | |
188 MemoryBarrier(); | |
189 return *ptr; | |
190 } | |
191 | |
192 #endif // defined(__LP64__) | |
193 | |
194 } // namespace subtle | |
195 } // namespace base | |
196 | |
197 #endif // BASE_ATOMICOPS_INTERNALS_MAC_H_ | |
OLD | NEW |