19 #ifndef INCLUDE_UTIL_PROFILE_HPP
20 #define INCLUDE_UTIL_PROFILE_HPP
22 #include <sys/types.h>
23 #include <sys/timeb.h>
31 #include "RCF/ThreadLibrary.hpp"
37 class ProfilingResults
46 static ProfilingResults *&getSingletonPtrRef()
48 static ProfilingResults *pProfilingResults = NULL;
49 if (pProfilingResults == NULL)
51 pProfilingResults =
new ProfilingResults();
53 return pProfilingResults;
56 std::vector<ProfilingData *> pTlsData;
59 static ProfilingResults &getSingleton()
61 return *getSingletonPtrRef();
63 static void deleteSingleton()
65 delete getSingletonPtrRef();
66 getSingletonPtrRef() = NULL;
70 RCF::Lock lock(mMutex);
71 for (
unsigned int i=0; i<mResults.size(); i++)
73 std::ostringstream ostr;
74 ostr <<
"*************************\n";
75 ostr <<
"Profiling results for thread #" << i <<
":\n";
77 for (DataT::iterator iter_i = mResults[i]->begin(); iter_i != mResults[i]->end(); iter_i++) {
78 if (!(*iter_i).first.empty()) {
79 ostr << (*iter_i).first <<
": " << (*iter_i).second.first / 1000.0 <<
" s.\n";
80 SubDataT &subData = (*iter_i).second.second;
81 for (SubDataT::iterator iter_j = subData.begin(); iter_j != subData.end(); iter_j++)
82 ostr <<
" " << (*iter_j).first <<
": " << (*iter_j).second / 1000.0 <<
"s.\n";
86 ostr <<
"*************************\n";
87 std::cout << ostr.str();
92 friend class ProfilingData;
93 typedef std::map<std::string, unsigned int> SubDataT;
94 typedef std::map<std::string, std::pair<unsigned int, SubDataT > > DataT;
97 std::vector< DataT * > mResults;
99 void add( DataT *data )
101 RCF::Lock scoped_lock( mMutex );
102 mResults.push_back( data );
110 ProfilingData() : stack_(100), data_(new DataT()) { ProfilingResults::getSingleton().add( data_ ); }
118 static ProfilingData &getThreadSpecificInstance()
120 static RCF::ThreadSpecificPtr<ProfilingData>::Val profilingData;
122 if (NULL == profilingData.get())
124 profilingData.reset(
new ProfilingData());
125 ProfilingResults::getSingleton().pTlsData.push_back(profilingData);
126 profilingData->push(
"");
128 return *profilingData;
131 void push(std::string sz)
133 stack_.push_back(sz);
141 void add(
unsigned int timespan)
143 std::string cur = stack_[stack_.size()-1];
144 std::string prev = stack_[stack_.size()-2];
145 (*data_)[cur].first += timespan;
146 (*data_)[prev].second[cur] += timespan;
150 typedef ProfilingResults::DataT DataT;
151 std::vector<std::string> stack_;
155 inline unsigned int getTickCount()
157 return RCF::getCurrentTimeMs();
163 Profile(
const std::string &name) : name(name), t0(getTickCount()), t1(0)
165 ProfilingData::getThreadSpecificInstance().push(name);
171 ProfilingData::getThreadSpecificInstance().add(t1 - t0);
172 ProfilingData::getThreadSpecificInstance().pop();
196 class ImmediateProfile
199 ImmediateProfile(
const std::string &name) :
201 t0Ms(getTickCount()),
207 t1Ms = getTickCount();
208 std::ostringstream ostr;
209 ostr <<
"Profile result: " << mName <<
": " << t1Ms-t0Ms <<
"ms" << std::endl;
210 std::cout << ostr.str();
219 ProfilingResults::~ProfilingResults()
221 for (std::size_t i=0; i<pTlsData.size(); ++i)