public:
static AmdBlasHelper & getInstance()
{
- static AmdBlasHelper amdBlas;
- return amdBlas;
+ CV_SINGLETON_LAZY_INIT_REF(AmdBlasHelper, new AmdBlasHelper())
}
bool isAvailable() const
{
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()
{
public:
static AmdFftHelper & getInstance()
{
- static AmdFftHelper amdFft;
- return amdFft;
+ CV_SINGLETON_LAZY_INIT_REF(AmdFftHelper, new AmdFftHelper())
}
bool isAvailable() const
{
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;
};
clAmdFftSetupData AmdFftHelper::setupData;
bool AmdFftHelper::g_isAmdFftAvailable = false;
bool AmdFftHelper::g_isAmdFftInitialized = false;
-Mutex AmdFftHelper::m;
bool haveAmdFft()
{
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
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"
#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
// 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()
}
-
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)