DD4hep - The AIDA detector description toolkit for high energy physics experiments
DD4hep  Rev:Unversioneddirectory
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
InstanceCount.cpp
Go to the documentation of this file.
1 // $Id: $
2 //==========================================================================
3 // AIDA Detector description implementation for LCD
4 //--------------------------------------------------------------------------
5 // Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN)
6 // All rights reserved.
7 //
8 // For the licensing terms see $DD4hepINSTALL/LICENSE.
9 // For the list of contributors see $DD4hepINSTALL/doc/CREDITS.
10 //
11 // Author : M.Frank
12 //
13 //==========================================================================
14 
15 // Framework include files
16 #include "DD4hep/InstanceCount.h"
17 #include "DD4hep/Handle.h"
18 #include "DD4hep/Memory.h"
19 // C/C++ include files
20 #include <iostream>
21 #include <iomanip>
22 #include <cstdio>
23 #include <cstdlib>
24 #include <cstring>
25 #include <map>
26 
27 using namespace std;
28 using namespace DD4hep;
29 
31 namespace {
32  typedef InstanceCount::Counter COUNT;
33  typedef std::map<const std::type_info*, COUNT*> TypeCounter;
34  typedef std::map<const std::string*, COUNT*> StringCounter;
35  static bool s_trace_instances = ::getenv("DD4HEP_TRACE") != 0;
36  static dd4hep_ptr<TypeCounter> s_typCounts(new TypeCounter());
37  static dd4hep_ptr<StringCounter> s_strCounts(new StringCounter());
38  static InstanceCount::Counter s_nullCount;
39  static InstanceCount::Counter s_thisCount;
40  static InstanceCount s_counter;
41  inline TypeCounter& types() {
42  return *(s_typCounts.get());
43  }
44  inline StringCounter& strings() {
45  return *(s_strCounts.get());
46  }
47  int s_global = 1;
48  struct _Global {
49  _Global() {}
50  ~_Global() { s_global = 0; }
51  } s_globalObj;
52  int on_exit_destructors() {
53  static bool first = true;
54  if ( first && s_global == 0 && s_trace_instances ) {
55  first = false;
56  ::printf("Static out of order destructors occurred. Reference count table is unreliable.....\n");
57  }
58  return 1;
59  }
60 }
61 
63 InstanceCount::InstanceCount() {
64  s_thisCount.increment();
65 }
67 InstanceCount::~InstanceCount() {
68  s_thisCount.decrement();
69  if (0 == s_thisCount.value()) {
70  StringCounter::iterator i;
71  TypeCounter::iterator j;
72  dump(s_trace_instances ? ALL : NONE);
73  for (i = s_strCounts->begin(); i != s_strCounts->end(); ++i)
74  delete (*i).second;
75  for (j = s_typCounts->begin(); j != s_typCounts->end(); ++j)
76  delete (*j).second;
77  s_strCounts->clear();
78  s_typCounts->clear();
79  }
80 }
82 bool InstanceCount::doTrace() {
83  return s_trace_instances;
84 }
86 void InstanceCount::doTracing(bool value) {
87  s_trace_instances = value;
88 }
90 InstanceCount::Counter* InstanceCount::getCounter(const std::type_info& typ) {
91  Counter* cnt = s_trace_instances ? types()[&typ] : &s_nullCount;
92  return (0 != cnt) ? cnt : types()[&typ] = new Counter();
93 }
94 
96 InstanceCount::Counter* InstanceCount::getCounter(const std::string& typ) {
97  Counter* cnt = s_trace_instances ? strings()[&typ] : &s_nullCount;
98  return (0 != cnt) ? cnt : strings()[&typ] = new Counter();
99 }
100 
102 void InstanceCount::increment(const std::string& typ) {
103  if ( s_global )
104  getCounter(typ)->increment();
105  else
106  on_exit_destructors();
107 }
108 
110 void InstanceCount::decrement(const std::string& typ) {
111  if ( s_global )
112  getCounter(typ)->decrement();
113  else
114  on_exit_destructors();
115 }
116 
118 void InstanceCount::increment(const std::type_info& typ) {
119  if ( s_global )
120  getCounter(typ)->increment();
121  else
122  on_exit_destructors();
123 }
124 
126 void InstanceCount::decrement(const std::type_info& typ) {
127  if ( s_global )
128  getCounter(typ)->decrement();
129  else
130  on_exit_destructors();
131 }
132 
134 void InstanceCount::dump(int typ) {
135  bool need_footer = false;
136  if ((typ & STRING) && s_strCounts.get()) {
137  if (s_strCounts->begin() != s_strCounts->end()) {
138  StringCounter::const_iterator i;
139  std::cout << "+-----------------------------------------------------------------------+" << std::endl;
140  std::cout << "| I n s t a n c e c o u n t e r s b y N A M E |" << std::endl;
141  std::cout << "+----------+------+---------+-------------------------------------------+" << std::endl;
142  std::cout << "| Total | Max | Leaking | Type identifier |" << std::endl;
143  std::cout << "+----------+------+---------+-------------------------------------------+" << std::endl;
144  for (i = s_strCounts->begin(); i != s_strCounts->end(); ++i) {
145  std::cout << "|" << std::setw(10) << (*i).second->total()
146  << "|" << std::setw(6) << (*i).second->maximum()
147  << "|" << std::setw(9) << (*i).second->value()
148  << "|" << (*i).first << std::endl;
149  }
150  need_footer = true;
151  }
152  }
153  if ((typ & TYPEINFO) && s_typCounts.get()) {
154  if (s_typCounts->begin() != s_typCounts->end()) {
155  TypeCounter::const_iterator i;
156  std::cout << "+-----------------------------------------------------------------------+" << std::endl;
157  std::cout << "| I n s t a n c e c o u n t e r s b y T Y P E I N F O |" << std::endl;
158  std::cout << "+----------+------+---------+-------------------------------------------+" << std::endl;
159  std::cout << "| Total | Max | Leaking | Type identifier |" << std::endl;
160  std::cout << "+----------+------+---------+-------------------------------------------+" << std::endl;
161  for (i = s_typCounts->begin(); i != s_typCounts->end(); ++i) {
162  std::cout << "|" << std::setw(10) << (*i).second->total()
163  << "|" << std::setw(6) << (*i).second->maximum()
164  << "|" << std::setw(9) << (*i).second->value()
165  << "|" << typeName(*((*i).first)) << std::endl;
166  }
167  need_footer = true;
168  }
169  }
170  if (need_footer) {
171  std::cout << "+----------+-------+-------------------------------------------+" << std::endl;
172  }
173 }
void decrement()
Decrement counter.
Definition: InstanceCount.h:72
std::string typeName(const std::type_info &type)
ABI information about type names.
Definition: Primitives.cpp:186
Out version of the std auto_ptr implementation base either on auto_ptr or unique_ptr.
Definition: Memory.h:43
void increment()
Increment counter.
Definition: InstanceCount.h:66
Helper to support object counting when debugging memory leaks.
Definition: InstanceCount.h:31
Internal class to could object constructions and destructions.
Definition: InstanceCount.h:50
counter_t value() const
Access counter value.
Definition: InstanceCount.h:76