aboutsummaryrefslogtreecommitdiffhomepage
path: root/Eigen/src/Core/StableNorm.h
diff options
context:
space:
mode:
authorGravatar Rasmus Munk Larsen <rmlarsen@google.com>2020-09-12 01:23:29 +0000
committerGravatar Rasmus Munk Larsen <rmlarsen@google.com>2020-09-12 01:23:29 +0000
commit71e08c702b0497b350830febdbfee05e2445ea9d (patch)
tree34a67619f195d9c4df7ae48ed4868894db49a280 /Eigen/src/Core/StableNorm.h
parentadc861cabd2ea02942a04d01d8588fee400903fc (diff)
Make blueNorm threadsafe if C++11 atomics are available.
Diffstat (limited to 'Eigen/src/Core/StableNorm.h')
-rw-r--r--Eigen/src/Core/StableNorm.h32
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);