diff options
author | Rasmus Munk Larsen <rmlarsen@google.com> | 2020-09-12 01:23:29 +0000 |
---|---|---|
committer | Rasmus Munk Larsen <rmlarsen@google.com> | 2020-09-12 01:23:29 +0000 |
commit | 71e08c702b0497b350830febdbfee05e2445ea9d (patch) | |
tree | 34a67619f195d9c4df7ae48ed4868894db49a280 /Eigen/src/Core | |
parent | adc861cabd2ea02942a04d01d8588fee400903fc (diff) |
Make blueNorm threadsafe if C++11 atomics are available.
Diffstat (limited to 'Eigen/src/Core')
-rw-r--r-- | Eigen/src/Core/StableNorm.h | 32 |
1 files changed, 29 insertions, 3 deletions
diff --git a/Eigen/src/Core/StableNorm.h b/Eigen/src/Core/StableNorm.h index 77ea3c261..8000f9d33 100644 --- a/Eigen/src/Core/StableNorm.h +++ b/Eigen/src/Core/StableNorm.h @@ -10,6 +10,10 @@ #ifndef EIGEN_STABLENORM_H #define EIGEN_STABLENORM_H +#if EIGEN_HAS_CXX11_ATOMIC +#include <atomic> +#endif + namespace Eigen { namespace internal { @@ -124,10 +128,29 @@ blueNorm_impl(const EigenBase<Derived>& _vec) using std::sqrt; using std::abs; const Derived& vec(_vec.derived()); - static bool initialized = false; + +#if EIGEN_HAS_CXX11_ATOMIC + enum { + kNotInitialized = 0, + kInitializing = 1, + kInitialized = 2 + }; + static std::atomic<uint8_t> initialized{kNotInitialized}; +#else + // Note: This is not theadsafe without C++11. + const bool kNotInitialized = false; + const bool kInitialized = true; + static bool initialized = kNotInitialized; +#endif static RealScalar b1, b2, s1m, s2m, rbig, relerr; - if(!initialized) + + while (initialized != kInitialized) { +#if EIGEN_HAS_CXX11_ATOMIC + // Checking again to see if another thread has already initialized the constants. + uint8_t val = kNotInitialized; + if (initialized.compare_exchange_strong(val, kInitializing) && val != kInitialized) { +#endif int ibeta, it, iemin, iemax, iexp; RealScalar eps; // This program calculates the machine-dependent constants @@ -156,7 +179,10 @@ blueNorm_impl(const EigenBase<Derived>& _vec) eps = RealScalar(pow(double(ibeta), 1-it)); relerr = sqrt(eps); // tolerance for neglecting asml - initialized = true; + initialized = kInitialized; +#if EIGEN_HAS_CXX11_ATOMIC + } +#endif } Index n = vec.size(); RealScalar ab2 = b2 / RealScalar(n); |