Panda3D
 All Classes Functions Variables Enumerations
profileTimer.cxx
00001 // Filename: profileTimer.cxx
00002 // Created by:  
00003 //
00004 ////////////////////////////////////////////////////////////////////
00005 //
00006 // PANDA 3D SOFTWARE
00007 // Copyright (c) Carnegie Mellon University.  All rights reserved.
00008 //
00009 // All use of this software is subject to the terms of the revised BSD
00010 // license.  You should have received a copy of this license along
00011 // with this source code in a file named "LICENSE."
00012 //
00013 ////////////////////////////////////////////////////////////////////
00014 
00015 #include "profileTimer.h"
00016 
00017 #include "pmap.h"
00018 
00019 using namespace std;
00020 
00021 // See ProfileTimer.h for documentation.
00022 
00023 
00024 EXPCL_PANDAEXPRESS ProfileTimer Skyler_timer_global=ProfileTimer("startup");
00025 
00026 ProfileTimer* ProfileTimer::_head;
00027 
00028 ProfileTimer::
00029 ProfileTimer(const char* name, int maxEntries) :
00030   _entries(0),
00031   _autoTimerCount(0) {
00032   // Keep a list of the ProfileTimers, so we can print them:
00033   _next=_head;
00034   _head=this;
00035   if (name) {
00036     init(name, maxEntries);
00037   }
00038 }
00039 
00040 ProfileTimer::
00041 ProfileTimer(const ProfileTimer& other) {
00042   // Add to list:
00043   _next=_head;
00044   _head=this;
00045   // init it:
00046   _name=other._name;
00047   _maxEntries=other._maxEntries;
00048   if (_name) {
00049     init(_name, _maxEntries);
00050   }
00051   // Copy other entries:
00052   _on=other._on;
00053   _elapsedTime=other._elapsedTime;
00054   _autoTimerCount=other._autoTimerCount;
00055   _entryCount=other._entryCount;
00056   if (other._entries) {
00057     memcpy(_entries, other._entries, _entryCount * sizeof(TimerEntry));
00058   }
00059 }
00060 
00061 ProfileTimer::
00062 ~ProfileTimer() {
00063   PANDA_FREE_ARRAY(_entries);
00064   // Remove this from the list:
00065   if (_head==this) {
00066     _head=_next;
00067   } else {
00068     ProfileTimer* p=_head;
00069     ProfileTimer* prior=p;
00070     while (p) {
00071       if (p==this) {
00072         prior->_next=_next;
00073         break;
00074       }
00075       prior=p;
00076       p=p->_next;
00077     }
00078   }
00079 }
00080 
00081 void ProfileTimer::
00082 init(const char* name, int maxEntries) {
00083   _name=name;
00084   _maxEntries=maxEntries;
00085   _entries = (TimerEntry *)PANDA_MALLOC_ARRAY(_maxEntries * sizeof(TimerEntry));
00086   _entryCount=0;
00087   _elapsedTime=0.0;
00088   _on=0.0;
00089 }
00090 
00091 double ProfileTimer::
00092 getTotalTime() const {
00093   double total=0;
00094   int i;
00095   for (i=0; i<_entryCount; ++i) {
00096     TimerEntry& te=_entries[i];
00097     total+=te._time;
00098   }
00099   return total;
00100 }
00101 
00102 void ProfileTimer::
00103 consolidateAllTo(ostream &out) {
00104   ProfileTimer* p=_head;
00105   while (p) {
00106     p->consolidateTo(out);
00107     p=p->_next;
00108   }
00109 }
00110 
00111 void ProfileTimer::
00112 consolidateTo(ostream &out) const {
00113   pmap<string, double> entries;
00114   int i;
00115   for (i=0; i<_entryCount; ++i) {
00116     TimerEntry& te=_entries[i];
00117     entries[te._tag]+=te._time;
00118   }
00119   out << "-------------------------------------------------------------------\n"
00120     << "Profile Timing of " << _name
00121     << "\n\n"; // ...should print data and time too.
00122   double total=0;
00123   {
00124   pmap<string, double>::const_iterator i=entries.begin();
00125   for (;i!=entries.end(); ++i) {
00126     out << "  " << setw(50) << i->first << ": "
00127     << setiosflags(ios::fixed) << setprecision(6) << setw(10) << i->second << "\n";
00128     total+=i->second;
00129   }
00130   }
00131   out << "\n                       [Total Time: "
00132     << setiosflags(ios::fixed) << setprecision(6) << total
00133     << " seconds]\n"
00134     << "-------------------------------------------------------------------\n";
00135   out << endl;
00136 }
00137 
00138 void ProfileTimer::
00139 printAllTo(ostream &out) {
00140   ProfileTimer* p=_head;
00141   while (p) {
00142     p->printTo(out);
00143     p=p->_next;
00144   }
00145 }
00146 
00147 void ProfileTimer::
00148 printTo(ostream &out) const {
00149   out << "-------------------------------------------------------------------\n"
00150     << "Profile Timing of " << _name
00151     << "\n\n"; // ...should print data and time too.
00152   double total=0;
00153   int i;
00154   for (i=0; i<_entryCount; ++i) {
00155     TimerEntry& te=_entries[i];
00156     out << "  " << setw(50) << te._tag << ": "
00157     << setiosflags(ios::fixed) << setprecision(6) << setw(10) << te._time << "\n";
00158     total+=te._time;
00159   }
00160   out << "\n                       [Total Time: "
00161     << setiosflags(ios::fixed) << setprecision(6) << total
00162     << " seconds]\n"
00163     << "-------------------------------------------------------------------\n";
00164   out << endl;
00165 }
00166 
00167 ProfileTimer::AutoTimer::AutoTimer(ProfileTimer& profile, const char* tag) :
00168     _profile(profile) {
00169   _tag=tag;
00170   if (_profile._autoTimerCount) {
00171     // ...this is a nested call to another AutoTimer.
00172     // Assign the time to the prior AutoTimer:
00173     _profile.mark(_profile._entries[_profile._entryCount-1]._tag);
00174   } else {
00175     // ...this is not a nested call.
00176     _profile.mark("other");
00177   }
00178   // Tell the profile that it's in an AutoTimer:
00179   ++_profile._autoTimerCount;
00180   _profile.mark(_tag);
00181 }
00182 
00183 
00184 
 All Classes Functions Variables Enumerations