RCFProto

- Main Page
- Classes
- Files

- File List

All Classes Functions Typedefs
Profile.hpp
1
2 //******************************************************************************
3 // RCF - Remote Call Framework
4 //
5 // Copyright (c) 2005 - 2013, Delta V Software. All rights reserved.
6 // http://www.deltavsoft.com
7 //
8 // RCF is distributed under dual licenses - closed source or GPL.
9 // Consult your particular license for conditions of use.
10 //
11 // If you have not purchased a commercial license, you are using RCF
12 // under GPL terms.
13 //
14 // Version: 2.0
15 // Contact: support <at> deltavsoft.com
16 //
17 //******************************************************************************
18
19 #ifndef INCLUDE_UTIL_PROFILE_HPP
20 #define INCLUDE_UTIL_PROFILE_HPP
21
22 #include <sys/types.h>
23 #include <sys/timeb.h>
24
25 #include <iostream>
26 #include <map>
27 #include <memory>
28 #include <sstream>
29 #include <vector>
30
31 #include "RCF/ThreadLibrary.hpp"
32
33 namespace util {
34
35 class ProfilingResults
36 {
37 private:
38 ProfilingResults()
39 {
40 }
41
42 static ProfilingResults *&getSingletonPtrRef()
43 {
44 static ProfilingResults *pProfilingResults = NULL;
45 if (pProfilingResults == NULL)
46 {
47 pProfilingResults = new ProfilingResults();
48 }
49 return pProfilingResults;
50 }
51 public:
52 static ProfilingResults &getSingleton()
53 {
54 return *getSingletonPtrRef();
55 }
56 static void deleteSingleton()
57 {
58 delete getSingletonPtrRef();
59 getSingletonPtrRef() = NULL;
60 }
61 void dump()
62 {
63 RCF::Lock lock(mMutex);
64 for (unsigned int i=0; i<mResults.size(); i++)
65 {
66 std::ostringstream ostr;
67 ostr << "*************************\n";
68 ostr << "Profiling results for thread #" << i << ":\n";
69
70 for (DataT::iterator iter_i = mResults[i]->begin(); iter_i != mResults[i]->end(); iter_i++) {
71 if (!(*iter_i).first.empty()) {
72 ostr << (*iter_i).first << ": " << (*iter_i).second.first / 1000.0 << " s.\n";
73 SubDataT &subData = (*iter_i).second.second;
74 for (SubDataT::iterator iter_j = subData.begin(); iter_j != subData.end(); iter_j++)
75 ostr << " " << (*iter_j).first << ": " << (*iter_j).second / 1000.0 << "s.\n";
76 }
77 }
78
79 ostr << "*************************\n";
80 std::cout << ostr.str();
81 }
82 }
83
84 private:
85 friend class ProfilingData;
86 typedef std::map<std::string, unsigned int> SubDataT;
87 typedef std::map<std::string, std::pair<unsigned int, SubDataT > > DataT;
88
89 RCF::Mutex mMutex;
90 std::vector< DataT * > mResults;
91
92 void add( DataT *data )
93 {
94 RCF::Lock scoped_lock( mMutex );
95 mResults.push_back( data );
96 }
97
98 };
99
100 class ProfilingData
101 {
102 private:
103 ProfilingData() : stack_(100), data_(new DataT()) { ProfilingResults::getSingleton().add( data_ ); }
104 public:
105 static ProfilingData &getThreadSpecificInstance()
106 {
107 static RCF::ThreadSpecificPtr<ProfilingData>::Val profilingData;
108
109 if (NULL == profilingData.get())
110 {
111 profilingData.reset(new ProfilingData());
112 profilingData->push("");
113 }
114 return *profilingData;
115 }
116
117 void push(std::string sz)
118 {
119 stack_.push_back(sz);
120 }
121
122 void pop()
123 {
124 stack_.pop_back();
125 }
126
127 void add(unsigned int timespan)
128 {
129 std::string cur = stack_[stack_.size()-1];
130 std::string prev = stack_[stack_.size()-2];
131 (*data_)[cur].first += timespan;
132 (*data_)[prev].second[cur] += timespan;
133 }
134
135 private:
136 typedef ProfilingResults::DataT DataT;
137 std::vector<std::string> stack_;
138 DataT *data_;
139 };
140
141 inline unsigned int getTickCount()
142 {
143 return RCF::getCurrentTimeMs();
144 }
145
146 class Profile
147 {
148 public:
149 Profile(const std::string &name) : name(name), t0(getTickCount()), t1(0)
150 {
151 ProfilingData::getThreadSpecificInstance().push(name);
152 }
153
154 void stop()
155 {
156 t1 = getTickCount();
157 ProfilingData::getThreadSpecificInstance().add(t1 - t0);
158 ProfilingData::getThreadSpecificInstance().pop();
159 }
160
161
162 ~Profile()
163 {
164 if (!t1)
165 {
166 stop();
167 }
168 }
169
170 int getDurationMs()
171 {
172 RCF_ASSERT(t1);
173 return t1 - t0;
174 }
175
176 private:
177 std::string name;
178 unsigned int t0;
179 unsigned int t1;
180 };
181
182 class ImmediateProfile
183 {
184 public:
185 ImmediateProfile(const std::string &name) :
186 mName(name),
187 t0Ms(getTickCount()),
188 t1Ms()
189 {}
190
191 ~ImmediateProfile()
192 {
193 t1Ms = getTickCount();
194 std::ostringstream ostr;
195 ostr << "Profile result: " << mName << ": " << t1Ms-t0Ms << "ms" << std::endl;
196 std::cout << ostr.str();
197 }
198
199 private:
200 std::string mName;
201 unsigned int t0Ms;
202 unsigned int t1Ms;
203 };
204
205 } // namespace util
206
207 #endif