Unverified Commit 40d2069d by Mircea Trofin Committed by GitHub

Use C++11 atomic_signal_fence for ClobberMemory (#1190)

* Use C++11 atomic_signal_fence for ClobberMemory * include * Conditionally using std::atomic_signal_fence when C++11 is available
parent 38b767e5
...@@ -187,6 +187,7 @@ BENCHMARK(BM_test)->Unit(benchmark::kMillisecond); ...@@ -187,6 +187,7 @@ BENCHMARK(BM_test)->Unit(benchmark::kMillisecond);
#include <vector> #include <vector>
#if defined(BENCHMARK_HAS_CXX11) #if defined(BENCHMARK_HAS_CXX11)
#include <atomic>
#include <initializer_list> #include <initializer_list>
#include <type_traits> #include <type_traits>
#include <utility> #include <utility>
...@@ -327,6 +328,14 @@ BENCHMARK_UNUSED static int stream_init_anchor = InitializeStreams(); ...@@ -327,6 +328,14 @@ BENCHMARK_UNUSED static int stream_init_anchor = InitializeStreams();
#define BENCHMARK_HAS_NO_INLINE_ASSEMBLY #define BENCHMARK_HAS_NO_INLINE_ASSEMBLY
#endif #endif
// Force the compiler to flush pending writes to global memory. Acts as an
// effective read/write barrier
#ifdef BENCHMARK_HAS_CXX11
inline BENCHMARK_ALWAYS_INLINE void ClobberMemory() {
std::atomic_signal_fence(std::memory_order_acq_rel);
}
#endif
// The DoNotOptimize(...) function can be used to prevent a value or // The DoNotOptimize(...) function can be used to prevent a value or
// expression from being optimized away by the compiler. This function is // expression from being optimized away by the compiler. This function is
// intended to add little to no overhead. // intended to add little to no overhead.
...@@ -346,11 +355,11 @@ inline BENCHMARK_ALWAYS_INLINE void DoNotOptimize(Tp& value) { ...@@ -346,11 +355,11 @@ inline BENCHMARK_ALWAYS_INLINE void DoNotOptimize(Tp& value) {
#endif #endif
} }
// Force the compiler to flush pending writes to global memory. Acts as an #ifndef BENCHMARK_HAS_CXX11
// effective read/write barrier
inline BENCHMARK_ALWAYS_INLINE void ClobberMemory() { inline BENCHMARK_ALWAYS_INLINE void ClobberMemory() {
asm volatile("" : : : "memory"); asm volatile("" : : : "memory");
} }
#endif
#elif defined(_MSC_VER) #elif defined(_MSC_VER)
template <class Tp> template <class Tp>
inline BENCHMARK_ALWAYS_INLINE void DoNotOptimize(Tp const& value) { inline BENCHMARK_ALWAYS_INLINE void DoNotOptimize(Tp const& value) {
...@@ -358,13 +367,15 @@ inline BENCHMARK_ALWAYS_INLINE void DoNotOptimize(Tp const& value) { ...@@ -358,13 +367,15 @@ inline BENCHMARK_ALWAYS_INLINE void DoNotOptimize(Tp const& value) {
_ReadWriteBarrier(); _ReadWriteBarrier();
} }
#ifndef BENCHMARK_HAS_CXX11
inline BENCHMARK_ALWAYS_INLINE void ClobberMemory() { _ReadWriteBarrier(); } inline BENCHMARK_ALWAYS_INLINE void ClobberMemory() { _ReadWriteBarrier(); }
#endif
#else #else
template <class Tp> template <class Tp>
inline BENCHMARK_ALWAYS_INLINE void DoNotOptimize(Tp const& value) { inline BENCHMARK_ALWAYS_INLINE void DoNotOptimize(Tp const& value) {
internal::UseCharPointer(&reinterpret_cast<char const volatile&>(value)); internal::UseCharPointer(&reinterpret_cast<char const volatile&>(value));
} }
// FIXME Add ClobberMemory() for non-gnu and non-msvc compilers // FIXME Add ClobberMemory() for non-gnu and non-msvc compilers, before C++11.
#endif #endif
// This class is used for user-defined counters. // This class is used for user-defined counters.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment