OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 // For atomic operations on reference counts, see atomic_refcount.h. | 5 // For atomic operations on reference counts, see atomic_refcount.h. |
6 // For atomic operations on sequence numbers, see atomic_sequence_num.h. | 6 // For atomic operations on sequence numbers, see atomic_sequence_num.h. |
7 | 7 |
8 // The routines exported by this module are subtle. If you use them, even if | 8 // The routines exported by this module are subtle. If you use them, even if |
9 // you get the code right, it will depend on careful reasoning about atomicity | 9 // you get the code right, it will depend on careful reasoning about atomicity |
10 // and memory ordering; it will be less readable, and harder to maintain. If | 10 // and memory ordering; it will be less readable, and harder to maintain. If |
(...skipping 10 matching lines...) Expand all Loading... |
21 // versions are provided when no barriers are needed: | 21 // versions are provided when no barriers are needed: |
22 // NoBarrier_Store() | 22 // NoBarrier_Store() |
23 // NoBarrier_Load() | 23 // NoBarrier_Load() |
24 // Although there are currently no compiler enforcement, you are encouraged | 24 // Although there are currently no compiler enforcement, you are encouraged |
25 // to use these. | 25 // to use these. |
26 // | 26 // |
27 | 27 |
28 #ifndef BASE_ATOMICOPS_H_ | 28 #ifndef BASE_ATOMICOPS_H_ |
29 #define BASE_ATOMICOPS_H_ | 29 #define BASE_ATOMICOPS_H_ |
30 | 30 |
| 31 #include <cassert> // Small C++ header which defines implementation specific |
| 32 // macros used to identify the STL implementation. |
31 #include <stdint.h> | 33 #include <stdint.h> |
32 | 34 |
| 35 #include "base/base_export.h" |
33 #include "build/build_config.h" | 36 #include "build/build_config.h" |
34 | 37 |
35 #if defined(OS_WIN) && defined(ARCH_CPU_64_BITS) | 38 #if defined(OS_WIN) && defined(ARCH_CPU_64_BITS) |
36 // windows.h #defines this (only on x64). This causes problems because the | 39 // windows.h #defines this (only on x64). This causes problems because the |
37 // public API also uses MemoryBarrier at the public name for this fence. So, on | 40 // public API also uses MemoryBarrier at the public name for this fence. So, on |
38 // X64, undef it, and call its documented | 41 // X64, undef it, and call its documented |
39 // (http://msdn.microsoft.com/en-us/library/windows/desktop/ms684208.aspx) | 42 // (http://msdn.microsoft.com/en-us/library/windows/desktop/ms684208.aspx) |
40 // implementation directly. | 43 // implementation directly. |
41 #undef MemoryBarrier | 44 #undef MemoryBarrier |
42 #endif | 45 #endif |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
130 void Acquire_Store(volatile Atomic64* ptr, Atomic64 value); | 133 void Acquire_Store(volatile Atomic64* ptr, Atomic64 value); |
131 void Release_Store(volatile Atomic64* ptr, Atomic64 value); | 134 void Release_Store(volatile Atomic64* ptr, Atomic64 value); |
132 Atomic64 NoBarrier_Load(volatile const Atomic64* ptr); | 135 Atomic64 NoBarrier_Load(volatile const Atomic64* ptr); |
133 Atomic64 Acquire_Load(volatile const Atomic64* ptr); | 136 Atomic64 Acquire_Load(volatile const Atomic64* ptr); |
134 Atomic64 Release_Load(volatile const Atomic64* ptr); | 137 Atomic64 Release_Load(volatile const Atomic64* ptr); |
135 #endif // ARCH_CPU_64_BITS | 138 #endif // ARCH_CPU_64_BITS |
136 | 139 |
137 } // namespace subtle | 140 } // namespace subtle |
138 } // namespace base | 141 } // namespace base |
139 | 142 |
140 // Include our platform specific implementation. | 143 // The following x86 CPU features are used in atomicops_internals_x86_gcc.h, but |
141 #if defined(THREAD_SANITIZER) | 144 // this file is duplicated inside of Chrome: protobuf and tcmalloc rely on the |
142 #include "base/atomicops_internals_tsan.h" | 145 // struct being present at link time. Some parts of Chrome can currently use the |
143 #elif defined(OS_WIN) && defined(COMPILER_MSVC) && defined(ARCH_CPU_X86_FAMILY) | 146 // portable interface whereas others still use GCC one. The include guards are |
144 #include "base/atomicops_internals_x86_msvc.h" | 147 // the same as in atomicops_internals_x86_gcc.cc. |
145 #elif defined(OS_MACOSX) | 148 #if defined(__i386__) || defined(__x86_64__) |
146 #include "base/atomicops_internals_mac.h" | 149 // This struct is not part of the public API of this module; clients may not |
147 #elif defined(OS_NACL) | 150 // use it. (However, it's exported via BASE_EXPORT because clients implicitly |
148 #include "base/atomicops_internals_gcc.h" | 151 // do use it at link time by inlining these functions.) |
149 #elif defined(COMPILER_GCC) && defined(ARCH_CPU_ARMEL) | 152 // Features of this x86. Values may not be correct before main() is run, |
150 #include "base/atomicops_internals_arm_gcc.h" | 153 // but are set conservatively. |
151 #elif defined(COMPILER_GCC) && defined(ARCH_CPU_ARM64) | 154 struct AtomicOps_x86CPUFeatureStruct { |
152 #include "base/atomicops_internals_arm64_gcc.h" | 155 bool has_amd_lock_mb_bug; // Processor has AMD memory-barrier bug; do lfence |
153 #elif defined(COMPILER_GCC) && defined(ARCH_CPU_X86_FAMILY) | 156 // after acquire compare-and-swap. |
154 #include "base/atomicops_internals_x86_gcc.h" | 157 // The following fields are unused by Chrome's base implementation but are |
155 #elif defined(COMPILER_GCC) && \ | 158 // still used by copies of the same code in other parts of the code base. This |
156 (defined(ARCH_CPU_MIPS_FAMILY) || defined(ARCH_CPU_MIPS64_FAMILY)) | 159 // causes an ODR violation, and the other code is likely reading invalid |
157 #include "base/atomicops_internals_mips_gcc.h" | 160 // memory. |
158 #else | 161 // TODO(jfb) Delete these fields once the rest of the Chrome code base doesn't |
159 #error "Atomic operations are not supported on your platform" | 162 // depend on them. |
| 163 bool has_sse2; // Processor has SSE2. |
| 164 bool has_cmpxchg16b; // Processor supports cmpxchg16b instruction. |
| 165 }; |
| 166 BASE_EXPORT extern struct AtomicOps_x86CPUFeatureStruct |
| 167 AtomicOps_Internalx86CPUFeatures; |
160 #endif | 168 #endif |
161 | 169 |
| 170 // Try to use a portable implementation based on C++11 atomics. |
| 171 // |
| 172 // Some toolchains support C++11 language features without supporting library |
| 173 // features (recent compiler, older STL). Whitelist libstdc++ and libc++ that we |
| 174 // know will have <atomic> when compiling C++11. |
| 175 #if ((__cplusplus >= 201103L) && \ |
| 176 ((defined(__GLIBCXX__) && (__GLIBCXX__ > 20110216)) || \ |
| 177 (defined(_LIBCPP_VERSION) && (_LIBCPP_STD_VER >= 11)))) |
| 178 # include "base/atomicops_internals_portable.h" |
| 179 #else // Otherwise use a platform specific implementation. |
| 180 # if defined(THREAD_SANITIZER) |
| 181 # error "Thread sanitizer must use the portable atomic operations" |
| 182 # elif (defined(OS_WIN) && defined(COMPILER_MSVC) && \ |
| 183 defined(ARCH_CPU_X86_FAMILY)) |
| 184 # include "base/atomicops_internals_x86_msvc.h" |
| 185 # elif defined(OS_MACOSX) |
| 186 # include "base/atomicops_internals_mac.h" |
| 187 # elif defined(OS_NACL) |
| 188 # include "base/atomicops_internals_gcc.h" |
| 189 # elif defined(COMPILER_GCC) && defined(ARCH_CPU_ARMEL) |
| 190 # include "base/atomicops_internals_arm_gcc.h" |
| 191 # elif defined(COMPILER_GCC) && defined(ARCH_CPU_ARM64) |
| 192 # include "base/atomicops_internals_arm64_gcc.h" |
| 193 # elif defined(COMPILER_GCC) && defined(ARCH_CPU_X86_FAMILY) |
| 194 # include "base/atomicops_internals_x86_gcc.h" |
| 195 # elif (defined(COMPILER_GCC) && \ |
| 196 (defined(ARCH_CPU_MIPS_FAMILY) || defined(ARCH_CPU_MIPS64_FAMILY))) |
| 197 # include "base/atomicops_internals_mips_gcc.h" |
| 198 # else |
| 199 # error "Atomic operations are not supported on your platform" |
| 200 # endif |
| 201 #endif // Portable / non-portable includes. |
| 202 |
162 // On some platforms we need additional declarations to make | 203 // On some platforms we need additional declarations to make |
163 // AtomicWord compatible with our other Atomic* types. | 204 // AtomicWord compatible with our other Atomic* types. |
164 #if defined(OS_MACOSX) || defined(OS_OPENBSD) | 205 #if defined(OS_MACOSX) || defined(OS_OPENBSD) |
165 #include "base/atomicops_internals_atomicword_compat.h" | 206 #include "base/atomicops_internals_atomicword_compat.h" |
166 #endif | 207 #endif |
167 | 208 |
168 #endif // BASE_ATOMICOPS_H_ | 209 #endif // BASE_ATOMICOPS_H_ |
OLD | NEW |