]> git.tdb.fi Git - libs/core.git/blob - source/debug/profiler.cpp
Add Debug::Profiler
[libs/core.git] / source / debug / profiler.cpp
1 /* $Id$
2
3 This file is part of libmspcore
4 Copyright © 2007  Mikko Rasa, Mikkosoft Productions
5 Distributed under the LGPL
6 */
7
8 #include "../core/except.h"
9 #include "../time/units.h"
10 #include "profiler.h"
11
12 using namespace std;
13
14 namespace Msp {
15 namespace Debug {
16
17 Profiler::Profiler():
18         period(0),
19         inner(0)
20 { }
21
22 void Profiler::set_period(unsigned p)
23 {
24         if(p==period)
25                 return;
26
27         period=p;
28         for(map<string, ScopeInfo>::iterator i=scopes.begin(); i!=scopes.end(); ++i)
29         {
30                 ScopeInfo &si=i->second;
31                 if(p==0)
32                         si.history.clear();
33                 else
34                         si.history.assign(period, Time::zero);
35                 si.hist_pos=0;
36         }
37 }
38
39 void Profiler::add_scope(const std::string &name)
40 {
41         if(!scopes.count(name))
42         {
43                 map<string, ScopeInfo>::iterator i=scopes.insert(map<string, ScopeInfo>::value_type(name, ScopeInfo())).first;
44                 i->second.history.resize(period);
45         }
46 }
47
48 ProfilingScope *Profiler::enter(ProfilingScope *ps)
49 {
50         ProfilingScope *old=inner;
51         inner=ps;
52         return old;
53 }
54
55 void Profiler::record(const string &scope_name, const string &parent, const Time::TimeDelta &time, const Time::TimeDelta &child_t)
56 {
57         map<string, ScopeInfo>::iterator i=scopes.find(scope_name);
58         if(i==scopes.end())
59         {
60                 i=scopes.insert(map<string, ScopeInfo>::value_type(scope_name, ScopeInfo())).first;
61                 i->second.history.resize(period);
62         }
63
64         ScopeInfo &si=i->second;
65         ++si.calls;
66         ++si.called_from[parent];
67         si.total_time+=time;
68         si.self_time+=time-child_t;
69         if(period)
70         {
71                 si.avg_time+=(time-si.history[si.hist_pos])/period;
72                 si.history[si.hist_pos++]=time;
73                 if(si.hist_pos>=period)
74                         si.hist_pos-=period;
75         }
76         else
77                 si.avg_time=si.total_time/si.calls;
78 }
79
80 const Profiler::ScopeInfo &Profiler::scope(const string &sn) const
81 {
82         map<string, ScopeInfo>::const_iterator i=scopes.find(sn);
83         if(i==scopes.end())
84                 throw KeyError("Unknown scope");
85
86         return i->second;
87 }
88
89
90 Profiler::ScopeInfo::ScopeInfo():
91         calls(0),
92         hist_pos(0)
93 { }
94
95 } // namespace Debug
96 } // namespace Msp