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