From 96a4a7b339f7ba2d3a634fc8ca8e9f5fd80e0d41 Mon Sep 17 00:00:00 2001 From: Alexander Alekhin Date: Fri, 22 Nov 2013 14:31:54 +0400 Subject: [PATCH 1/2] ocl: multi-threading: fix bug in intialization --- modules/ocl/src/cl_context.cpp | 45 ++++++++++++++++++++++------------ 1 file changed, 30 insertions(+), 15 deletions(-) diff --git a/modules/ocl/src/cl_context.cpp b/modules/ocl/src/cl_context.cpp index f9111edf16..ee541ce07f 100644 --- a/modules/ocl/src/cl_context.cpp +++ b/modules/ocl/src/cl_context.cpp @@ -187,11 +187,8 @@ static bool parseOpenCLDeviceConfiguration(const std::string& configurationStr, return true; } -static bool __deviceSelected = false; static bool selectOpenCLDevice() { - __deviceSelected = true; - std::string platform; std::vector deviceTypes; std::string deviceName; @@ -526,26 +523,38 @@ private: static ContextImpl* currentContext = NULL; +static bool __deviceSelected = false; + Context* Context::getContext() { if (currentContext == NULL) { - if (!__initialized || !__deviceSelected) + static bool defaultInitiaization = false; + if (!defaultInitiaization) { cv::AutoLock lock(getInitializationMutex()); - if (!__initialized) + try { - if (initializeOpenCLDevices() == 0) + if (!__initialized) { - CV_Error(CV_OpenCLInitError, "OpenCL not available"); + if (initializeOpenCLDevices() == 0) + { + CV_Error(CV_OpenCLInitError, "OpenCL not available"); + } } + if (!__deviceSelected) + { + if (!selectOpenCLDevice()) + { + CV_Error(CV_OpenCLInitError, "Can't select OpenCL device"); + } + } + defaultInitiaization = true; } - if (!__deviceSelected) + catch (...) { - if (!selectOpenCLDevice()) - { - CV_Error(CV_OpenCLInitError, "Can't select OpenCL device"); - } + defaultInitiaization = true; + throw; } } CV_Assert(currentContext != NULL); @@ -739,10 +748,16 @@ int getOpenCLDevices(std::vector &devices, int deviceType, co void setDevice(const DeviceInfo* info) { - if (!__deviceSelected) + try + { + ContextImpl::setContext(info); __deviceSelected = true; - - ContextImpl::setContext(info); + } + catch (...) + { + __deviceSelected = true; + throw; + } } bool supportsFeature(FEATURE_TYPE featureType) From d650efc069b1dad37497712d0c4d0a3defc18149 Mon Sep 17 00:00:00 2001 From: Alexander Alekhin Date: Fri, 22 Nov 2013 14:38:12 +0400 Subject: [PATCH 2/2] ocl: multi-threading: opencl buffer memory guard --- modules/ocl/src/cl_operations.cpp | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/modules/ocl/src/cl_operations.cpp b/modules/ocl/src/cl_operations.cpp index 7ed1a79c8d..032ebe82a4 100644 --- a/modules/ocl/src/cl_operations.cpp +++ b/modules/ocl/src/cl_operations.cpp @@ -192,6 +192,7 @@ void openCLMallocPitchEx(Context *ctx, void **dev_ptr, size_t *pitch, clFinish(getClCommandQueue(ctx)); #endif CheckBuffers data(mainBuffer, size, widthInBytes, height); + cv::AutoLock lock(getInitializationMutex()); __check_buffers.insert(std::pair((cl_mem)*dev_ptr, data)); } #endif @@ -253,10 +254,17 @@ void openCLFree(void *devPtr) bool failBefore = false, failAfter = false; #endif CheckBuffers data; - std::map::iterator i = __check_buffers.find((cl_mem)devPtr); - if (i != __check_buffers.end()) { - data = i->second; + cv::AutoLock lock(getInitializationMutex()); + std::map::iterator i = __check_buffers.find((cl_mem)devPtr); + if (i != __check_buffers.end()) + { + data = i->second; + __check_buffers.erase(i); + } + } + if (data.mainBuffer != NULL) + { #ifdef CHECK_MEMORY_CORRUPTION Context* ctx = Context::getContext(); std::vector checkBefore(__memory_corruption_guard_bytes); @@ -286,7 +294,6 @@ void openCLFree(void *devPtr) clFinish(getClCommandQueue(ctx)); #endif openCLSafeCall(clReleaseMemObject(data.mainBuffer)); - __check_buffers.erase(i); } #if defined(CHECK_MEMORY_CORRUPTION) if (failBefore)