Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2010 the V8 project authors. All rights reserved. | 1 // Copyright 2010 the V8 project 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 // The routines exported by this module are subtle. If you use them, even if | 5 // The routines exported by this module are subtle. If you use them, even if |
| 6 // you get the code right, it will depend on careful reasoning about atomicity | 6 // you get the code right, it will depend on careful reasoning about atomicity |
| 7 // and memory ordering; it will be less readable, and harder to maintain. If | 7 // and memory ordering; it will be less readable, and harder to maintain. If |
| 8 // you plan to use these routines, you should have a good reason, such as solid | 8 // you plan to use these routines, you should have a good reason, such as solid |
| 9 // evidence that performance would otherwise suffer, or there being no | 9 // evidence that performance would otherwise suffer, or there being no |
| 10 // alternative. You should assume only properties explicitly guaranteed by the | 10 // alternative. You should assume only properties explicitly guaranteed by the |
| 11 // specifications in this file. You are almost certainly _not_ writing code | 11 // specifications in this file. You are almost certainly _not_ writing code |
| 12 // just for the x86; if you assume x86 semantics, x86 hardware bugs and | 12 // just for the x86; if you assume x86 semantics, x86 hardware bugs and |
| 13 // implementations on other archtectures will cause your code to break. If you | 13 // implementations on other archtectures will cause your code to break. If you |
| 14 // do not know what you are doing, avoid these routines, and use a Mutex. | 14 // do not know what you are doing, avoid these routines, and use a Mutex. |
| 15 // | 15 // |
| 16 // It is incorrect to make direct assignments to/from an atomic variable. | 16 // It is incorrect to make direct assignments to/from an atomic variable. |
| 17 // You should use one of the Load or Store routines. The NoBarrier | 17 // You should use one of the Load or Store routines. The Relaxed versions |
| 18 // versions are provided when no barriers are needed: | 18 // are provided when no fences are needed: |
| 19 // NoBarrier_Store() | 19 // Relaxed_Store() |
| 20 // NoBarrier_Load() | 20 // Relaxed_Load() |
| 21 // Although there are currently no compiler enforcement, you are encouraged | 21 // Although there are currently no compiler enforcement, you are encouraged |
| 22 // to use these. | 22 // to use these. |
| 23 // | 23 // |
| 24 | 24 |
| 25 #ifndef V8_BASE_ATOMICOPS_H_ | 25 #ifndef V8_BASE_ATOMICOPS_H_ |
| 26 #define V8_BASE_ATOMICOPS_H_ | 26 #define V8_BASE_ATOMICOPS_H_ |
| 27 | 27 |
| 28 #include <stdint.h> | 28 #include <stdint.h> |
| 29 | 29 |
| 30 // Small C++ header which defines implementation specific macros used to | 30 // Small C++ header which defines implementation specific macros used to |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 67 // Atomically execute: | 67 // Atomically execute: |
| 68 // result = *ptr; | 68 // result = *ptr; |
| 69 // if (*ptr == old_value) | 69 // if (*ptr == old_value) |
| 70 // *ptr = new_value; | 70 // *ptr = new_value; |
| 71 // return result; | 71 // return result; |
| 72 // | 72 // |
| 73 // I.e., replace "*ptr" with "new_value" if "*ptr" used to be "old_value". | 73 // I.e., replace "*ptr" with "new_value" if "*ptr" used to be "old_value". |
| 74 // Always return the old value of "*ptr" | 74 // Always return the old value of "*ptr" |
| 75 // | 75 // |
| 76 // This routine implies no memory barriers. | 76 // This routine implies no memory barriers. |
| 77 Atomic32 NoBarrier_CompareAndSwap(volatile Atomic32* ptr, | 77 Atomic32 Relaxed_CompareAndSwap(volatile Atomic32* ptr, Atomic32 old_value, |
| 78 Atomic32 old_value, | 78 Atomic32 new_value); |
| 79 Atomic32 new_value); | |
| 80 | 79 |
| 81 // Atomically store new_value into *ptr, returning the previous value held in | 80 // Atomically store new_value into *ptr, returning the previous value held in |
| 82 // *ptr. This routine implies no memory barriers. | 81 // *ptr. This routine implies no memory barriers. |
| 83 Atomic32 NoBarrier_AtomicExchange(volatile Atomic32* ptr, Atomic32 new_value); | 82 Atomic32 Relaxed_AtomicExchange(volatile Atomic32* ptr, Atomic32 new_value); |
| 84 | 83 |
| 85 // Atomically increment *ptr by "increment". Returns the new value of | 84 // Atomically increment *ptr by "increment". Returns the new value of |
| 86 // *ptr with the increment applied. This routine implies no memory barriers. | 85 // *ptr with the increment applied. This routine implies no memory barriers. |
| 87 Atomic32 NoBarrier_AtomicIncrement(volatile Atomic32* ptr, Atomic32 increment); | 86 Atomic32 Relaxed_AtomicIncrement(volatile Atomic32* ptr, Atomic32 increment); |
| 88 | 87 |
| 89 Atomic32 Barrier_AtomicIncrement(volatile Atomic32* ptr, | 88 Atomic32 Barrier_AtomicIncrement(volatile Atomic32* ptr, |
| 90 Atomic32 increment); | 89 Atomic32 increment); |
| 91 | 90 |
| 92 // These following lower-level operations are typically useful only to people | 91 // These following lower-level operations are typically useful only to people |
| 93 // implementing higher-level synchronization operations like spinlocks, | 92 // implementing higher-level synchronization operations like spinlocks, |
| 94 // mutexes, and condition-variables. They combine CompareAndSwap(), a load, or | 93 // mutexes, and condition-variables. They combine CompareAndSwap(), a load, or |
| 95 // a store with appropriate memory-ordering instructions. "Acquire" operations | 94 // a store with appropriate memory-ordering instructions. "Acquire" operations |
| 96 // ensure that no later memory access can be reordered ahead of the operation. | 95 // ensure that no later memory access can be reordered ahead of the operation. |
| 97 // "Release" operations ensure that no previous memory access can be reordered | 96 // "Release" operations ensure that no previous memory access can be reordered |
| 98 // after the operation. "Barrier" operations have both "Acquire" and "Release" | 97 // after the operation. "Barrier" operations have both "Acquire" and "Release" |
| 99 // semantics. A MemoryBarrier() has "Barrier" semantics, but does no memory | 98 // semantics. A MemoryBarrier() has "Barrier" semantics, but does no memory |
| 100 // access. | 99 // access. |
| 101 Atomic32 Acquire_CompareAndSwap(volatile Atomic32* ptr, | 100 Atomic32 Acquire_CompareAndSwap(volatile Atomic32* ptr, |
| 102 Atomic32 old_value, | 101 Atomic32 old_value, |
| 103 Atomic32 new_value); | 102 Atomic32 new_value); |
| 104 Atomic32 Release_CompareAndSwap(volatile Atomic32* ptr, | 103 Atomic32 Release_CompareAndSwap(volatile Atomic32* ptr, |
| 105 Atomic32 old_value, | 104 Atomic32 old_value, |
| 106 Atomic32 new_value); | 105 Atomic32 new_value); |
| 107 | 106 |
| 108 void MemoryBarrier(); | 107 void MemoryBarrier(); |
|
ulan
2017/05/29 13:08:20
I will rename this in another CL.
| |
| 109 void NoBarrier_Store(volatile Atomic8* ptr, Atomic8 value); | 108 void Relaxed_Store(volatile Atomic8* ptr, Atomic8 value); |
| 110 void NoBarrier_Store(volatile Atomic32* ptr, Atomic32 value); | 109 void Relaxed_Store(volatile Atomic32* ptr, Atomic32 value); |
| 111 void Release_Store(volatile Atomic32* ptr, Atomic32 value); | 110 void Release_Store(volatile Atomic32* ptr, Atomic32 value); |
| 112 | 111 |
| 113 Atomic8 NoBarrier_Load(volatile const Atomic8* ptr); | 112 Atomic8 Relaxed_Load(volatile const Atomic8* ptr); |
| 114 Atomic32 NoBarrier_Load(volatile const Atomic32* ptr); | 113 Atomic32 Relaxed_Load(volatile const Atomic32* ptr); |
| 115 Atomic32 Acquire_Load(volatile const Atomic32* ptr); | 114 Atomic32 Acquire_Load(volatile const Atomic32* ptr); |
| 116 | 115 |
| 117 // 64-bit atomic operations (only available on 64-bit processors). | 116 // 64-bit atomic operations (only available on 64-bit processors). |
| 118 #ifdef V8_HOST_ARCH_64_BIT | 117 #ifdef V8_HOST_ARCH_64_BIT |
| 119 Atomic64 NoBarrier_CompareAndSwap(volatile Atomic64* ptr, | 118 Atomic64 Relaxed_CompareAndSwap(volatile Atomic64* ptr, Atomic64 old_value, |
| 120 Atomic64 old_value, | 119 Atomic64 new_value); |
| 121 Atomic64 new_value); | 120 Atomic64 Relaxed_AtomicExchange(volatile Atomic64* ptr, Atomic64 new_value); |
| 122 Atomic64 NoBarrier_AtomicExchange(volatile Atomic64* ptr, Atomic64 new_value); | 121 Atomic64 Relaxed_AtomicIncrement(volatile Atomic64* ptr, Atomic64 increment); |
| 123 Atomic64 NoBarrier_AtomicIncrement(volatile Atomic64* ptr, Atomic64 increment); | |
| 124 Atomic64 Barrier_AtomicIncrement(volatile Atomic64* ptr, Atomic64 increment); | 122 Atomic64 Barrier_AtomicIncrement(volatile Atomic64* ptr, Atomic64 increment); |
|
ulan
2017/05/29 13:08:20
I will rename this in another CL.
| |
| 125 | 123 |
| 126 Atomic64 Acquire_CompareAndSwap(volatile Atomic64* ptr, | 124 Atomic64 Acquire_CompareAndSwap(volatile Atomic64* ptr, |
| 127 Atomic64 old_value, | 125 Atomic64 old_value, |
| 128 Atomic64 new_value); | 126 Atomic64 new_value); |
| 129 Atomic64 Release_CompareAndSwap(volatile Atomic64* ptr, | 127 Atomic64 Release_CompareAndSwap(volatile Atomic64* ptr, |
| 130 Atomic64 old_value, | 128 Atomic64 old_value, |
| 131 Atomic64 new_value); | 129 Atomic64 new_value); |
| 132 void NoBarrier_Store(volatile Atomic64* ptr, Atomic64 value); | 130 void Relaxed_Store(volatile Atomic64* ptr, Atomic64 value); |
| 133 void Release_Store(volatile Atomic64* ptr, Atomic64 value); | 131 void Release_Store(volatile Atomic64* ptr, Atomic64 value); |
| 134 Atomic64 NoBarrier_Load(volatile const Atomic64* ptr); | 132 Atomic64 Relaxed_Load(volatile const Atomic64* ptr); |
| 135 Atomic64 Acquire_Load(volatile const Atomic64* ptr); | 133 Atomic64 Acquire_Load(volatile const Atomic64* ptr); |
| 136 #endif // V8_HOST_ARCH_64_BIT | 134 #endif // V8_HOST_ARCH_64_BIT |
| 137 | 135 |
| 138 } // namespace base | 136 } // namespace base |
| 139 } // namespace v8 | 137 } // namespace v8 |
| 140 | 138 |
| 141 #if defined(V8_OS_WIN) | 139 #if defined(V8_OS_WIN) |
| 142 // TODO(hpayer): The MSVC header includes windows.h, which other files end up | 140 // TODO(hpayer): The MSVC header includes windows.h, which other files end up |
| 143 // relying on. Fix this as part of crbug.com/559247. | 141 // relying on. Fix this as part of crbug.com/559247. |
| 144 #include "src/base/atomicops_internals_x86_msvc.h" | 142 #include "src/base/atomicops_internals_x86_msvc.h" |
| 145 #else | 143 #else |
| 146 #include "src/base/atomicops_internals_portable.h" | 144 #include "src/base/atomicops_internals_portable.h" |
| 147 #endif | 145 #endif |
| 148 | 146 |
| 149 // On some platforms we need additional declarations to make | 147 // On some platforms we need additional declarations to make |
| 150 // AtomicWord compatible with our other Atomic* types. | 148 // AtomicWord compatible with our other Atomic* types. |
| 151 #if defined(V8_OS_MACOSX) || defined(V8_OS_OPENBSD) || defined(V8_OS_AIX) | 149 #if defined(V8_OS_MACOSX) || defined(V8_OS_OPENBSD) || defined(V8_OS_AIX) |
| 152 #include "src/base/atomicops_internals_atomicword_compat.h" | 150 #include "src/base/atomicops_internals_atomicword_compat.h" |
| 153 #endif | 151 #endif |
| 154 | 152 |
| 155 #endif // V8_BASE_ATOMICOPS_H_ | 153 #endif // V8_BASE_ATOMICOPS_H_ |
| OLD | NEW |