implement singleton lazy initialization
authorAlexander Alekhin <alexander.alekhin@itseez.com>
Tue, 23 Jun 2015 11:31:01 +0000 (14:31 +0300)
committerAlexander Alekhin <alexander.alekhin@itseez.com>
Tue, 23 Jun 2015 11:38:45 +0000 (14:38 +0300)
modules/core/src/dxt.cpp
modules/core/src/matop.cpp
modules/core/src/matrix.cpp
modules/core/src/ocl.cpp
modules/core/src/precomp.hpp
modules/core/src/system.cpp

index e3fd0e4..ef01c21 100644 (file)
@@ -2026,8 +2026,7 @@ class OCL_FftPlanCache
 public:
     static OCL_FftPlanCache & getInstance()
     {
-        static OCL_FftPlanCache planCache;
-        return planCache;
+        CV_SINGLETON_LAZY_INIT_REF(OCL_FftPlanCache, new OCL_FftPlanCache())
     }
 
     Ptr<OCL_FftPlan> getFftPlan(int dft_size, int depth)
@@ -2291,8 +2290,7 @@ class PlanCache
 public:
     static PlanCache & getInstance()
     {
-        static PlanCache planCache;
-        return planCache;
+        CV_SINGLETON_LAZY_INIT_REF(PlanCache, new PlanCache())
     }
 
     clAmdFftPlanHandle getPlanHandle(const Size & dft_size, int src_step, int dst_step, bool doubleFP,
index a0ee431..b512485 100644 (file)
@@ -205,8 +205,7 @@ public:
 
 static MatOp_Initializer* getGlobalMatOpInitializer()
 {
-    static MatOp_Initializer initializer;
-    return &initializer;
+    CV_SINGLETON_LAZY_INIT(MatOp_Initializer, new MatOp_Initializer())
 }
 
 static inline bool isIdentity(const MatExpr& e) { return e.op == &g_MatOp_Identity; }
index 5de7e03..9b39fe6 100644 (file)
@@ -222,14 +222,9 @@ public:
     }
 };
 
-static StdMatAllocator *mat_allocator = NULL;
 MatAllocator* Mat::getStdAllocator()
 {
-    if (mat_allocator == NULL)
-    {
-        mat_allocator = new StdMatAllocator();
-    }
-    return mat_allocator;
+    CV_SINGLETON_LAZY_INIT(MatAllocator, new StdMatAllocator())
 }
 
 void swap( Mat& a, Mat& b )
index 9d25eb0..0378b66 100644 (file)
@@ -1510,8 +1510,7 @@ class AmdBlasHelper
 public:
     static AmdBlasHelper & getInstance()
     {
-        static AmdBlasHelper amdBlas;
-        return amdBlas;
+        CV_SINGLETON_LAZY_INIT_REF(AmdBlasHelper, new AmdBlasHelper())
     }
 
     bool isAvailable() const
@@ -1533,35 +1532,36 @@ protected:
     {
         if (!g_isAmdBlasInitialized)
         {
-            AutoLock lock(m);
+            AutoLock lock(getInitializationMutex());
 
-            if (!g_isAmdBlasInitialized && haveOpenCL())
+            if (!g_isAmdBlasInitialized)
             {
-                try
+                if (haveOpenCL())
                 {
-                    g_isAmdBlasAvailable = clAmdBlasSetup() == clAmdBlasSuccess;
+                    try
+                    {
+                        g_isAmdBlasAvailable = clAmdBlasSetup() == clAmdBlasSuccess;
+                    }
+                    catch (...)
+                    {
+                        g_isAmdBlasAvailable = false;
+                    }
                 }
-                catch (...)
-                {
+                else
                     g_isAmdBlasAvailable = false;
-                }
-            }
-            else
-                g_isAmdBlasAvailable = false;
 
-            g_isAmdBlasInitialized = true;
+                g_isAmdBlasInitialized = true;
+            }
         }
     }
 
 private:
-    static Mutex m;
     static bool g_isAmdBlasInitialized;
     static bool g_isAmdBlasAvailable;
 };
 
 bool AmdBlasHelper::g_isAmdBlasAvailable = false;
 bool AmdBlasHelper::g_isAmdBlasInitialized = false;
-Mutex AmdBlasHelper::m;
 
 bool haveAmdBlas()
 {
@@ -1584,8 +1584,7 @@ class AmdFftHelper
 public:
     static AmdFftHelper & getInstance()
     {
-        static AmdFftHelper amdFft;
-        return amdFft;
+        CV_SINGLETON_LAZY_INIT_REF(AmdFftHelper, new AmdFftHelper())
     }
 
     bool isAvailable() const
@@ -1607,34 +1606,36 @@ protected:
     {
         if (!g_isAmdFftInitialized)
         {
-            AutoLock lock(m);
+            AutoLock lock(getInitializationMutex());
 
-            if (!g_isAmdFftInitialized && haveOpenCL())
+            if (!g_isAmdFftInitialized)
             {
-                try
+                if (haveOpenCL())
                 {
-                    cl_uint major, minor, patch;
-                    CV_Assert(clAmdFftInitSetupData(&setupData) == CLFFT_SUCCESS);
+                    try
+                    {
+                        cl_uint major, minor, patch;
+                        CV_Assert(clAmdFftInitSetupData(&setupData) == CLFFT_SUCCESS);
 
-                    // it throws exception in case AmdFft binaries are not found
-                    CV_Assert(clAmdFftGetVersion(&major, &minor, &patch) == CLFFT_SUCCESS);
-                    g_isAmdFftAvailable = true;
+                        // it throws exception in case AmdFft binaries are not found
+                        CV_Assert(clAmdFftGetVersion(&major, &minor, &patch) == CLFFT_SUCCESS);
+                        g_isAmdFftAvailable = true;
+                    }
+                    catch (const Exception &)
+                    {
+                        g_isAmdFftAvailable = false;
+                    }
                 }
-                catch (const Exception &)
-                {
+                else
                     g_isAmdFftAvailable = false;
-                }
-            }
-            else
-                g_isAmdFftAvailable = false;
 
-            g_isAmdFftInitialized = true;
+                g_isAmdFftInitialized = true;
+            }
         }
     }
 
 private:
     static clAmdFftSetupData setupData;
-    static Mutex m;
     static bool g_isAmdFftInitialized;
     static bool g_isAmdFftAvailable;
 };
@@ -1642,7 +1643,6 @@ private:
 clAmdFftSetupData AmdFftHelper::setupData;
 bool AmdFftHelper::g_isAmdFftAvailable = false;
 bool AmdFftHelper::g_isAmdFftInitialized = false;
-Mutex AmdFftHelper::m;
 
 bool haveAmdFft()
 {
@@ -5237,15 +5237,9 @@ public:
     MatAllocator* matStdAllocator;
 };
 
-// This line should not force OpenCL runtime initialization! (don't put "new OpenCLAllocator()" here)
-static MatAllocator *ocl_allocator = NULL;
 MatAllocator* getOpenCLAllocator()
 {
-    if (ocl_allocator == NULL)
-    {
-        ocl_allocator = new OpenCLAllocator();
-    }
-    return ocl_allocator;
+    CV_SINGLETON_LAZY_INIT(MatAllocator, new OpenCLAllocator())
 }
 
 }} // namespace cv::ocl
index 88b60e4..d8d7e00 100644 (file)
@@ -295,6 +295,22 @@ TLSData<CoreTLSData>& getCoreTlsData();
 extern bool __termination; // skip some cleanups, because process is terminating
                            // (for example, if ExitProcess() was already called)
 
+cv::Mutex& getInitializationMutex();
+
+// TODO Memory barriers?
+#define CV_SINGLETON_LAZY_INIT_(TYPE, INITIALIZER, RET_VALUE) \
+    static TYPE* volatile instance = NULL; \
+    if (instance == NULL) \
+    { \
+        cv::AutoLock lock(cv::getInitializationMutex()); \
+        if (instance == NULL) \
+            instance = INITIALIZER; \
+    } \
+    return RET_VALUE;
+
+#define CV_SINGLETON_LAZY_INIT(TYPE, INITIALIZER) CV_SINGLETON_LAZY_INIT_(TYPE, INITIALIZER, instance)
+#define CV_SINGLETON_LAZY_INIT_REF(TYPE, INITIALIZER) CV_SINGLETON_LAZY_INIT_(TYPE, INITIALIZER, *instance)
+
 }
 
 #include "opencv2/hal/intrin.hpp"
index 46f41dc..6a85c40 100644 (file)
 
 #include "precomp.hpp"
 
+namespace cv {
+
+static Mutex* __initialization_mutex = NULL;
+Mutex& getInitializationMutex()
+{
+    if (__initialization_mutex == NULL)
+        __initialization_mutex = new Mutex();
+    return *__initialization_mutex;
+}
+// force initialization (single-threaded environment)
+Mutex* __initialization_mutex_initializer = &getInitializationMutex();
+
+} // namespace cv
+
 #ifdef _MSC_VER
 # if _MSC_VER >= 1700
 #  pragma warning(disable:4447) // Disable warning 'main' signature found without threading model
@@ -1108,8 +1122,7 @@ public:
 // For more information: http://www.parashift.com/c++-faq/static-init-order-on-first-use.html
 static TLSContainerStorage& getTLSContainerStorage()
 {
-    static TLSContainerStorage *tlsContainerStorage = new TLSContainerStorage();
-    return *tlsContainerStorage;
+    CV_SINGLETON_LAZY_INIT_REF(TLSContainerStorage, new TLSContainerStorage())
 }
 
 TLSDataContainer::TLSDataContainer()
@@ -1153,20 +1166,16 @@ TLSStorage::~TLSStorage()
 }
 
 
-
 TLSData<CoreTLSData>& getCoreTlsData()
 {
-    static TLSData<CoreTLSData> *value = new TLSData<CoreTLSData>();
-    return *value;
+    CV_SINGLETON_LAZY_INIT_REF(TLSData<CoreTLSData>, new TLSData<CoreTLSData>())
 }
 
 
-
 #ifdef CV_COLLECT_IMPL_DATA
 ImplCollector& getImplData()
 {
-    static ImplCollector *value = new ImplCollector();
-    return *value;
+    CV_SINGLETON_LAZY_INIT_REF(ImplCollector, new ImplCollector())
 }
 
 void setImpl(int flags)