From 18cad2e78602aa5f55f04926c327a7864d67b756 Mon Sep 17 00:00:00 2001
From: Pietro Incardona <incardon@mpi-cbg.de>
Date: Tue, 27 Oct 2015 12:45:22 +0100
Subject: [PATCH] Memleak_check move

---
 src/Makefile.am          |   6 +-
 src/Memleak_check.cpp    |  21 +++++
 src/Memleak_check.hpp    | 180 +++++++++++++++++++++++++++++++++++++++
 src/memory/PtrMemory.hpp |  13 ---
 4 files changed, 204 insertions(+), 16 deletions(-)
 create mode 100644 src/Memleak_check.cpp
 create mode 100644 src/Memleak_check.hpp

diff --git a/src/Makefile.am b/src/Makefile.am
index 61cb880..4139c08 100755
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -8,17 +8,17 @@ else
 endif
 
 noinst_PROGRAMS = mem
-mem_SOURCES = main.cpp memory/HeapMemory.cpp $(CUDA_SOURCES)
+mem_SOURCES = main.cpp memory/HeapMemory.cpp $(CUDA_SOURCES) Memleak_check.cpp
 mem_CXXFLAGS = $(INCLUDES_PATH) $(BOOST_CPPFLAGS) -I/usr/local/include
 mem_CFLAGS = 
 mem_LDADD = $(LINKLIBS) -L/usr/lib64/nvidia-bumblebee/
 
 lib_LIBRARIES = libofpmmemory.a
-libofpmmemory_a_SOURCES = memory/HeapMemory.cpp $(CUDA_SOURCES) memory/PtrMemory.cpp
+libofpmmemory_a_SOURCES = memory/HeapMemory.cpp $(CUDA_SOURCES) memory/PtrMemory.cpp Memleak_check.cpp
 libofpmmemory_a_CXXFLAGS = $(INCLUDES_PATH) $(BOOST_CPPFLAGS) -I/usr/local/include
 libofpmmemory_a_CFLAGS =
 
-nobase_include_HEADERS = memory/ExtPreAlloc.hpp memory/HeapMemory.hpp memory/memory.hpp memory/PreAllocHeapMemory.hpp memory/PtrMemory.hpp
+nobase_include_HEADERS = memory/ExtPreAlloc.hpp memory/HeapMemory.hpp memory/memory.hpp memory/PreAllocHeapMemory.hpp memory/PtrMemory.hpp Memleak_check.hpp
 
 .cu.o :
 	$(NVCC) $(NVCCFLAGS) -I. $(INCLUDES_PATH) -o $@ -c $<
diff --git a/src/Memleak_check.cpp b/src/Memleak_check.cpp
new file mode 100644
index 0000000..0561bde
--- /dev/null
+++ b/src/Memleak_check.cpp
@@ -0,0 +1,21 @@
+#include "config.h"
+#include "Memleak_check.hpp"
+
+#ifdef SE_CLASS2
+
+// counter for allocation of new memory
+size_t new_data;
+
+// counter to delete memory
+size_t delete_data;
+
+// structure that store all the active pointer
+std::map<byte_ptr, size_t> active_ptr;
+
+// Running process id
+long int process_v_cl;
+
+// Process to print
+long int process_to_print = 0;
+
+#endif
diff --git a/src/Memleak_check.hpp b/src/Memleak_check.hpp
new file mode 100644
index 0000000..24afa91
--- /dev/null
+++ b/src/Memleak_check.hpp
@@ -0,0 +1,180 @@
+#include "config.h"
+#include <iostream>
+#include <map>
+
+#ifndef MEMLEAK_CHECK_HPP
+#define MEMLEAK_CHECK_HPP
+
+typedef unsigned char * byte_ptr;
+
+#ifdef SE_CLASS2
+
+#include "util/se_util.hpp"
+
+#define MEM_ERROR 1300lu
+
+extern size_t new_data;
+extern size_t delete_data;
+
+extern std::map<byte_ptr,size_t> active_ptr;
+
+extern long int process_v_cl;
+extern long int process_to_print;
+
+/*! \brief Check and remove the active pointer
+ *
+ * Check and remove the pointer from the active list
+ *
+ * \param pointer to check and remove
+ *
+ * \return true if the operation succeded, false if the pointer does not exist
+ *
+ */
+static bool remove_ptr(const void * ptr)
+{
+	// Check if the pointer exist
+	std::map<byte_ptr, size_t>::iterator it = active_ptr.find((byte_ptr)ptr);
+
+	// if the element does not exist, print that something wrong happened and return
+	if ( it == active_ptr.end() )
+	{
+		std::cout << "Error pointer not found " << ptr << "\n";
+		ACTION_ON_ERROR(MEM_ERROR);
+		return false;
+	}
+
+	// erase the pointer
+	active_ptr.erase((byte_ptr)ptr);
+
+	return true;
+}
+
+/*! \brief Print all active pointer
+ *
+ * Print all active pointer
+ *
+ */
+static void print_unalloc()
+{
+	for (std::map<byte_ptr,size_t>::iterator it = active_ptr.begin(); it != active_ptr.end(); ++it)
+	{
+		std::cout << "Unallocated memory " << it->first << "     size " << it->second << "\n";
+	}
+}
+
+
+/*! \brief Add the new allocated active pointer
+ *
+ * Add the new allocated active pointer
+ *
+ * \param new data active pointer
+ * \param sz size of the new allocated memory
+ *
+ */
+static bool check_new(const void * data, size_t sz)
+{
+	// Add a new pointer
+	new_data++;
+	active_ptr[(byte_ptr)data] = sz;
+
+#ifdef SE_CLASS2_VERBOSE
+	if (process_to_print < 0 || process_to_print == process_v_cl)
+		std::cout << "New data: " << new_data << "   " << data << "\n";
+#endif
+
+	return true;
+}
+
+/*! \brief check and delete a pointer
+ *
+ * check and delete a pointer from the list of active pointers
+ *
+ * \param pointer data
+ * \return true if the operation to delete succeed
+ *
+ */
+static bool check_delete(const void * data)
+{
+	if (data == NULL)	return true;
+	// Delete the pointer
+	delete_data++;
+	bool result = remove_ptr(data);
+
+#ifdef SE_CLASS2_VERBOSE
+	if (process_to_print < 0 || process_to_print == process_v_cl)
+		std::cout << "Delete data: " << delete_data << "   " << data << "\n";
+#endif
+
+	return result;
+}
+
+/*! \brief check if the access is valid
+ *
+ * check if the access is valid
+ *
+ * \param ptr pointer we are going to access
+ * \param size_access is the size in byte of the data we are fetching
+ *
+ * \return true if the pointer is valid
+ *
+ */
+static bool check_valid(const void * ptr, size_t size_access)
+{
+	// get the lower bound
+
+	std::map<byte_ptr, size_t>::iterator l_b = active_ptr.upper_bound((byte_ptr)ptr);
+
+	if (active_ptr.size() == 0)
+	{
+		std::cout << "Error invalid pointer: " << __FILE__ << ":" << __LINE__ << "  " << ptr << "\n";
+		ACTION_ON_ERROR(MEM_ERROR);
+		return false;
+	}
+
+	//! subtract one
+	l_b--;
+
+	// if there is no memory that satisfy the request
+	if (l_b == active_ptr.end())
+	{
+		if (process_to_print < 0 || process_to_print == process_v_cl)
+		{
+			std::cout << "Error invalid pointer: " << __FILE__ << ":" << __LINE__ << "  " << ptr << "\n";
+			ACTION_ON_ERROR(MEM_ERROR);
+		}
+		return false;
+	}
+
+	// check if ptr is in the range
+
+	size_t sz = l_b->second;
+
+	if (((unsigned char *)l_b->first) + sz < ((unsigned char *)ptr) + size_access)
+	{
+		if (process_to_print < 0 || process_to_print == process_v_cl)
+		{
+			std::cout << "Error invalid pointer: " << __FILE__ << ":" << __LINE__ << "  "  << ptr << "\n";
+			ACTION_ON_ERROR(MEM_ERROR);
+			return false;
+		}
+	}
+
+	return true;
+}
+
+/*! \brief In case of Parallel application it set the process that print the
+ *
+ * \param p_to_print is < 0 (Mean all)
+ *
+ */
+static void set_process_to_print(long int p_to_print)
+{
+	process_to_print = p_to_print;
+}
+
+#else
+
+
+
+#endif
+#endif
diff --git a/src/memory/PtrMemory.hpp b/src/memory/PtrMemory.hpp
index a725d58..4fa91b8 100644
--- a/src/memory/PtrMemory.hpp
+++ b/src/memory/PtrMemory.hpp
@@ -104,28 +104,15 @@ public:
 	// Default constructor
 	PtrMemory():spm(0),dm(NULL),sz(0),ref_cnt(0)
 	{
-#ifdef SE_CLASS2
-		if (process_to_print == process_v_cl)
-			std::cout << "Creating PtrMemory: " << this << "\n";
-#endif
 	};
 
 	//! Constructor, we choose a default alignment of 32 for avx
 	PtrMemory(void * ptr, size_t sz):spm(sz),dm(ptr),sz(0),ref_cnt(0)
 	{
-#ifdef SE_CLASS2
-		if (process_to_print == process_v_cl)
-			std::cout << "Creating PtrMemory: " << this << "\n";
-#endif
 	};
 
 	~PtrMemory()
 	{
-#ifdef SE_CLASS2
-		if (process_to_print == process_v_cl)
-			std::cout << "Delete PtrMemory: " << this << "\n";
-#endif
-
 		if(ref_cnt == 0)
 			destroy();
 		else
-- 
GitLab