Panda3D
profileTimer.cxx
1 // Filename: profileTimer.cxx
2 // Created by:
3 //
4 ////////////////////////////////////////////////////////////////////
5 //
6 // PANDA 3D SOFTWARE
7 // Copyright (c) Carnegie Mellon University. All rights reserved.
8 //
9 // All use of this software is subject to the terms of the revised BSD
10 // license. You should have received a copy of this license along
11 // with this source code in a file named "LICENSE."
12 //
13 ////////////////////////////////////////////////////////////////////
14 
15 #include "profileTimer.h"
16 
17 #include "pmap.h"
18 
19 using namespace std;
20 
21 // See ProfileTimer.h for documentation.
22 
23 
24 EXPCL_PANDAEXPRESS ProfileTimer Skyler_timer_global=ProfileTimer("startup");
25 
26 ProfileTimer* ProfileTimer::_head;
27 
28 ProfileTimer::
29 ProfileTimer(const char* name, int maxEntries) :
30  _entries(0),
31  _autoTimerCount(0) {
32  // Keep a list of the ProfileTimers, so we can print them:
33  _next=_head;
34  _head=this;
35  if (name) {
36  init(name, maxEntries);
37  }
38 }
39 
40 ProfileTimer::
41 ProfileTimer(const ProfileTimer& other) {
42  // Add to list:
43  _next=_head;
44  _head=this;
45  // init it:
46  _name=other._name;
47  _maxEntries=other._maxEntries;
48  if (_name) {
49  init(_name, _maxEntries);
50  }
51  // Copy other entries:
52  _on=other._on;
53  _elapsedTime=other._elapsedTime;
54  _autoTimerCount=other._autoTimerCount;
55  _entryCount=other._entryCount;
56  if (other._entries) {
57  memcpy(_entries, other._entries, _entryCount * sizeof(TimerEntry));
58  }
59 }
60 
61 ProfileTimer::
62 ~ProfileTimer() {
63  PANDA_FREE_ARRAY(_entries);
64  // Remove this from the list:
65  if (_head==this) {
66  _head=_next;
67  } else {
68  ProfileTimer* p=_head;
69  ProfileTimer* prior=p;
70  while (p) {
71  if (p==this) {
72  prior->_next=_next;
73  break;
74  }
75  prior=p;
76  p=p->_next;
77  }
78  }
79 }
80 
81 void ProfileTimer::
82 init(const char* name, int maxEntries) {
83  _name=name;
84  _maxEntries=maxEntries;
85  _entries = (TimerEntry *)PANDA_MALLOC_ARRAY(_maxEntries * sizeof(TimerEntry));
86  _entryCount=0;
87  _elapsedTime=0.0;
88  _on=0.0;
89 }
90 
91 double ProfileTimer::
92 getTotalTime() const {
93  double total=0;
94  int i;
95  for (i=0; i<_entryCount; ++i) {
96  TimerEntry& te=_entries[i];
97  total+=te._time;
98  }
99  return total;
100 }
101 
102 void ProfileTimer::
103 consolidateAllTo(ostream &out) {
104  ProfileTimer* p=_head;
105  while (p) {
106  p->consolidateTo(out);
107  p=p->_next;
108  }
109 }
110 
111 void ProfileTimer::
112 consolidateTo(ostream &out) const {
113  pmap<string, double> entries;
114  int i;
115  for (i=0; i<_entryCount; ++i) {
116  TimerEntry& te=_entries[i];
117  entries[te._tag]+=te._time;
118  }
119  out << "-------------------------------------------------------------------\n"
120  << "Profile Timing of " << _name
121  << "\n\n"; // ...should print data and time too.
122  double total=0;
123  {
124  pmap<string, double>::const_iterator i=entries.begin();
125  for (;i!=entries.end(); ++i) {
126  out << " " << setw(50) << i->first << ": "
127  << setiosflags(ios::fixed) << setprecision(6) << setw(10) << i->second << "\n";
128  total+=i->second;
129  }
130  }
131  out << "\n [Total Time: "
132  << setiosflags(ios::fixed) << setprecision(6) << total
133  << " seconds]\n"
134  << "-------------------------------------------------------------------\n";
135  out << endl;
136 }
137 
138 void ProfileTimer::
139 printAllTo(ostream &out) {
140  ProfileTimer* p=_head;
141  while (p) {
142  p->printTo(out);
143  p=p->_next;
144  }
145 }
146 
147 void ProfileTimer::
148 printTo(ostream &out) const {
149  out << "-------------------------------------------------------------------\n"
150  << "Profile Timing of " << _name
151  << "\n\n"; // ...should print data and time too.
152  double total=0;
153  int i;
154  for (i=0; i<_entryCount; ++i) {
155  TimerEntry& te=_entries[i];
156  out << " " << setw(50) << te._tag << ": "
157  << setiosflags(ios::fixed) << setprecision(6) << setw(10) << te._time << "\n";
158  total+=te._time;
159  }
160  out << "\n [Total Time: "
161  << setiosflags(ios::fixed) << setprecision(6) << total
162  << " seconds]\n"
163  << "-------------------------------------------------------------------\n";
164  out << endl;
165 }
166 
167 ProfileTimer::AutoTimer::AutoTimer(ProfileTimer& profile, const char* tag) :
168  _profile(profile) {
169  _tag=tag;
170  if (_profile._autoTimerCount) {
171  // ...this is a nested call to another AutoTimer.
172  // Assign the time to the prior AutoTimer:
173  _profile.mark(_profile._entries[_profile._entryCount-1]._tag);
174  } else {
175  // ...this is not a nested call.
176  _profile.mark("other");
177  }
178  // Tell the profile that it's in an AutoTimer:
179  ++_profile._autoTimerCount;
180  _profile.mark(_tag);
181 }
182 
183 
184 
This is our own Panda specialization on the default STL map.
Definition: pmap.h:52
STL namespace.