Geant4 Cross Reference |
1 // Copyright (C) 2010, Guy Barrand. All rights 1 // Copyright (C) 2010, Guy Barrand. All rights reserved. 2 // See the file tools.license for terms. 2 // See the file tools.license for terms. 3 3 4 #ifndef tools_mem 4 #ifndef tools_mem 5 #define tools_mem 5 #define tools_mem 6 6 7 #ifdef TOOLS_MEM 7 #ifdef TOOLS_MEM 8 // to count instances. 8 // to count instances. 9 9 10 // WARNING : it uses writable static data, the 10 // WARNING : it uses writable static data, then it is NOT thread safe. 11 // This class must be used for debug 11 // This class must be used for debugging only. 12 12 13 #include <ostream> 13 #include <ostream> 14 #include <list> 14 #include <list> 15 #include <string> 15 #include <string> 16 #include <cstring> //strcmp 16 #include <cstring> //strcmp 17 17 18 namespace tools { 18 namespace tools { 19 19 20 class mem { 20 class mem { 21 static const std::string& s_class() { 21 static const std::string& s_class() { 22 static const std::string s_v("tools::mem") 22 static const std::string s_v("tools::mem"); 23 return s_v; 23 return s_v; 24 } 24 } 25 protected: 25 protected: 26 mem(){increment(s_class().c_str());} 26 mem(){increment(s_class().c_str());} 27 virtual ~mem(){decrement(s_class().c_str()); 27 virtual ~mem(){decrement(s_class().c_str());} 28 mem(const mem&){} 28 mem(const mem&){} 29 mem& operator=(const mem&){return *this;} 29 mem& operator=(const mem&){return *this;} 30 public: 30 public: 31 //static void increment(){counter()++;} 31 //static void increment(){counter()++;} 32 //static void decrement(){counter()--;} 32 //static void decrement(){counter()--;} 33 33 34 static void increment(const char* a_class){ 34 static void increment(const char* a_class){ 35 counter()++; 35 counter()++; 36 if(check_by_class()) { 36 if(check_by_class()) { 37 mem_list::iterator it; 37 mem_list::iterator it; 38 for(it=list().begin();it!=list().end();+ 38 for(it=list().begin();it!=list().end();++it) { 39 if(!::strcmp((*it).first.c_str(),a_cla 39 if(!::strcmp((*it).first.c_str(),a_class)) { 40 (*it).second++; 40 (*it).second++; 41 return; 41 return; 42 } 42 } 43 } 43 } 44 list().push_back(std::pair<std::string,i 44 list().push_back(std::pair<std::string,int>(std::string(a_class),1)); 45 } 45 } 46 } 46 } 47 47 48 static void decrement(const char* a_class,un 48 static void decrement(const char* a_class,unsigned int a_num = 1){ 49 counter() -= a_num; 49 counter() -= a_num; 50 if(check_by_class()) { 50 if(check_by_class()) { 51 mem_list::iterator it; 51 mem_list::iterator it; 52 for(it=list().begin();it!=list().end();+ 52 for(it=list().begin();it!=list().end();++it) { 53 if(!::strcmp((*it).first.c_str(),a_cla 53 if(!::strcmp((*it).first.c_str(),a_class)) { 54 (*it).second -= a_num; 54 (*it).second -= a_num; 55 return; 55 return; 56 } 56 } 57 } 57 } 58 list().push_back(std::pair<std::string,i 58 list().push_back(std::pair<std::string,int>(std::string(a_class),-int(a_num))); 59 } 59 } 60 } 60 } 61 61 62 static void set_check_by_class(bool a_value) 62 static void set_check_by_class(bool a_value) { 63 check_by_class() = a_value; 63 check_by_class() = a_value; 64 } 64 } 65 /* 65 /* 66 static void reset(); 66 static void reset(); 67 */ 67 */ 68 68 69 static void balance(std::ostream& a_out){ 69 static void balance(std::ostream& a_out){ 70 if(counter()) { 70 if(counter()) { 71 a_out << "tools::mem::balance :" 71 a_out << "tools::mem::balance :" 72 << " bad global object balance : " 72 << " bad global object balance : " << counter() 73 << std::endl; 73 << std::endl; 74 if(check_by_class()) { 74 if(check_by_class()) { 75 a_out << "tools::mem::balance :" 75 a_out << "tools::mem::balance :" 76 << " check by class was enabled. 76 << " check by class was enabled." 77 << std::endl; 77 << std::endl; 78 } else { 78 } else { 79 a_out << "tools::mem::balance :" 79 a_out << "tools::mem::balance :" 80 << " check by class was disabled 80 << " check by class was disabled." 81 << std::endl; 81 << std::endl; 82 } 82 } 83 } 83 } 84 mem_list::iterator it; 84 mem_list::iterator it; 85 for(it=list().begin();it!=list().end();++i 85 for(it=list().begin();it!=list().end();++it) { 86 if((*it).second) { 86 if((*it).second) { 87 a_out << "tools::mem::balance :" 87 a_out << "tools::mem::balance :" 88 << " for class " << (*it).first 88 << " for class " << (*it).first 89 << ", bad object balance : " << 89 << ", bad object balance : " << (*it).second 90 << std::endl; 90 << std::endl; 91 } 91 } 92 } 92 } 93 list().clear(); 93 list().clear(); 94 } 94 } 95 95 96 protected: 96 protected: 97 public: //for MT disconnection (see test/mt_ro 97 public: //for MT disconnection (see test/mt_root_ntuple.cpp). 98 static int& counter() { 98 static int& counter() { 99 static int s_count = 0; 99 static int s_count = 0; 100 return s_count; 100 return s_count; 101 } 101 } 102 102 103 static bool& check_by_class() { 103 static bool& check_by_class() { 104 static bool s_check_by_class = false; 104 static bool s_check_by_class = false; 105 return s_check_by_class; 105 return s_check_by_class; 106 } 106 } 107 protected: 107 protected: 108 108 109 typedef std::list< std::pair<std::string,int 109 typedef std::list< std::pair<std::string,int> > mem_list; 110 110 111 static mem_list& list() { 111 static mem_list& list() { 112 static mem_list* s_list = new mem_list(); 112 static mem_list* s_list = new mem_list(); //have it on the heap, so that an atexit logic works. 113 return *s_list; 113 return *s_list; 114 } 114 } 115 }; 115 }; 116 116 117 inline const std::string& s_new() { 117 inline const std::string& s_new() { 118 static const std::string s_v("new"); 118 static const std::string s_v("new"); 119 return s_v; 119 return s_v; 120 } 120 } 121 121 122 inline const std::string& s_malloc() { 122 inline const std::string& s_malloc() { 123 static const std::string s_v("malloc"); 123 static const std::string s_v("malloc"); 124 return s_v; 124 return s_v; 125 } 125 } 126 126 127 inline const std::string& s_tex() { 127 inline const std::string& s_tex() { 128 static const std::string s_v("tex"); 128 static const std::string s_v("tex"); 129 return s_v; 129 return s_v; 130 } 130 } 131 131 132 inline const std::string& s_gsto() { 132 inline const std::string& s_gsto() { 133 static const std::string s_v("gsto"); 133 static const std::string s_v("gsto"); 134 return s_v; 134 return s_v; 135 } 135 } 136 136 137 } 137 } 138 138 139 #endif 139 #endif 140 140 141 #endif 141 #endif 142 142 143 143 144 144 145 145