| 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 | 
|---|