From 3f92b731ae782e2e49932b2990ee2b6b796ae54b Mon Sep 17 00:00:00 2001
From: psychocrypt <psychocryptHPC@gmail.com>
Date: Fri, 15 Mar 2019 17:37:36 +0100
Subject: [PATCH] OpenCL: fix memory leak

Fix a memory leak that the OpenCL programs was not freed correctly.
First solved by @xmrig
---
 xmrstak/backend/amd/OclCryptonightR_gen.cpp | 11 +++--------
 xmrstak/backend/amd/OclCryptonightR_gen.hpp |  2 +-
 xmrstak/backend/amd/amd_gpu/gpu.cpp         | 15 ++++++++-------
 3 files changed, 12 insertions(+), 16 deletions(-)

diff --git a/xmrstak/backend/amd/OclCryptonightR_gen.cpp b/xmrstak/backend/amd/OclCryptonightR_gen.cpp
index 7358e98..ccb836e 100644
--- a/xmrstak/backend/amd/OclCryptonightR_gen.cpp
+++ b/xmrstak/backend/amd/OclCryptonightR_gen.cpp
@@ -135,14 +135,9 @@ static cl_program CryptonightR_build_program(
     xmrstak_algo algo,
     uint64_t height,
     uint32_t precompile_count,
-    cl_kernel old_kernel,
     std::string source_code,
     std::string options)
 {
-    if(old_kernel)
-        clReleaseKernel(old_kernel);
-
-
     std::vector<cl_program> old_programs;
     old_programs.reserve(32);
     {
@@ -253,12 +248,12 @@ static cl_program CryptonightR_build_program(
     return program;
 }
 
-cl_program CryptonightR_get_program(GpuContext* ctx, xmrstak_algo algo, uint64_t height, uint32_t precompile_count, bool background, cl_kernel old_kernel)
+cl_program CryptonightR_get_program(GpuContext* ctx, xmrstak_algo algo, uint64_t height, uint32_t precompile_count, bool background)
 {
 	printer::inst()->print_msg(LDEBUG, "CryptonightR: start %llu released",height);
 
     if (background) {
-        background_exec([=](){ CryptonightR_get_program(ctx, algo, height, precompile_count, false, old_kernel); });
+        background_exec([=](){ CryptonightR_get_program(ctx, algo, height, precompile_count, false); });
         return nullptr;
     }
 
@@ -350,7 +345,7 @@ cl_program CryptonightR_get_program(GpuContext* ctx, xmrstak_algo algo, uint64_t
 
     }
 
-    return CryptonightR_build_program(ctx, algo, height, precompile_count, old_kernel, source, options);
+    return CryptonightR_build_program(ctx, algo, height, precompile_count, source, options);
 }
 
 } // namespace amd
diff --git a/xmrstak/backend/amd/OclCryptonightR_gen.hpp b/xmrstak/backend/amd/OclCryptonightR_gen.hpp
index 5f97d1e..7dce77b 100644
--- a/xmrstak/backend/amd/OclCryptonightR_gen.hpp
+++ b/xmrstak/backend/amd/OclCryptonightR_gen.hpp
@@ -20,7 +20,7 @@ namespace amd
 {
 
 cl_program CryptonightR_get_program(GpuContext* ctx, const xmrstak_algo algo,
-	uint64_t height, uint32_t precompile_count, bool background = false, cl_kernel old_kernel = nullptr);
+	uint64_t height, uint32_t precompile_count, bool background = false);
 
 } // namespace amd
 } // namespace xmrstak
diff --git a/xmrstak/backend/amd/amd_gpu/gpu.cpp b/xmrstak/backend/amd/amd_gpu/gpu.cpp
index 9c9db2e..97aa12b 100644
--- a/xmrstak/backend/amd/amd_gpu/gpu.cpp
+++ b/xmrstak/backend/amd/amd_gpu/gpu.cpp
@@ -339,7 +339,7 @@ size_t InitOpenCLGpu(cl_context opencl_ctx, GpuContext* ctx, const char* source_
 		isWindowsOs = 1;
 #endif
 		options += " -DIS_WINDOWS_OS=" + std::to_string(isWindowsOs);
-		
+
 		if(miner_algo == cryptonight_gpu)
 			options += " -cl-fp32-correctly-rounded-divide-sqrt";
 
@@ -967,20 +967,21 @@ size_t XMRSetJob(GpuContext* ctx, uint8_t* input, size_t input_len, uint64_t tar
             cl_int ret;
             cl_kernel kernel = clCreateKernel(program, "cn1_cryptonight_r", &ret);
 
-            cl_kernel old_kernel = nullptr;
             if (ret != CL_SUCCESS) {
                 printer::inst()->print_msg(LDEBUG, "CryptonightR: clCreateKernel returned error %s", err_to_str(ret));
             }
-            else {
-                old_kernel = Kernels[1];
+            else
+			{
+                cl_kernel old_kernel = Kernels[1];
+				if(old_kernel)
+					clReleaseKernel(old_kernel);
                 Kernels[1] = kernel;
             }
             ctx->ProgramCryptonightR = program;
 
             // Precompile next program in background
-            xmrstak::amd::CryptonightR_get_program(ctx, miner_algo, height + 1, PRECOMPILATION_DEPTH, true, old_kernel);
-            for (int i = 2; i <= PRECOMPILATION_DEPTH; ++i)
-                xmrstak::amd::CryptonightR_get_program(ctx, miner_algo, height + i, PRECOMPILATION_DEPTH, true, nullptr);
+            for (int i = 1; i <= PRECOMPILATION_DEPTH; ++i)
+                xmrstak::amd::CryptonightR_get_program(ctx, miner_algo, height + i, PRECOMPILATION_DEPTH, true);
 
             printer::inst()->print_msg(LDEBUG, "Thread #%zu updated CryptonightR", ctx->deviceIdx);
         }
-- 
GitLab