From b4dc2651a888185688dc16171fde2eab0e3a673c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Radovan=20=C4=8Cerven=C3=BD?= <radovan.cerveny@gmail.com>
Date: Tue, 2 Feb 2016 15:26:50 +0100
Subject: [PATCH] added custom allocator to avoid memory tracking pollution

---
 .../src/measurements/MeasurementFrames.hpp    |  2 ++
 alib2algo/src/measurements/MeasurementNew.cpp | 22 ++++++++++++++-----
 alib2algo/src/measurements/MeasurementNew.hpp | 16 ++++++++++++++
 .../src/measurements/MeasurementTypes.hpp     | 19 ++++++++++++++++
 .../src/measurements/MemoryDataFrame.cpp      |  2 --
 5 files changed, 53 insertions(+), 8 deletions(-)
 create mode 100644 alib2algo/src/measurements/MeasurementNew.hpp

diff --git a/alib2algo/src/measurements/MeasurementFrames.hpp b/alib2algo/src/measurements/MeasurementFrames.hpp
index 65c91d98c3..1d02d63341 100644
--- a/alib2algo/src/measurements/MeasurementFrames.hpp
+++ b/alib2algo/src/measurements/MeasurementFrames.hpp
@@ -30,6 +30,7 @@ struct MemoryDataFrame {
 	size_t current_heap_usage;
 
 	std::string to_string ( );
+
 	// void		to_xml ( );
 
 	static void init ( unsigned, std::vector < MeasurementFrame > & );
@@ -44,6 +45,7 @@ struct TimeDataFrame {
 	std::chrono::microseconds real_duration;
 
 	std::string to_string ( );
+
 	// void		to_xml ( );
 
 	static void init ( unsigned, std::vector < MeasurementFrame > & );
diff --git a/alib2algo/src/measurements/MeasurementNew.cpp b/alib2algo/src/measurements/MeasurementNew.cpp
index c1c24dbf35..4be528a7e7 100644
--- a/alib2algo/src/measurements/MeasurementNew.cpp
+++ b/alib2algo/src/measurements/MeasurementNew.cpp
@@ -4,9 +4,10 @@
 
 #include <cstdlib>
 #include <new>
+#include "MeasurementNew.hpp"
 #include "measurements.hpp"
 
-void * operator new( std::size_t n ) {
+void * operator new( std::size_t n, bool measure ) {
 	void * ptr = nullptr;
 
 	for ( ; ; ) {
@@ -19,8 +20,9 @@ void * operator new( std::size_t n ) {
 			* sptr = n;
 			sptr++;
 
-			 // send it to the engine
-			measurements::memory_hint ( { measurements::MemoryHint::Type::NEW, n } );
+			 // send it to the engine if it does not come from stealth allocation
+			if ( measure )
+				measurements::memory_hint ( { measurements::MemoryHint::Type::NEW, n } );
 
 			return static_cast < void * > ( sptr );
 		}
@@ -35,14 +37,22 @@ void * operator new( std::size_t n ) {
 	}
 }
 
-void operator delete( void * ptr ) noexcept {
+void * operator new( std::size_t n ) {
+	return operator new( n, true );
+}
 
+void operator delete( void * ptr, bool measure ) noexcept {
 	std::size_t * sptr = static_cast < std::size_t * > ( ptr );
 
 	sptr--;
 
-	 // read the block size and send it to the engine
-	measurements::memory_hint ( { measurements::MemoryHint::Type::DELETE, * sptr } );
+	 // read the block size and send it to the engine if it does not come from stealth allocation
+	if ( measure )
+		measurements::memory_hint ( { measurements::MemoryHint::Type::DELETE, * sptr } );
 
 	std::free ( sptr );
 }
+
+void operator delete( void * ptr ) noexcept {
+	operator delete( ptr, false );
+}
diff --git a/alib2algo/src/measurements/MeasurementNew.hpp b/alib2algo/src/measurements/MeasurementNew.hpp
new file mode 100644
index 0000000000..d8f1b18e41
--- /dev/null
+++ b/alib2algo/src/measurements/MeasurementNew.hpp
@@ -0,0 +1,16 @@
+/*
+ * Author: Radovan Cerveny
+ */
+
+#ifndef MEASUREMENT_NEW_HPP_
+#define MEASUREMENT_NEW_HPP_
+
+void * operator new( std::size_t n, bool measure );
+
+void * operator new( std::size_t n );
+
+void operator delete( void * ptr, bool measure ) noexcept;
+
+void operator delete( void * ptr ) noexcept;
+
+#endif /* MEASUREMENT_NEW_HPP_ */
diff --git a/alib2algo/src/measurements/MeasurementTypes.hpp b/alib2algo/src/measurements/MeasurementTypes.hpp
index d47a1d64bc..d5f2cfecd8 100644
--- a/alib2algo/src/measurements/MeasurementTypes.hpp
+++ b/alib2algo/src/measurements/MeasurementTypes.hpp
@@ -6,6 +6,7 @@
 #define MEASUREMENT_TYPES_HPP_
 
 #include <memory>
+#include "MeasurementNew.hpp"
 
 namespace measurements {
 
@@ -18,6 +19,24 @@ std::unique_ptr < T > make_unique ( Args && ... args ) {
 	return std::unique_ptr < T > ( new T ( std::forward < Args > ( args ) ... ) );
 }
 
+template < typename T >
+class stealth_allocator : public std::allocator < T > {
+public:
+	using pointer = T *;
+	using size_type = size_t;
+
+	pointer allocate ( size_type n ) {
+		return static_cast < pointer > ( operator new( n * sizeof ( T ), false ) );
+	}
+
+	void deallocate ( pointer ptr, size_type ) {
+		operator delete( ptr, false );
+	}
+
+	template < typename U >
+	struct rebind { using other = stealth_allocator < U >; };
+};
+
 }
 
 #endif /* MEASUREMENT_TYPES_HPP_ */
diff --git a/alib2algo/src/measurements/MemoryDataFrame.cpp b/alib2algo/src/measurements/MemoryDataFrame.cpp
index 7356331580..da2d054a0a 100644
--- a/alib2algo/src/measurements/MemoryDataFrame.cpp
+++ b/alib2algo/src/measurements/MemoryDataFrame.cpp
@@ -4,8 +4,6 @@
 
 #include "MeasurementFrames.hpp"
 
-#include <iostream>
-
 using namespace std::chrono;
 
 namespace measurements {
-- 
GitLab