Warning, /include/Geant4/tools/mem is written in an unsupported language. File is not indexed.
0001 // Copyright (C) 2010, Guy Barrand. All rights reserved.
0002 // See the file tools.license for terms.
0003
0004 #ifndef tools_mem
0005 #define tools_mem
0006
0007 #ifdef TOOLS_MEM
0008 // to count instances.
0009
0010 // WARNING : it uses writable static data, then it is NOT thread safe.
0011 // This class must be used for debugging only.
0012
0013 #include <ostream>
0014 #include <list>
0015 #include <string>
0016 #include <cstring> //strcmp
0017
0018 namespace tools {
0019
0020 class mem {
0021 static const std::string& s_class() {
0022 static const std::string s_v("tools::mem");
0023 return s_v;
0024 }
0025 protected:
0026 mem(){increment(s_class().c_str());}
0027 virtual ~mem(){decrement(s_class().c_str());}
0028 mem(const mem&){}
0029 mem& operator=(const mem&){return *this;}
0030 public:
0031 //static void increment(){counter()++;}
0032 //static void decrement(){counter()--;}
0033
0034 static void increment(const char* a_class){
0035 counter()++;
0036 if(check_by_class()) {
0037 mem_list::iterator it;
0038 for(it=list().begin();it!=list().end();++it) {
0039 if(!::strcmp((*it).first.c_str(),a_class)) {
0040 (*it).second++;
0041 return;
0042 }
0043 }
0044 list().push_back(std::pair<std::string,int>(std::string(a_class),1));
0045 }
0046 }
0047
0048 static void decrement(const char* a_class,unsigned int a_num = 1){
0049 counter() -= a_num;
0050 if(check_by_class()) {
0051 mem_list::iterator it;
0052 for(it=list().begin();it!=list().end();++it) {
0053 if(!::strcmp((*it).first.c_str(),a_class)) {
0054 (*it).second -= a_num;
0055 return;
0056 }
0057 }
0058 list().push_back(std::pair<std::string,int>(std::string(a_class),-int(a_num)));
0059 }
0060 }
0061
0062 static void set_check_by_class(bool a_value) {
0063 check_by_class() = a_value;
0064 }
0065 /*
0066 static void reset();
0067 */
0068
0069 static void balance(std::ostream& a_out){
0070 if(counter()) {
0071 a_out << "tools::mem::balance :"
0072 << " bad global object balance : " << counter()
0073 << std::endl;
0074 if(check_by_class()) {
0075 a_out << "tools::mem::balance :"
0076 << " check by class was enabled."
0077 << std::endl;
0078 } else {
0079 a_out << "tools::mem::balance :"
0080 << " check by class was disabled."
0081 << std::endl;
0082 }
0083 }
0084 mem_list::iterator it;
0085 for(it=list().begin();it!=list().end();++it) {
0086 if((*it).second) {
0087 a_out << "tools::mem::balance :"
0088 << " for class " << (*it).first
0089 << ", bad object balance : " << (*it).second
0090 << std::endl;
0091 }
0092 }
0093 list().clear();
0094 }
0095
0096 protected:
0097 public: //for MT disconnection (see test/mt_root_ntuple.cpp).
0098 static int& counter() {
0099 static int s_count = 0;
0100 return s_count;
0101 }
0102
0103 static bool& check_by_class() {
0104 static bool s_check_by_class = false;
0105 return s_check_by_class;
0106 }
0107 protected:
0108
0109 typedef std::list< std::pair<std::string,int> > mem_list;
0110
0111 static mem_list& list() {
0112 static mem_list* s_list = new mem_list(); //have it on the heap, so that an atexit logic works.
0113 return *s_list;
0114 }
0115 };
0116
0117 inline const std::string& s_new() {
0118 static const std::string s_v("new");
0119 return s_v;
0120 }
0121
0122 inline const std::string& s_malloc() {
0123 static const std::string s_v("malloc");
0124 return s_v;
0125 }
0126
0127 inline const std::string& s_tex() {
0128 static const std::string s_v("tex");
0129 return s_v;
0130 }
0131
0132 inline const std::string& s_gsto() {
0133 static const std::string s_v("gsto");
0134 return s_v;
0135 }
0136
0137 }
0138
0139 #endif
0140
0141 #endif
0142
0143
0144
0145