From d62ef4d0df239790a3ccb304ce6dd85ed399fa74 Mon Sep 17 00:00:00 2001 From: Georgios Pinitas Date: Fri, 19 Feb 2021 19:42:57 +0000 Subject: Close loaded library on OpenCL symbols destruction Although is not needed we call dlclose on the loaded library on destruction to avoid resource leak complains from static analysers Resolves: COMPMID-4170 Signed-off-by: Georgios Pinitas Change-Id: I6047681d04309a5854b2f420f064176625c115e9 Reviewed-on: https://review.mlplatform.org/c/ml/ComputeLibrary/+/5117 Tested-by: Arm Jenkins Reviewed-by: Giorgio Arena Reviewed-by: Manuel Bottini Comments-Addressed: Arm Jenkins --- arm_compute/core/CL/OpenCL.h | 7 +++ src/core/CL/OpenCL.cpp | 113 +++++++++++++++++++++++-------------------- 2 files changed, 68 insertions(+), 52 deletions(-) diff --git a/arm_compute/core/CL/OpenCL.h b/arm_compute/core/CL/OpenCL.h index 155c3e4eef..64b24dba8f 100644 --- a/arm_compute/core/CL/OpenCL.h +++ b/arm_compute/core/CL/OpenCL.h @@ -63,6 +63,12 @@ class CLSymbols final public: /** Default Constructor */ CLSymbols() noexcept(false); + /** Destructor */ + ~CLSymbols(); + /** Prevent instances of this class from being copied (As this class contains pointers) */ + CLSymbols(const CLSymbols &) = delete; + /** Prevent instances of this class from being copied (As this class contains pointers) */ + CLSymbols &operator=(const CLSymbols &) = delete; /** Load OpenCL symbols from handle * * @param[in] handle Handle to load symbols from @@ -144,6 +150,7 @@ public: private: std::pair _loaded; + void *_handle; }; } // namespace arm_compute #endif /* ARM_COMPUTE_OPENCL_H */ diff --git a/src/core/CL/OpenCL.cpp b/src/core/CL/OpenCL.cpp index aff6285697..152759b4df 100644 --- a/src/core/CL/OpenCL.cpp +++ b/src/core/CL/OpenCL.cpp @@ -38,10 +38,19 @@ CLSymbols::CLSymbols() noexcept(false) : _loaded( { false, false -}) +}), +_handle(nullptr) { } +CLSymbols::~CLSymbols() +{ + if(_handle != nullptr) + { + dlclose(_handle); + } +} + CLSymbols &CLSymbols::get() { static CLSymbols symbols; @@ -75,9 +84,9 @@ bool CLSymbols::load_default() bool CLSymbols::load(const std::string &library) { - void *handle = dlopen(library.c_str(), RTLD_LAZY | RTLD_LOCAL); + _handle = dlopen(library.c_str(), RTLD_LAZY | RTLD_LOCAL); - if(handle == nullptr) + if(_handle == nullptr) { std::cerr << "Can't load " << library << ": " << dlerror() << "\n"; // Set status of loading to failed @@ -88,60 +97,60 @@ bool CLSymbols::load(const std::string &library) #define LOAD_FUNCTION_PTR(func_name, handle) \ func_name##_ptr = reinterpret_cast(dlsym(handle, #func_name)); - LOAD_FUNCTION_PTR(clCreateContext, handle); - LOAD_FUNCTION_PTR(clCreateContextFromType, handle); - LOAD_FUNCTION_PTR(clCreateCommandQueue, handle); - LOAD_FUNCTION_PTR(clGetContextInfo, handle); - LOAD_FUNCTION_PTR(clBuildProgram, handle); - LOAD_FUNCTION_PTR(clEnqueueNDRangeKernel, handle); - LOAD_FUNCTION_PTR(clSetKernelArg, handle); - LOAD_FUNCTION_PTR(clReleaseKernel, handle); - LOAD_FUNCTION_PTR(clCreateProgramWithSource, handle); - LOAD_FUNCTION_PTR(clCreateBuffer, handle); - LOAD_FUNCTION_PTR(clRetainKernel, handle); - LOAD_FUNCTION_PTR(clCreateKernel, handle); - LOAD_FUNCTION_PTR(clGetProgramInfo, handle); - LOAD_FUNCTION_PTR(clFlush, handle); - LOAD_FUNCTION_PTR(clFinish, handle); - LOAD_FUNCTION_PTR(clReleaseProgram, handle); - LOAD_FUNCTION_PTR(clRetainContext, handle); - LOAD_FUNCTION_PTR(clCreateProgramWithBinary, handle); - LOAD_FUNCTION_PTR(clReleaseCommandQueue, handle); - LOAD_FUNCTION_PTR(clEnqueueMapBuffer, handle); - LOAD_FUNCTION_PTR(clRetainProgram, handle); - LOAD_FUNCTION_PTR(clGetProgramBuildInfo, handle); - LOAD_FUNCTION_PTR(clEnqueueReadBuffer, handle); - LOAD_FUNCTION_PTR(clEnqueueWriteBuffer, handle); - LOAD_FUNCTION_PTR(clReleaseEvent, handle); - LOAD_FUNCTION_PTR(clReleaseContext, handle); - LOAD_FUNCTION_PTR(clRetainCommandQueue, handle); - LOAD_FUNCTION_PTR(clEnqueueUnmapMemObject, handle); - LOAD_FUNCTION_PTR(clRetainMemObject, handle); - LOAD_FUNCTION_PTR(clReleaseMemObject, handle); - LOAD_FUNCTION_PTR(clGetDeviceInfo, handle); - LOAD_FUNCTION_PTR(clGetDeviceIDs, handle); - LOAD_FUNCTION_PTR(clGetMemObjectInfo, handle); - LOAD_FUNCTION_PTR(clRetainEvent, handle); - LOAD_FUNCTION_PTR(clGetPlatformIDs, handle); - LOAD_FUNCTION_PTR(clGetKernelWorkGroupInfo, handle); - LOAD_FUNCTION_PTR(clGetCommandQueueInfo, handle); - LOAD_FUNCTION_PTR(clGetKernelInfo, handle); - LOAD_FUNCTION_PTR(clGetEventProfilingInfo, handle); - LOAD_FUNCTION_PTR(clSVMAlloc, handle); - LOAD_FUNCTION_PTR(clSVMFree, handle); - LOAD_FUNCTION_PTR(clEnqueueSVMMap, handle); - LOAD_FUNCTION_PTR(clEnqueueSVMUnmap, handle); - LOAD_FUNCTION_PTR(clEnqueueMarker, handle); - LOAD_FUNCTION_PTR(clWaitForEvents, handle); - LOAD_FUNCTION_PTR(clCreateImage, handle); - LOAD_FUNCTION_PTR(clSetKernelExecInfo, handle); + LOAD_FUNCTION_PTR(clCreateContext, _handle); + LOAD_FUNCTION_PTR(clCreateContextFromType, _handle); + LOAD_FUNCTION_PTR(clCreateCommandQueue, _handle); + LOAD_FUNCTION_PTR(clGetContextInfo, _handle); + LOAD_FUNCTION_PTR(clBuildProgram, _handle); + LOAD_FUNCTION_PTR(clEnqueueNDRangeKernel, _handle); + LOAD_FUNCTION_PTR(clSetKernelArg, _handle); + LOAD_FUNCTION_PTR(clReleaseKernel, _handle); + LOAD_FUNCTION_PTR(clCreateProgramWithSource, _handle); + LOAD_FUNCTION_PTR(clCreateBuffer, _handle); + LOAD_FUNCTION_PTR(clRetainKernel, _handle); + LOAD_FUNCTION_PTR(clCreateKernel, _handle); + LOAD_FUNCTION_PTR(clGetProgramInfo, _handle); + LOAD_FUNCTION_PTR(clFlush, _handle); + LOAD_FUNCTION_PTR(clFinish, _handle); + LOAD_FUNCTION_PTR(clReleaseProgram, _handle); + LOAD_FUNCTION_PTR(clRetainContext, _handle); + LOAD_FUNCTION_PTR(clCreateProgramWithBinary, _handle); + LOAD_FUNCTION_PTR(clReleaseCommandQueue, _handle); + LOAD_FUNCTION_PTR(clEnqueueMapBuffer, _handle); + LOAD_FUNCTION_PTR(clRetainProgram, _handle); + LOAD_FUNCTION_PTR(clGetProgramBuildInfo, _handle); + LOAD_FUNCTION_PTR(clEnqueueReadBuffer, _handle); + LOAD_FUNCTION_PTR(clEnqueueWriteBuffer, _handle); + LOAD_FUNCTION_PTR(clReleaseEvent, _handle); + LOAD_FUNCTION_PTR(clReleaseContext, _handle); + LOAD_FUNCTION_PTR(clRetainCommandQueue, _handle); + LOAD_FUNCTION_PTR(clEnqueueUnmapMemObject, _handle); + LOAD_FUNCTION_PTR(clRetainMemObject, _handle); + LOAD_FUNCTION_PTR(clReleaseMemObject, _handle); + LOAD_FUNCTION_PTR(clGetDeviceInfo, _handle); + LOAD_FUNCTION_PTR(clGetDeviceIDs, _handle); + LOAD_FUNCTION_PTR(clGetMemObjectInfo, _handle); + LOAD_FUNCTION_PTR(clRetainEvent, _handle); + LOAD_FUNCTION_PTR(clGetPlatformIDs, _handle); + LOAD_FUNCTION_PTR(clGetKernelWorkGroupInfo, _handle); + LOAD_FUNCTION_PTR(clGetCommandQueueInfo, _handle); + LOAD_FUNCTION_PTR(clGetKernelInfo, _handle); + LOAD_FUNCTION_PTR(clGetEventProfilingInfo, _handle); + LOAD_FUNCTION_PTR(clSVMAlloc, _handle); + LOAD_FUNCTION_PTR(clSVMFree, _handle); + LOAD_FUNCTION_PTR(clEnqueueSVMMap, _handle); + LOAD_FUNCTION_PTR(clEnqueueSVMUnmap, _handle); + LOAD_FUNCTION_PTR(clEnqueueMarker, _handle); + LOAD_FUNCTION_PTR(clWaitForEvents, _handle); + LOAD_FUNCTION_PTR(clCreateImage, _handle); + LOAD_FUNCTION_PTR(clSetKernelExecInfo, _handle); // Third-party extensions - LOAD_FUNCTION_PTR(clImportMemoryARM, handle); + LOAD_FUNCTION_PTR(clImportMemoryARM, _handle); #undef LOAD_FUNCTION_PTR - //Don't call dlclose(handle) or all the symbols will be unloaded ! + //Don't call dlclose(_handle) or all the symbols will be unloaded ! // Disable default loading and set status to successful _loaded = std::make_pair(true, true); -- cgit v1.2.1