/src/brpc/src/butil/atomicops.h
Line | Count | Source (jump to first uncovered line) |
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 | | // For atomic operations on reference counts, see atomic_refcount.h. |
6 | | // For atomic operations on sequence numbers, see atomic_sequence_num.h. |
7 | | |
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 |
10 | | // and memory ordering; it will be less readable, and harder to maintain. If |
11 | | // you plan to use these routines, you should have a good reason, such as solid |
12 | | // evidence that performance would otherwise suffer, or there being no |
13 | | // alternative. You should assume only properties explicitly guaranteed by the |
14 | | // specifications in this file. You are almost certainly _not_ writing code |
15 | | // just for the x86; if you assume x86 semantics, x86 hardware bugs and |
16 | | // implementations on other archtectures will cause your code to break. If you |
17 | | // do not know what you are doing, avoid these routines, and use a Mutex. |
18 | | // |
19 | | // It is incorrect to make direct assignments to/from an atomic variable. |
20 | | // You should use one of the Load or Store routines. The NoBarrier |
21 | | // versions are provided when no barriers are needed: |
22 | | // NoBarrier_Store() |
23 | | // NoBarrier_Load() |
24 | | // Although there are currently no compiler enforcement, you are encouraged |
25 | | // to use these. |
26 | | // |
27 | | |
28 | | #ifndef BUTIL_ATOMICOPS_H_ |
29 | | #define BUTIL_ATOMICOPS_H_ |
30 | | |
31 | | #include <stdint.h> |
32 | | |
33 | | #include "butil/build_config.h" |
34 | | #include "butil/macros.h" |
35 | | |
36 | | #if defined(OS_WIN) && defined(ARCH_CPU_64_BITS) |
37 | | // windows.h #defines this (only on x64). This causes problems because the |
38 | | // public API also uses MemoryBarrier at the public name for this fence. So, on |
39 | | // X64, undef it, and call its documented |
40 | | // (http://msdn.microsoft.com/en-us/library/windows/desktop/ms684208.aspx) |
41 | | // implementation directly. |
42 | | #undef MemoryBarrier |
43 | | #endif |
44 | | |
45 | | namespace butil { |
46 | | namespace subtle { |
47 | | |
48 | | typedef int32_t Atomic32; |
49 | | #ifdef ARCH_CPU_64_BITS |
50 | | // We need to be able to go between Atomic64 and AtomicWord implicitly. This |
51 | | // means Atomic64 and AtomicWord should be the same type on 64-bit. |
52 | | #if defined(__ILP32__) || defined(OS_NACL) |
53 | | // NaCl's intptr_t is not actually 64-bits on 64-bit! |
54 | | // http://code.google.com/p/nativeclient/issues/detail?id=1162 |
55 | | typedef int64_t Atomic64; |
56 | | #else |
57 | | typedef intptr_t Atomic64; |
58 | | #endif |
59 | | #endif |
60 | | |
61 | | // Use AtomicWord for a machine-sized pointer. It will use the Atomic32 or |
62 | | // Atomic64 routines below, depending on your architecture. |
63 | | typedef intptr_t AtomicWord; |
64 | | |
65 | | // Atomically execute: |
66 | | // result = *ptr; |
67 | | // if (*ptr == old_value) |
68 | | // *ptr = new_value; |
69 | | // return result; |
70 | | // |
71 | | // I.e., replace "*ptr" with "new_value" if "*ptr" used to be "old_value". |
72 | | // Always return the old value of "*ptr" |
73 | | // |
74 | | // This routine implies no memory barriers. |
75 | | Atomic32 NoBarrier_CompareAndSwap(volatile Atomic32* ptr, |
76 | | Atomic32 old_value, |
77 | | Atomic32 new_value); |
78 | | |
79 | | // Atomically store new_value into *ptr, returning the previous value held in |
80 | | // *ptr. This routine implies no memory barriers. |
81 | | Atomic32 NoBarrier_AtomicExchange(volatile Atomic32* ptr, Atomic32 new_value); |
82 | | |
83 | | // Atomically increment *ptr by "increment". Returns the new value of |
84 | | // *ptr with the increment applied. This routine implies no memory barriers. |
85 | | Atomic32 NoBarrier_AtomicIncrement(volatile Atomic32* ptr, Atomic32 increment); |
86 | | |
87 | | Atomic32 Barrier_AtomicIncrement(volatile Atomic32* ptr, |
88 | | Atomic32 increment); |
89 | | |
90 | | // These following lower-level operations are typically useful only to people |
91 | | // implementing higher-level synchronization operations like spinlocks, |
92 | | // mutexes, and condition-variables. They combine CompareAndSwap(), a load, or |
93 | | // a store with appropriate memory-ordering instructions. "Acquire" operations |
94 | | // ensure that no later memory access can be reordered ahead of the operation. |
95 | | // "Release" operations ensure that no previous memory access can be reordered |
96 | | // after the operation. "Barrier" operations have both "Acquire" and "Release" |
97 | | // semantics. A MemoryBarrier() has "Barrier" semantics, but does no memory |
98 | | // access. |
99 | | Atomic32 Acquire_CompareAndSwap(volatile Atomic32* ptr, |
100 | | Atomic32 old_value, |
101 | | Atomic32 new_value); |
102 | | Atomic32 Release_CompareAndSwap(volatile Atomic32* ptr, |
103 | | Atomic32 old_value, |
104 | | Atomic32 new_value); |
105 | | |
106 | | void MemoryBarrier(); |
107 | | void NoBarrier_Store(volatile Atomic32* ptr, Atomic32 value); |
108 | | void Acquire_Store(volatile Atomic32* ptr, Atomic32 value); |
109 | | void Release_Store(volatile Atomic32* ptr, Atomic32 value); |
110 | | |
111 | | Atomic32 NoBarrier_Load(volatile const Atomic32* ptr); |
112 | | Atomic32 Acquire_Load(volatile const Atomic32* ptr); |
113 | | Atomic32 Release_Load(volatile const Atomic32* ptr); |
114 | | |
115 | | // 64-bit atomic operations (only available on 64-bit processors). |
116 | | #ifdef ARCH_CPU_64_BITS |
117 | | Atomic64 NoBarrier_CompareAndSwap(volatile Atomic64* ptr, |
118 | | Atomic64 old_value, |
119 | | Atomic64 new_value); |
120 | | Atomic64 NoBarrier_AtomicExchange(volatile Atomic64* ptr, Atomic64 new_value); |
121 | | Atomic64 NoBarrier_AtomicIncrement(volatile Atomic64* ptr, Atomic64 increment); |
122 | | Atomic64 Barrier_AtomicIncrement(volatile Atomic64* ptr, Atomic64 increment); |
123 | | |
124 | | Atomic64 Acquire_CompareAndSwap(volatile Atomic64* ptr, |
125 | | Atomic64 old_value, |
126 | | Atomic64 new_value); |
127 | | Atomic64 Release_CompareAndSwap(volatile Atomic64* ptr, |
128 | | Atomic64 old_value, |
129 | | Atomic64 new_value); |
130 | | void NoBarrier_Store(volatile Atomic64* ptr, Atomic64 value); |
131 | | void Acquire_Store(volatile Atomic64* ptr, Atomic64 value); |
132 | | void Release_Store(volatile Atomic64* ptr, Atomic64 value); |
133 | | Atomic64 NoBarrier_Load(volatile const Atomic64* ptr); |
134 | | Atomic64 Acquire_Load(volatile const Atomic64* ptr); |
135 | | Atomic64 Release_Load(volatile const Atomic64* ptr); |
136 | | #endif // ARCH_CPU_64_BITS |
137 | | |
138 | | } // namespace subtle |
139 | | } // namespace butil |
140 | | |
141 | | // Include our platform specific implementation. |
142 | | #if defined(THREAD_SANITIZER) |
143 | | #include "butil/atomicops_internals_tsan.h" |
144 | | #elif defined(OS_WIN) && defined(COMPILER_MSVC) && defined(ARCH_CPU_X86_FAMILY) |
145 | | #include "butil/atomicops_internals_x86_msvc.h" |
146 | | #elif defined(OS_MACOSX) |
147 | | #include "butil/atomicops_internals_mac.h" |
148 | | #elif defined(OS_NACL) |
149 | | #include "butil/atomicops_internals_gcc.h" |
150 | | #elif defined(COMPILER_GCC) && defined(ARCH_CPU_ARMEL) |
151 | | #include "butil/atomicops_internals_arm_gcc.h" |
152 | | #elif defined(COMPILER_GCC) && defined(ARCH_CPU_ARM64) |
153 | | #include "butil/atomicops_internals_arm64_gcc.h" |
154 | | #elif defined(COMPILER_GCC) && defined(ARCH_CPU_X86_FAMILY) |
155 | | #include "butil/atomicops_internals_x86_gcc.h" |
156 | | #elif defined(COMPILER_GCC) && defined(ARCH_CPU_MIPS_FAMILY) |
157 | | #include "butil/atomicops_internals_mips_gcc.h" |
158 | | #elif defined(COMPILER_GCC) && defined(ARCH_CPU_LOONGARCH64_FAMILY) |
159 | | #include "butil/atomicops_internals_loongarch64_gcc.h" |
160 | | #else |
161 | | #error "Atomic operations are not supported on your platform" |
162 | | #endif |
163 | | |
164 | | // On some platforms we need additional declarations to make |
165 | | // AtomicWord compatible with our other Atomic* types. |
166 | | #if defined(OS_MACOSX) || defined(OS_OPENBSD) |
167 | | #include "butil/atomicops_internals_atomicword_compat.h" |
168 | | #endif |
169 | | |
170 | | // ========= Provide butil::atomic<T> ========= |
171 | | #if defined(BUTIL_CXX11_ENABLED) |
172 | | |
173 | | // gcc supports atomic thread fence since 4.8 checkout |
174 | | // https://gcc.gnu.org/gcc-4.7/cxx0x_status.html and |
175 | | // https://gcc.gnu.org/gcc-4.8/cxx0x_status.html for more details |
176 | | #if defined(__clang__) || \ |
177 | | !defined(__GNUC__) || \ |
178 | | (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 >= 40800) |
179 | | |
180 | | # include <atomic> |
181 | | |
182 | | #else |
183 | | |
184 | | # if __GNUC__ * 10000 + __GNUC_MINOR__ * 100 >= 40500 |
185 | | // gcc 4.5 renames cstdatomic to atomic |
186 | | // (https://gcc.gnu.org/gcc-4.5/changes.html) |
187 | | # include <atomic> |
188 | | # else |
189 | | # include <cstdatomic> |
190 | | # endif |
191 | | |
192 | | namespace std { |
193 | | |
194 | | BUTIL_FORCE_INLINE void atomic_thread_fence(memory_order v) { |
195 | | switch (v) { |
196 | | case memory_order_relaxed: |
197 | | break; |
198 | | case memory_order_consume: |
199 | | case memory_order_acquire: |
200 | | case memory_order_release: |
201 | | case memory_order_acq_rel: |
202 | | __asm__ __volatile__("" : : : "memory"); |
203 | | break; |
204 | | case memory_order_seq_cst: |
205 | | __asm__ __volatile__("mfence" : : : "memory"); |
206 | | break; |
207 | | } |
208 | | } |
209 | | |
210 | | BUTIL_FORCE_INLINE void atomic_signal_fence(memory_order v) { |
211 | | if (v != memory_order_relaxed) { |
212 | | __asm__ __volatile__("" : : : "memory"); |
213 | | } |
214 | | } |
215 | | |
216 | | } // namespace std |
217 | | |
218 | | #endif // __GNUC__ |
219 | | |
220 | | namespace butil { |
221 | | using ::std::memory_order; |
222 | | using ::std::memory_order_relaxed; |
223 | | using ::std::memory_order_consume; |
224 | | using ::std::memory_order_acquire; |
225 | | using ::std::memory_order_release; |
226 | | using ::std::memory_order_acq_rel; |
227 | | using ::std::memory_order_seq_cst; |
228 | | using ::std::atomic_thread_fence; |
229 | | using ::std::atomic_signal_fence; |
230 | | template <typename T> class atomic : public ::std::atomic<T> { |
231 | | public: |
232 | 589k | atomic() {} Unexecuted instantiation: butil::atomic<butil::ObjectPool<butil::IOBufSample>::Block*>::atomic() Unexecuted instantiation: butil::atomic<butil::ObjectPool<bthread::SampledContention>::Block*>::atomic() Unexecuted instantiation: butil::atomic<butil::ObjectPool<bthread::StackFactory<bthread::SmallStackClass>::Wrapper>::Block*>::atomic() Unexecuted instantiation: butil::atomic<butil::ObjectPool<bthread::StackFactory<bthread::NormalStackClass>::Wrapper>::Block*>::atomic() Unexecuted instantiation: butil::atomic<butil::ObjectPool<bthread::StackFactory<bthread::LargeStackClass>::Wrapper>::Block*>::atomic() Unexecuted instantiation: butil::atomic<butil::ResourcePool<bthread::TaskMeta>::Block*>::atomic() Unexecuted instantiation: butil::atomic<long>::atomic() Unexecuted instantiation: butil::atomic<butil::ResourcePool<bthread::TimerThread::Task>::Block*>::atomic() butil::atomic<butil::ObjectPool<brpc::policy::MostCommonMessage>::Block*>::atomic() Line | Count | Source | 232 | 65.5k | atomic() {} |
Unexecuted instantiation: butil::atomic<unsigned long>::atomic() Unexecuted instantiation: butil::atomic<butil::ResourcePool<brpc::Socket>::Block*>::atomic() Unexecuted instantiation: butil::atomic<butil::ResourcePool<brpc::IOEventData>::Block*>::atomic() Unexecuted instantiation: butil::atomic<butil::ObjectPool<brpc::Socket::WriteRequest>::Block*>::atomic() Unexecuted instantiation: butil::atomic<int>::atomic() Unexecuted instantiation: butil::atomic<butil::ObjectPool<brpc::Span>::Block*>::atomic() Unexecuted instantiation: butil::atomic<butil::ObjectPool<logging::LogRequest>::Block*>::atomic() Unexecuted instantiation: butil::atomic<butil::ResourcePool<butil::details::ExtendedEndPoint>::Block*>::atomic() Unexecuted instantiation: butil::atomic<bthread::Butex*>::atomic() Unexecuted instantiation: butil::atomic<butil::ObjectPool<bthread::Butex>::Block*>::atomic() Unexecuted instantiation: butil::atomic<butil::ObjectPool<bthread::TaskNode>::Block*>::atomic() Unexecuted instantiation: butil::atomic<bool>::atomic() Unexecuted instantiation: butil::atomic<butil::ResourcePool<bthread::ExecutionQueueBase>::Block*>::atomic() Unexecuted instantiation: butil::atomic<butil::atomic<int>*>::atomic() butil::atomic<bthread::LazyArray<butil::atomic<int>*, 262144ul, 256ul>::Block*>::atomic() Line | Count | Source | 232 | 524k | atomic() {} |
Unexecuted instantiation: butil::atomic<butil::ResourcePool<bthread::Id>::Block*>::atomic() Unexecuted instantiation: baidu_rpc_protocol.cpp:butil::atomic<butil::ObjectPool<brpc::policy::(anonymous namespace)::BaiduProxyPBMessages>::Block*>::atomic() Unexecuted instantiation: butil::atomic<brpc::policy::RtmpContext::SubChunkArray*>::atomic() Unexecuted instantiation: butil::atomic<brpc::policy::RtmpChunkStream*>::atomic() Unexecuted instantiation: butil::atomic<butil::ObjectPool<brpc::DefaultRpcPBMessages>::Block*>::atomic() |
233 | 6 | atomic(T v) : ::std::atomic<T>(v) {} butil::atomic<int>::atomic(int) Line | Count | Source | 233 | 5 | atomic(T v) : ::std::atomic<T>(v) {} |
butil::atomic<unsigned long>::atomic(unsigned long) Line | Count | Source | 233 | 1 | atomic(T v) : ::std::atomic<T>(v) {} |
Unexecuted instantiation: butil::atomic<bool>::atomic(bool) Unexecuted instantiation: butil::atomic<butil::MPSCQueueNode<butil::IOBufSample*>*>::atomic(butil::MPSCQueueNode<butil::IOBufSample*>*) Unexecuted instantiation: butil::atomic<bthread::ButexWaiter*>::atomic(bthread::ButexWaiter*) Unexecuted instantiation: butil::atomic<unsigned int>::atomic(unsigned int) Unexecuted instantiation: butil::atomic<long>::atomic(long) Unexecuted instantiation: butil::atomic<brpc::SocketPool*>::atomic(brpc::SocketPool*) Unexecuted instantiation: butil::atomic<brpc::VersionedRefWithId<brpc::Socket>::AdditionalRefStatus>::atomic(brpc::VersionedRefWithId<brpc::Socket>::AdditionalRefStatus) Unexecuted instantiation: butil::atomic<brpc::Socket::SharedPart*>::atomic(brpc::Socket::SharedPart*) Unexecuted instantiation: butil::atomic<brpc::Destroyable*>::atomic(brpc::Destroyable*) Unexecuted instantiation: butil::atomic<brpc::Socket::WriteRequest*>::atomic(brpc::Socket::WriteRequest*) Unexecuted instantiation: butil::atomic<brpc::VersionedRefWithId<brpc::IOEventData>::AdditionalRefStatus>::atomic(brpc::VersionedRefWithId<brpc::IOEventData>::AdditionalRefStatus) Unexecuted instantiation: butil::atomic<logging::LogRequest*>::atomic(logging::LogRequest*) Unexecuted instantiation: butil::atomic<bthread::TaskNode*>::atomic(bthread::TaskNode*) Unexecuted instantiation: butil::atomic<bvar::LatencyRecorder*>::atomic(bvar::LatencyRecorder*) |
234 | 0 | atomic& operator=(T v) { |
235 | 0 | this->store(v); |
236 | 0 | return *this; |
237 | 0 | } Unexecuted instantiation: butil::atomic<butil::atomic<int>*>::operator=(butil::atomic<int>*) Unexecuted instantiation: butil::atomic<int>::operator=(int) |
238 | | private: |
239 | | DISALLOW_COPY_AND_ASSIGN(atomic); |
240 | | // Make sure memory layout of std::atomic<T> and boost::atomic<T> |
241 | | // are same so that different compilation units seeing different |
242 | | // definitions(enable C++11 or not) should be compatible. |
243 | | BAIDU_CASSERT(sizeof(T) == sizeof(::std::atomic<T>), size_must_match); |
244 | | }; |
245 | | } // namespace butil |
246 | | #else |
247 | | #include <boost/atomic.hpp> |
248 | | namespace butil { |
249 | | using ::boost::memory_order; |
250 | | using ::boost::memory_order_relaxed; |
251 | | using ::boost::memory_order_consume; |
252 | | using ::boost::memory_order_acquire; |
253 | | using ::boost::memory_order_release; |
254 | | using ::boost::memory_order_acq_rel; |
255 | | using ::boost::memory_order_seq_cst; |
256 | | using ::boost::atomic_thread_fence; |
257 | | using ::boost::atomic_signal_fence; |
258 | | template <typename T> class atomic : public ::boost::atomic<T> { |
259 | | public: |
260 | | atomic() {} |
261 | | atomic(T v) : ::boost::atomic<T>(v) {} |
262 | | atomic& operator=(T v) { |
263 | | this->store(v); |
264 | | return *this; |
265 | | } |
266 | | private: |
267 | | DISALLOW_COPY_AND_ASSIGN(atomic); |
268 | | // Make sure memory layout of std::atomic<T> and boost::atomic<T> |
269 | | // are same so that different compilation units seeing different |
270 | | // definitions(enable C++11 or not) should be compatible. |
271 | | BAIDU_CASSERT(sizeof(T) == sizeof(::boost::atomic<T>), size_must_match); |
272 | | }; |
273 | | } // namespace butil |
274 | | #endif |
275 | | |
276 | | // static_atomic<> is a work-around for C++03 to declare global atomics |
277 | | // w/o constructing-order issues. It can also used in C++11 though. |
278 | | // Example: |
279 | | // butil::static_atomic<int> g_counter = BUTIL_STATIC_ATOMIC_INIT(0); |
280 | | // Notice that to make static_atomic work for C++03, it cannot be |
281 | | // initialized by a constructor. Following code is wrong: |
282 | | // butil::static_atomic<int> g_counter(0); // Not compile |
283 | | |
284 | | #define BUTIL_STATIC_ATOMIC_INIT(val) { (val) } |
285 | | |
286 | | namespace butil { |
287 | | template <typename T> struct static_atomic { |
288 | | T val; |
289 | | |
290 | | // NOTE: the memory_order parameters must be present. |
291 | 73 | T load(memory_order o) { return ref().load(o); } butil::static_atomic<unsigned long>::load(std::memory_order) Line | Count | Source | 291 | 9 | T load(memory_order o) { return ref().load(o); } |
Unexecuted instantiation: butil::static_atomic<butil::ObjectPool<butil::IOBufSample>*>::load(std::memory_order) Unexecuted instantiation: butil::static_atomic<butil::ObjectPool<butil::IOBufSample>::BlockGroup*>::load(std::memory_order) butil::static_atomic<long>::load(std::memory_order) Line | Count | Source | 291 | 2 | T load(memory_order o) { return ref().load(o); } |
Unexecuted instantiation: butil::static_atomic<butil::ObjectPool<bthread::SampledContention>*>::load(std::memory_order) Unexecuted instantiation: butil::static_atomic<butil::ObjectPool<bthread::SampledContention>::BlockGroup*>::load(std::memory_order) Unexecuted instantiation: butil::static_atomic<butil::ObjectPool<bthread::StackFactory<bthread::SmallStackClass>::Wrapper>*>::load(std::memory_order) Unexecuted instantiation: butil::static_atomic<butil::ObjectPool<bthread::StackFactory<bthread::SmallStackClass>::Wrapper>::BlockGroup*>::load(std::memory_order) Unexecuted instantiation: butil::static_atomic<butil::ObjectPool<bthread::StackFactory<bthread::NormalStackClass>::Wrapper>*>::load(std::memory_order) Unexecuted instantiation: butil::static_atomic<butil::ObjectPool<bthread::StackFactory<bthread::NormalStackClass>::Wrapper>::BlockGroup*>::load(std::memory_order) Unexecuted instantiation: butil::static_atomic<butil::ObjectPool<bthread::StackFactory<bthread::LargeStackClass>::Wrapper>*>::load(std::memory_order) Unexecuted instantiation: butil::static_atomic<butil::ObjectPool<bthread::StackFactory<bthread::LargeStackClass>::Wrapper>::BlockGroup*>::load(std::memory_order) Unexecuted instantiation: butil::static_atomic<butil::ResourcePool<bthread::TaskMeta>::BlockGroup*>::load(std::memory_order) Unexecuted instantiation: butil::static_atomic<butil::ResourcePool<bthread::TaskMeta>*>::load(std::memory_order) Unexecuted instantiation: butil::static_atomic<butil::ResourcePool<bthread::TimerThread::Task>*>::load(std::memory_order) Unexecuted instantiation: butil::static_atomic<butil::ResourcePool<bthread::TimerThread::Task>::BlockGroup*>::load(std::memory_order) butil::static_atomic<butil::ObjectPool<brpc::policy::MostCommonMessage>*>::load(std::memory_order) Line | Count | Source | 291 | 61 | T load(memory_order o) { return ref().load(o); } |
butil::static_atomic<butil::ObjectPool<brpc::policy::MostCommonMessage>::BlockGroup*>::load(std::memory_order) Line | Count | Source | 291 | 1 | T load(memory_order o) { return ref().load(o); } |
Unexecuted instantiation: butil::static_atomic<butil::ResourcePool<brpc::IOEventData>*>::load(std::memory_order) Unexecuted instantiation: butil::static_atomic<butil::ResourcePool<brpc::IOEventData>::BlockGroup*>::load(std::memory_order) Unexecuted instantiation: butil::static_atomic<butil::ObjectPool<brpc::internal::ArenaRpcPBMessages<256ul, 8192ul> >*>::load(std::memory_order) Unexecuted instantiation: butil::static_atomic<butil::ObjectPool<brpc::internal::ArenaRpcPBMessages<256ul, 8192ul> >::BlockGroup*>::load(std::memory_order) Unexecuted instantiation: butil::static_atomic<butil::ResourcePool<brpc::Socket>::BlockGroup*>::load(std::memory_order) Unexecuted instantiation: butil::static_atomic<butil::ResourcePool<brpc::Socket>*>::load(std::memory_order) Unexecuted instantiation: butil::static_atomic<butil::ObjectPool<brpc::Socket::WriteRequest>*>::load(std::memory_order) Unexecuted instantiation: butil::static_atomic<butil::ObjectPool<brpc::Socket::WriteRequest>::BlockGroup*>::load(std::memory_order) Unexecuted instantiation: butil::static_atomic<butil::ObjectPool<brpc::Span>*>::load(std::memory_order) Unexecuted instantiation: butil::static_atomic<butil::ObjectPool<brpc::Span>::BlockGroup*>::load(std::memory_order) Unexecuted instantiation: butil::static_atomic<butil::ObjectPool<logging::LogRequest>*>::load(std::memory_order) Unexecuted instantiation: butil::static_atomic<butil::ObjectPool<logging::LogRequest>::BlockGroup*>::load(std::memory_order) Unexecuted instantiation: butil::static_atomic<butil::ResourcePool<butil::details::ExtendedEndPoint>::BlockGroup*>::load(std::memory_order) Unexecuted instantiation: butil::static_atomic<butil::ResourcePool<butil::details::ExtendedEndPoint>*>::load(std::memory_order) Unexecuted instantiation: butil::static_atomic<butil::ObjectPool<bthread::Butex>*>::load(std::memory_order) Unexecuted instantiation: butil::static_atomic<butil::ObjectPool<bthread::Butex>::BlockGroup*>::load(std::memory_order) Unexecuted instantiation: butil::static_atomic<butil::ResourcePool<bthread::ExecutionQueueBase>*>::load(std::memory_order) Unexecuted instantiation: butil::static_atomic<butil::ObjectPool<bthread::TaskNode>*>::load(std::memory_order) Unexecuted instantiation: butil::static_atomic<butil::ObjectPool<bthread::TaskNode>::BlockGroup*>::load(std::memory_order) Unexecuted instantiation: butil::static_atomic<butil::ResourcePool<bthread::ExecutionQueueBase>::BlockGroup*>::load(std::memory_order) Unexecuted instantiation: butil::static_atomic<butil::ResourcePool<bthread::Id>*>::load(std::memory_order) Unexecuted instantiation: butil::static_atomic<butil::ResourcePool<bthread::Id>::BlockGroup*>::load(std::memory_order) Unexecuted instantiation: butil::static_atomic<int>::load(std::memory_order) Unexecuted instantiation: baidu_rpc_protocol.cpp:butil::static_atomic<butil::ObjectPool<brpc::policy::(anonymous namespace)::BaiduProxyPBMessages>*>::load(std::memory_order) Unexecuted instantiation: baidu_rpc_protocol.cpp:butil::static_atomic<butil::ObjectPool<brpc::policy::(anonymous namespace)::BaiduProxyPBMessages>::BlockGroup*>::load(std::memory_order) Unexecuted instantiation: butil::static_atomic<butil::ObjectPool<brpc::DefaultRpcPBMessages>*>::load(std::memory_order) Unexecuted instantiation: butil::static_atomic<butil::ObjectPool<brpc::DefaultRpcPBMessages>::BlockGroup*>::load(std::memory_order) Unexecuted instantiation: butil::static_atomic<brpc::SocketMap*>::load(std::memory_order) |
292 | 3 | void store(T v, memory_order o) { return ref().store(v, o); } Unexecuted instantiation: butil::static_atomic<butil::ObjectPool<butil::IOBufSample>*>::store(butil::ObjectPool<butil::IOBufSample>*, std::memory_order) Unexecuted instantiation: butil::static_atomic<butil::ObjectPool<butil::IOBufSample>::BlockGroup*>::store(butil::ObjectPool<butil::IOBufSample>::BlockGroup*, std::memory_order) butil::static_atomic<unsigned long>::store(unsigned long, std::memory_order) Line | Count | Source | 292 | 1 | void store(T v, memory_order o) { return ref().store(v, o); } |
Unexecuted instantiation: butil::static_atomic<butil::ObjectPool<bthread::SampledContention>*>::store(butil::ObjectPool<bthread::SampledContention>*, std::memory_order) Unexecuted instantiation: butil::static_atomic<butil::ObjectPool<bthread::SampledContention>::BlockGroup*>::store(butil::ObjectPool<bthread::SampledContention>::BlockGroup*, std::memory_order) Unexecuted instantiation: butil::static_atomic<butil::ObjectPool<bthread::StackFactory<bthread::SmallStackClass>::Wrapper>*>::store(butil::ObjectPool<bthread::StackFactory<bthread::SmallStackClass>::Wrapper>*, std::memory_order) Unexecuted instantiation: butil::static_atomic<butil::ObjectPool<bthread::StackFactory<bthread::SmallStackClass>::Wrapper>::BlockGroup*>::store(butil::ObjectPool<bthread::StackFactory<bthread::SmallStackClass>::Wrapper>::BlockGroup*, std::memory_order) Unexecuted instantiation: butil::static_atomic<butil::ObjectPool<bthread::StackFactory<bthread::NormalStackClass>::Wrapper>*>::store(butil::ObjectPool<bthread::StackFactory<bthread::NormalStackClass>::Wrapper>*, std::memory_order) Unexecuted instantiation: butil::static_atomic<butil::ObjectPool<bthread::StackFactory<bthread::NormalStackClass>::Wrapper>::BlockGroup*>::store(butil::ObjectPool<bthread::StackFactory<bthread::NormalStackClass>::Wrapper>::BlockGroup*, std::memory_order) Unexecuted instantiation: butil::static_atomic<butil::ObjectPool<bthread::StackFactory<bthread::LargeStackClass>::Wrapper>*>::store(butil::ObjectPool<bthread::StackFactory<bthread::LargeStackClass>::Wrapper>*, std::memory_order) Unexecuted instantiation: butil::static_atomic<butil::ObjectPool<bthread::StackFactory<bthread::LargeStackClass>::Wrapper>::BlockGroup*>::store(butil::ObjectPool<bthread::StackFactory<bthread::LargeStackClass>::Wrapper>::BlockGroup*, std::memory_order) Unexecuted instantiation: butil::static_atomic<butil::ResourcePool<bthread::TaskMeta>*>::store(butil::ResourcePool<bthread::TaskMeta>*, std::memory_order) Unexecuted instantiation: butil::static_atomic<butil::ResourcePool<bthread::TaskMeta>::BlockGroup*>::store(butil::ResourcePool<bthread::TaskMeta>::BlockGroup*, std::memory_order) Unexecuted instantiation: butil::static_atomic<butil::ResourcePool<bthread::TimerThread::Task>*>::store(butil::ResourcePool<bthread::TimerThread::Task>*, std::memory_order) Unexecuted instantiation: butil::static_atomic<butil::ResourcePool<bthread::TimerThread::Task>::BlockGroup*>::store(butil::ResourcePool<bthread::TimerThread::Task>::BlockGroup*, std::memory_order) butil::static_atomic<butil::ObjectPool<brpc::policy::MostCommonMessage>*>::store(butil::ObjectPool<brpc::policy::MostCommonMessage>*, std::memory_order) Line | Count | Source | 292 | 1 | void store(T v, memory_order o) { return ref().store(v, o); } |
butil::static_atomic<butil::ObjectPool<brpc::policy::MostCommonMessage>::BlockGroup*>::store(butil::ObjectPool<brpc::policy::MostCommonMessage>::BlockGroup*, std::memory_order) Line | Count | Source | 292 | 1 | void store(T v, memory_order o) { return ref().store(v, o); } |
Unexecuted instantiation: butil::static_atomic<butil::ResourcePool<brpc::IOEventData>*>::store(butil::ResourcePool<brpc::IOEventData>*, std::memory_order) Unexecuted instantiation: butil::static_atomic<butil::ObjectPool<brpc::internal::ArenaRpcPBMessages<256ul, 8192ul> >*>::store(butil::ObjectPool<brpc::internal::ArenaRpcPBMessages<256ul, 8192ul> >*, std::memory_order) Unexecuted instantiation: butil::static_atomic<butil::ObjectPool<brpc::internal::ArenaRpcPBMessages<256ul, 8192ul> >::BlockGroup*>::store(butil::ObjectPool<brpc::internal::ArenaRpcPBMessages<256ul, 8192ul> >::BlockGroup*, std::memory_order) Unexecuted instantiation: butil::static_atomic<butil::ResourcePool<brpc::Socket>*>::store(butil::ResourcePool<brpc::Socket>*, std::memory_order) Unexecuted instantiation: butil::static_atomic<butil::ObjectPool<brpc::Socket::WriteRequest>*>::store(butil::ObjectPool<brpc::Socket::WriteRequest>*, std::memory_order) Unexecuted instantiation: butil::static_atomic<butil::ResourcePool<brpc::Socket>::BlockGroup*>::store(butil::ResourcePool<brpc::Socket>::BlockGroup*, std::memory_order) Unexecuted instantiation: butil::static_atomic<butil::ResourcePool<brpc::IOEventData>::BlockGroup*>::store(butil::ResourcePool<brpc::IOEventData>::BlockGroup*, std::memory_order) Unexecuted instantiation: butil::static_atomic<butil::ObjectPool<brpc::Socket::WriteRequest>::BlockGroup*>::store(butil::ObjectPool<brpc::Socket::WriteRequest>::BlockGroup*, std::memory_order) Unexecuted instantiation: butil::static_atomic<butil::ObjectPool<brpc::Span>*>::store(butil::ObjectPool<brpc::Span>*, std::memory_order) Unexecuted instantiation: butil::static_atomic<butil::ObjectPool<brpc::Span>::BlockGroup*>::store(butil::ObjectPool<brpc::Span>::BlockGroup*, std::memory_order) Unexecuted instantiation: butil::static_atomic<butil::ObjectPool<logging::LogRequest>*>::store(butil::ObjectPool<logging::LogRequest>*, std::memory_order) Unexecuted instantiation: butil::static_atomic<butil::ObjectPool<logging::LogRequest>::BlockGroup*>::store(butil::ObjectPool<logging::LogRequest>::BlockGroup*, std::memory_order) Unexecuted instantiation: butil::static_atomic<butil::ResourcePool<butil::details::ExtendedEndPoint>*>::store(butil::ResourcePool<butil::details::ExtendedEndPoint>*, std::memory_order) Unexecuted instantiation: butil::static_atomic<butil::ResourcePool<butil::details::ExtendedEndPoint>::BlockGroup*>::store(butil::ResourcePool<butil::details::ExtendedEndPoint>::BlockGroup*, std::memory_order) Unexecuted instantiation: butil::static_atomic<butil::ObjectPool<bthread::Butex>*>::store(butil::ObjectPool<bthread::Butex>*, std::memory_order) Unexecuted instantiation: butil::static_atomic<butil::ObjectPool<bthread::Butex>::BlockGroup*>::store(butil::ObjectPool<bthread::Butex>::BlockGroup*, std::memory_order) Unexecuted instantiation: butil::static_atomic<butil::ResourcePool<bthread::ExecutionQueueBase>*>::store(butil::ResourcePool<bthread::ExecutionQueueBase>*, std::memory_order) Unexecuted instantiation: butil::static_atomic<butil::ObjectPool<bthread::TaskNode>*>::store(butil::ObjectPool<bthread::TaskNode>*, std::memory_order) Unexecuted instantiation: butil::static_atomic<butil::ObjectPool<bthread::TaskNode>::BlockGroup*>::store(butil::ObjectPool<bthread::TaskNode>::BlockGroup*, std::memory_order) Unexecuted instantiation: butil::static_atomic<butil::ResourcePool<bthread::ExecutionQueueBase>::BlockGroup*>::store(butil::ResourcePool<bthread::ExecutionQueueBase>::BlockGroup*, std::memory_order) Unexecuted instantiation: butil::static_atomic<butil::ResourcePool<bthread::Id>*>::store(butil::ResourcePool<bthread::Id>*, std::memory_order) Unexecuted instantiation: butil::static_atomic<butil::ResourcePool<bthread::Id>::BlockGroup*>::store(butil::ResourcePool<bthread::Id>::BlockGroup*, std::memory_order) Unexecuted instantiation: baidu_rpc_protocol.cpp:butil::static_atomic<butil::ObjectPool<brpc::policy::(anonymous namespace)::BaiduProxyPBMessages>*>::store(butil::ObjectPool<brpc::policy::(anonymous namespace)::BaiduProxyPBMessages>*, std::memory_order) Unexecuted instantiation: baidu_rpc_protocol.cpp:butil::static_atomic<butil::ObjectPool<brpc::policy::(anonymous namespace)::BaiduProxyPBMessages>::BlockGroup*>::store(butil::ObjectPool<brpc::policy::(anonymous namespace)::BaiduProxyPBMessages>::BlockGroup*, std::memory_order) Unexecuted instantiation: butil::static_atomic<butil::ObjectPool<brpc::DefaultRpcPBMessages>*>::store(butil::ObjectPool<brpc::DefaultRpcPBMessages>*, std::memory_order) Unexecuted instantiation: butil::static_atomic<butil::ObjectPool<brpc::DefaultRpcPBMessages>::BlockGroup*>::store(butil::ObjectPool<brpc::DefaultRpcPBMessages>::BlockGroup*, std::memory_order) Unexecuted instantiation: butil::static_atomic<brpc::SocketMap*>::store(brpc::SocketMap*, std::memory_order) |
293 | 0 | T exchange(T v, memory_order o) { return ref().exchange(v, o); } |
294 | | bool compare_exchange_weak(T& e, T d, memory_order o) |
295 | | { return ref().compare_exchange_weak(e, d, o); } |
296 | | bool compare_exchange_weak(T& e, T d, memory_order so, memory_order fo) |
297 | | { return ref().compare_exchange_weak(e, d, so, fo); } |
298 | | bool compare_exchange_strong(T& e, T d, memory_order o) |
299 | 0 | { return ref().compare_exchange_strong(e, d, o); } |
300 | | bool compare_exchange_strong(T& e, T d, memory_order so, memory_order fo) |
301 | | { return ref().compare_exchange_strong(e, d, so, fo); } |
302 | 11 | T fetch_add(T v, memory_order o) { return ref().fetch_add(v, o); } butil::static_atomic<unsigned long>::fetch_add(unsigned long, std::memory_order) Line | Count | Source | 302 | 10 | T fetch_add(T v, memory_order o) { return ref().fetch_add(v, o); } |
butil::static_atomic<long>::fetch_add(long, std::memory_order) Line | Count | Source | 302 | 1 | T fetch_add(T v, memory_order o) { return ref().fetch_add(v, o); } |
Unexecuted instantiation: butil::static_atomic<int>::fetch_add(int, std::memory_order) |
303 | 0 | T fetch_sub(T v, memory_order o) { return ref().fetch_sub(v, o); } Unexecuted instantiation: butil::static_atomic<unsigned long>::fetch_sub(unsigned long, std::memory_order) Unexecuted instantiation: butil::static_atomic<long>::fetch_sub(long, std::memory_order) Unexecuted instantiation: butil::static_atomic<int>::fetch_sub(int, std::memory_order) |
304 | | T fetch_and(T v, memory_order o) { return ref().fetch_and(v, o); } |
305 | | T fetch_or(T v, memory_order o) { return ref().fetch_or(v, o); } |
306 | | T fetch_xor(T v, memory_order o) { return ref().fetch_xor(v, o); } |
307 | | static_atomic& operator=(T v) { |
308 | | store(v, memory_order_seq_cst); |
309 | | return *this; |
310 | | } |
311 | | private: |
312 | | DISALLOW_ASSIGN(static_atomic); |
313 | | BAIDU_CASSERT(sizeof(T) == sizeof(atomic<T>), size_must_match); |
314 | 87 | atomic<T>& ref() { |
315 | | // Suppress strict-alias warnings. |
316 | 87 | atomic<T>* p = reinterpret_cast<atomic<T>*>(&val); |
317 | 87 | return *p; |
318 | 87 | } butil::static_atomic<unsigned long>::ref() Line | Count | Source | 314 | 20 | atomic<T>& ref() { | 315 | | // Suppress strict-alias warnings. | 316 | 20 | atomic<T>* p = reinterpret_cast<atomic<T>*>(&val); | 317 | 20 | return *p; | 318 | 20 | } |
Unexecuted instantiation: butil::static_atomic<butil::ObjectPool<butil::IOBufSample>*>::ref() butil::static_atomic<long>::ref() Line | Count | Source | 314 | 3 | atomic<T>& ref() { | 315 | | // Suppress strict-alias warnings. | 316 | 3 | atomic<T>* p = reinterpret_cast<atomic<T>*>(&val); | 317 | 3 | return *p; | 318 | 3 | } |
Unexecuted instantiation: butil::static_atomic<butil::ObjectPool<butil::IOBufSample>::BlockGroup*>::ref() Unexecuted instantiation: butil::static_atomic<butil::ObjectPool<bthread::SampledContention>*>::ref() Unexecuted instantiation: butil::static_atomic<butil::ObjectPool<bthread::SampledContention>::BlockGroup*>::ref() Unexecuted instantiation: butil::static_atomic<unsigned char>::ref() Unexecuted instantiation: butil::static_atomic<butil::ObjectPool<bthread::StackFactory<bthread::SmallStackClass>::Wrapper>*>::ref() Unexecuted instantiation: butil::static_atomic<butil::ObjectPool<bthread::StackFactory<bthread::SmallStackClass>::Wrapper>::BlockGroup*>::ref() Unexecuted instantiation: butil::static_atomic<butil::ObjectPool<bthread::StackFactory<bthread::NormalStackClass>::Wrapper>*>::ref() Unexecuted instantiation: butil::static_atomic<butil::ObjectPool<bthread::StackFactory<bthread::NormalStackClass>::Wrapper>::BlockGroup*>::ref() Unexecuted instantiation: butil::static_atomic<butil::ObjectPool<bthread::StackFactory<bthread::LargeStackClass>::Wrapper>*>::ref() Unexecuted instantiation: butil::static_atomic<butil::ObjectPool<bthread::StackFactory<bthread::LargeStackClass>::Wrapper>::BlockGroup*>::ref() Unexecuted instantiation: butil::static_atomic<butil::ResourcePool<bthread::TaskMeta>::BlockGroup*>::ref() Unexecuted instantiation: butil::static_atomic<butil::ResourcePool<bthread::TaskMeta>*>::ref() Unexecuted instantiation: butil::static_atomic<butil::ResourcePool<bthread::TimerThread::Task>*>::ref() Unexecuted instantiation: butil::static_atomic<butil::ResourcePool<bthread::TimerThread::Task>::BlockGroup*>::ref() butil::static_atomic<butil::ObjectPool<brpc::policy::MostCommonMessage>*>::ref() Line | Count | Source | 314 | 62 | atomic<T>& ref() { | 315 | | // Suppress strict-alias warnings. | 316 | 62 | atomic<T>* p = reinterpret_cast<atomic<T>*>(&val); | 317 | 62 | return *p; | 318 | 62 | } |
butil::static_atomic<butil::ObjectPool<brpc::policy::MostCommonMessage>::BlockGroup*>::ref() Line | Count | Source | 314 | 2 | atomic<T>& ref() { | 315 | | // Suppress strict-alias warnings. | 316 | 2 | atomic<T>* p = reinterpret_cast<atomic<T>*>(&val); | 317 | 2 | return *p; | 318 | 2 | } |
Unexecuted instantiation: butil::static_atomic<int>::ref() Unexecuted instantiation: butil::static_atomic<butil::ResourcePool<brpc::IOEventData>*>::ref() Unexecuted instantiation: butil::static_atomic<butil::ResourcePool<brpc::IOEventData>::BlockGroup*>::ref() Unexecuted instantiation: butil::static_atomic<butil::ObjectPool<brpc::internal::ArenaRpcPBMessages<256ul, 8192ul> >*>::ref() Unexecuted instantiation: butil::static_atomic<butil::ObjectPool<brpc::internal::ArenaRpcPBMessages<256ul, 8192ul> >::BlockGroup*>::ref() Unexecuted instantiation: butil::static_atomic<butil::ResourcePool<brpc::Socket>::BlockGroup*>::ref() Unexecuted instantiation: butil::static_atomic<butil::ResourcePool<brpc::Socket>*>::ref() Unexecuted instantiation: butil::static_atomic<butil::ObjectPool<brpc::Socket::WriteRequest>*>::ref() Unexecuted instantiation: butil::static_atomic<butil::ObjectPool<brpc::Socket::WriteRequest>::BlockGroup*>::ref() Unexecuted instantiation: butil::static_atomic<butil::ObjectPool<brpc::Span>*>::ref() Unexecuted instantiation: butil::static_atomic<butil::ObjectPool<brpc::Span>::BlockGroup*>::ref() Unexecuted instantiation: butil::static_atomic<butil::ObjectPool<logging::LogRequest>*>::ref() Unexecuted instantiation: butil::static_atomic<butil::ObjectPool<logging::LogRequest>::BlockGroup*>::ref() Unexecuted instantiation: butil::static_atomic<butil::ResourcePool<butil::details::ExtendedEndPoint>::BlockGroup*>::ref() Unexecuted instantiation: butil::static_atomic<butil::ResourcePool<butil::details::ExtendedEndPoint>*>::ref() Unexecuted instantiation: butil::static_atomic<butil::ObjectPool<bthread::Butex>*>::ref() Unexecuted instantiation: butil::static_atomic<butil::ObjectPool<bthread::Butex>::BlockGroup*>::ref() Unexecuted instantiation: butil::static_atomic<butil::ResourcePool<bthread::ExecutionQueueBase>*>::ref() Unexecuted instantiation: butil::static_atomic<butil::ObjectPool<bthread::TaskNode>*>::ref() Unexecuted instantiation: butil::static_atomic<butil::ObjectPool<bthread::TaskNode>::BlockGroup*>::ref() Unexecuted instantiation: butil::static_atomic<butil::ResourcePool<bthread::ExecutionQueueBase>::BlockGroup*>::ref() Unexecuted instantiation: butil::static_atomic<butil::ResourcePool<bthread::Id>*>::ref() Unexecuted instantiation: butil::static_atomic<butil::ResourcePool<bthread::Id>::BlockGroup*>::ref() Unexecuted instantiation: baidu_rpc_protocol.cpp:butil::static_atomic<butil::ObjectPool<brpc::policy::(anonymous namespace)::BaiduProxyPBMessages>*>::ref() Unexecuted instantiation: baidu_rpc_protocol.cpp:butil::static_atomic<butil::ObjectPool<brpc::policy::(anonymous namespace)::BaiduProxyPBMessages>::BlockGroup*>::ref() Unexecuted instantiation: butil::static_atomic<butil::ObjectPool<brpc::DefaultRpcPBMessages>*>::ref() Unexecuted instantiation: butil::static_atomic<butil::ObjectPool<brpc::DefaultRpcPBMessages>::BlockGroup*>::ref() Unexecuted instantiation: butil::static_atomic<brpc::SocketMap*>::ref() |
319 | | }; |
320 | | } // namespace butil |
321 | | |
322 | | #endif // BUTIL_ATOMICOPS_H_ |