Commit 53fc5440 authored by Alexander Alekhin's avatar Alexander Alekhin

implement singleton lazy initialization

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