Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:13:55

0001 //==========================================================================
0002 //  AIDA Detector description implementation 
0003 //--------------------------------------------------------------------------
0004 // Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN)
0005 // All rights reserved.
0006 //
0007 // For the licensing terms see $DD4hepINSTALL/LICENSE.
0008 // For the list of contributors see $DD4hepINSTALL/doc/CREDITS.
0009 //
0010 // Author     : M.Frank
0011 //
0012 //==========================================================================
0013 
0014 /// Framework include files
0015 #include <DD4hep/InstanceCount.h>
0016 #include <DD4hep/Handle.h>
0017 #include <DD4hep/Memory.h>
0018 
0019 /// C/C++ include files
0020 #include <iostream>
0021 #include <iomanip>
0022 #include <cstdio>
0023 #include <cstdlib>
0024 #include <cstring>
0025 #include <mutex>
0026 #include <map>
0027 
0028 using namespace dd4hep;
0029 
0030 /// Do not clutter global namespace
0031 namespace {
0032   typedef InstanceCount::Counter COUNT;
0033   typedef std::map<const std::type_info*, COUNT*> TypeCounter;
0034   typedef std::map<const std::string*, COUNT*> StringCounter;
0035   static  bool s_trace_instances = ::getenv("DD4HEP_TRACE") != 0;
0036   static  dd4hep_ptr<TypeCounter> s_typCounts(new TypeCounter());
0037   static  dd4hep_ptr<StringCounter> s_strCounts(new StringCounter());
0038   static  InstanceCount::Counter s_nullCount;
0039   static  InstanceCount::Counter s_thisCount;
0040   static  InstanceCount s_counter;
0041   inline  TypeCounter& types() {
0042     return *(s_typCounts.get());
0043   }
0044   inline StringCounter& strings() {
0045     return *(s_strCounts.get());
0046   }
0047   int s_global = 1;
0048   struct _Global {
0049     std::mutex lock;
0050     _Global() {}
0051     ~_Global() { s_global = 0; }
0052   } s_globalObj;
0053   int on_exit_destructors()  {
0054     static bool first = true;
0055     if ( first && s_global == 0 && s_trace_instances )  {
0056       first = false;
0057       ::printf("Static out of order destructors occurred. Reference count table is unreliable.....\n");
0058     }
0059     return 1;
0060   }
0061 }
0062 
0063 /// Standard Constructor
0064 InstanceCount::InstanceCount() {
0065   s_thisCount.increment();
0066 }
0067 
0068 /// Standard destructor
0069 InstanceCount::~InstanceCount() {
0070   s_thisCount.decrement();
0071   if (0 == s_thisCount.value()) {
0072     StringCounter::iterator i;
0073     TypeCounter::iterator j;
0074     dump(s_trace_instances ? ALL : NONE);
0075     for (i = s_strCounts->begin(); i != s_strCounts->end(); ++i)
0076       delete (*i).second;
0077     for (j = s_typCounts->begin(); j != s_typCounts->end(); ++j)
0078       delete (*j).second;
0079     s_strCounts->clear();
0080     s_typCounts->clear();
0081   }
0082 }
0083 
0084 /// Check if tracing is enabled.
0085 bool InstanceCount::doTrace() {
0086   return s_trace_instances;
0087 }
0088 
0089 /// Enable/Disable tracing
0090 void InstanceCount::doTracing(bool value) {
0091   s_trace_instances = value;
0092 }
0093 
0094 /// Access counter object for local caching on optimizations
0095 InstanceCount::Counter* InstanceCount::getCounter(const std::type_info& typ) {
0096   Counter* cnt = s_trace_instances ? types()[&typ] : &s_nullCount;
0097   return (0 != cnt) ? cnt : types()[&typ] = new Counter();
0098 }
0099 
0100 /// Access counter object for local caching on optimizations
0101 InstanceCount::Counter* InstanceCount::getCounter(const std::string& typ) {
0102   Counter* cnt = s_trace_instances ? strings()[&typ] : &s_nullCount;
0103   return (0 != cnt) ? cnt : strings()[&typ] = new Counter();
0104 }
0105 
0106 #define COUNTER_LOCK std::lock_guard<std::mutex> _counter_lock(s_globalObj.lock);
0107 
0108 /// Increment count according to string information
0109 void InstanceCount::increment(const std::string& typ) {
0110   if ( s_global )   {
0111     COUNTER_LOCK
0112     getCounter(typ)->increment();
0113   }
0114   else
0115     on_exit_destructors();
0116 }
0117 
0118 /// Decrement count according to string information
0119 void InstanceCount::decrement(const std::string& typ) {
0120   if ( s_global )   {
0121     COUNTER_LOCK
0122     getCounter(typ)->decrement();
0123   }
0124   else
0125     on_exit_destructors();
0126 }
0127 
0128 /// Increment count according to type information
0129 void InstanceCount::increment(const std::type_info& typ) {
0130   if ( s_global )    {
0131     COUNTER_LOCK
0132     getCounter(typ)->increment();
0133   }
0134   else
0135     on_exit_destructors();
0136 }
0137 
0138 /// Decrement count according to type information
0139 void InstanceCount::decrement(const std::type_info& typ) {
0140   if ( s_global )   {
0141     COUNTER_LOCK
0142     getCounter(typ)->decrement();
0143   }
0144   else
0145     on_exit_destructors();
0146 }
0147 
0148 /// Force dump of counter
0149 void InstanceCount::dump(int typ) {
0150   bool need_footer = false;
0151   if ((typ & STRING) && s_strCounts.get()) {
0152     if ( !s_strCounts->empty() )  {
0153       std::cout << "+--------------------------------------------------------------------------+" << std::endl;
0154       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;
0155       std::cout << "+----------+---------+---------+-------------------------------------------+" << std::endl;
0156       std::cout << "|   Total  |  Max    | Leaking |      Type identifier                      |" << std::endl;
0157       std::cout << "+----------+---------+---------+-------------------------------------------+" << std::endl;
0158       long tot_instances=0, max_instances=0, now_instances=0;
0159       for ( const auto& i : *s_strCounts ) {
0160         std::cout << "|" << std::setw(10) << i.second->total()
0161           << "|" << std::setw(9)  << i.second->maximum()
0162           << "|" << std::setw(9)  << i.second->value()
0163           << "|" << i.first->substr(0,80) << std::endl;
0164         tot_instances += i.second->total();
0165         max_instances += i.second->maximum();
0166         now_instances += i.second->value();
0167       }
0168       std::cout << "+----------+---------+---------+-------------------------------------------+" << std::endl;
0169       std::cout << "|" << std::setw(10) << tot_instances
0170         << "|" << std::setw(9)  << max_instances
0171         << "|" << std::setw(9)  << now_instances
0172         << "|" << "Grand total (Sum of all counters)" << std::endl;
0173       need_footer = true;
0174     }
0175   }
0176   if ((typ & TYPEINFO) && s_typCounts.get()) {
0177     if ( !s_typCounts->empty() ) {
0178       std::cout << "+--------------------------------------------------------------------------+" << std::endl;
0179       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;
0180       std::cout << "+----------+---------+---------+-------------------------------------------+" << std::endl;
0181       std::cout << "|   Total  |  Max    | Leaking |      Type identifier                      |" << std::endl;
0182       std::cout << "+----------+---------+---------+-------------------------------------------+" << std::endl;
0183       long tot_instances=0, max_instances=0, now_instances=0;
0184       for ( const auto& i : *s_typCounts ) {
0185     std::string nam = typeName(*(i.first));
0186         if ( nam.length() > 80 ) nam = nam.substr(0,80)+" ...";
0187         std::cout << "|" << std::setw(10) << i.second->total()
0188           << "|" << std::setw(9)  << i.second->maximum()
0189           << "|" << std::setw(9)  << i.second->value()
0190           << "|" << nam << std::endl;
0191         tot_instances += i.second->total();
0192         max_instances += i.second->maximum();
0193         now_instances += i.second->value();
0194       }
0195       std::cout << "+----------+---------+---------+-------------------------------------------+" << std::endl;
0196       std::cout << "|" << std::setw(10) << tot_instances
0197         << "|" << std::setw(9)  << max_instances
0198         << "|" << std::setw(9)  << now_instances
0199         << "|" << "Grand total (Sum of all counters)" << std::endl;
0200       need_footer = true;
0201     }
0202   }
0203   if (need_footer) {
0204     std::cout << "+----------+-------+-------------------------------------------+" << std::endl;
0205   }
0206 }