Files
geant4/source/externals/g4tools/include/tools/mem
T
2021-06-25 16:12:29 +02:00

146 lines
3.3 KiB
Plaintext

// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_mem
#define tools_mem
#ifdef TOOLS_MEM
// to count instances.
// WARNING : it uses writable static data, then it is NOT thread safe.
// This class must be used for debugging only.
#include <ostream>
#include <list>
#include <string>
#include <cstring> //strcmp
namespace tools {
class mem {
static const std::string& s_class() {
static const std::string s_v("tools::mem");
return s_v;
}
protected:
mem(){increment(s_class().c_str());}
virtual ~mem(){decrement(s_class().c_str());}
mem(const mem&){}
mem& operator=(const mem&){return *this;}
public:
//static void increment(){counter()++;}
//static void decrement(){counter()--;}
static void increment(const char* a_class){
counter()++;
if(check_by_class()) {
mem_list::iterator it;
for(it=list().begin();it!=list().end();++it) {
if(!::strcmp((*it).first.c_str(),a_class)) {
(*it).second++;
return;
}
}
list().push_back(std::pair<std::string,int>(std::string(a_class),1));
}
}
static void decrement(const char* a_class,unsigned int a_num = 1){
counter() -= a_num;
if(check_by_class()) {
mem_list::iterator it;
for(it=list().begin();it!=list().end();++it) {
if(!::strcmp((*it).first.c_str(),a_class)) {
(*it).second -= a_num;
return;
}
}
list().push_back(std::pair<std::string,int>(std::string(a_class),-int(a_num)));
}
}
static void set_check_by_class(bool a_value) {
check_by_class() = a_value;
}
/*
static void reset();
*/
static void balance(std::ostream& a_out){
if(counter()) {
a_out << "tools::mem::balance :"
<< " bad global object balance : " << counter()
<< std::endl;
if(check_by_class()) {
a_out << "tools::mem::balance :"
<< " check by class was enabled."
<< std::endl;
} else {
a_out << "tools::mem::balance :"
<< " check by class was disabled."
<< std::endl;
}
}
mem_list::iterator it;
for(it=list().begin();it!=list().end();++it) {
if((*it).second) {
a_out << "tools::mem::balance :"
<< " for class " << (*it).first
<< ", bad object balance : " << (*it).second
<< std::endl;
}
}
list().clear();
}
protected:
public: //for MT disconnection (see test/mt_root_ntuple.cpp).
static int& counter() {
static int s_count = 0;
return s_count;
}
static bool& check_by_class() {
static bool s_check_by_class = false;
return s_check_by_class;
}
protected:
typedef std::list< std::pair<std::string,int> > mem_list;
static mem_list& list() {
static mem_list* s_list = new mem_list(); //have it on the heap, so that an atexit logic works.
return *s_list;
}
};
inline const std::string& s_new() {
static const std::string s_v("new");
return s_v;
}
inline const std::string& s_malloc() {
static const std::string s_v("malloc");
return s_v;
}
inline const std::string& s_tex() {
static const std::string s_v("tex");
return s_v;
}
inline const std::string& s_gsto() {
static const std::string s_v("gsto");
return s_v;
}
}
#endif
#endif