Main Page   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members  

panda/src/express/profileTimer.cxx

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

Generated on Fri May 2 00:38:33 2003 for Panda by doxygen1.3