1 // TortoiseSVN - a Windows shell extension for easy version control
\r
3 // Copyright (C) 2003-2008 - TortoiseSVN
\r
5 // This program is free software; you can redistribute it and/or
\r
6 // modify it under the terms of the GNU General Public License
\r
7 // as published by the Free Software Foundation; either version 2
\r
8 // of the License, or (at your option) any later version.
\r
10 // This program is distributed in the hope that it will be useful,
\r
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
\r
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
\r
13 // GNU General Public License for more details.
\r
15 // You should have received a copy of the GNU General Public License
\r
16 // along with this program; if not, write to the Free Software Foundation,
\r
17 // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
\r
26 #include "ProfilingInfo.h"
\r
30 //////////////////////////////////////////////////////////////////////
\r
31 /// construction / destruction
\r
32 //////////////////////////////////////////////////////////////////////
\r
34 CRecordProfileEvent::CRecordProfileEvent (CProfilingRecord* aRecord)
\r
40 CRecordProfileEvent::~CRecordProfileEvent()
\r
43 record->Add (__rdtsc() - start);
\r
48 //////////////////////////////////////////////////////////////////////
\r
49 // construction / destruction
\r
50 //////////////////////////////////////////////////////////////////////
\r
52 CProfilingRecord::CProfilingRecord ( const char* name
\r
60 , minValue (ULLONG_MAX)
\r
65 //////////////////////////////////////////////////////////////////////
\r
67 //////////////////////////////////////////////////////////////////////
\r
69 void CProfilingRecord::Add (unsigned __int64 value)
\r
74 if (value < minValue)
\r
76 if (value > maxValue)
\r
80 //////////////////////////////////////////////////////////////////////
\r
82 //////////////////////////////////////////////////////////////////////
\r
84 void CProfilingRecord::Reset()
\r
89 minValue = LLONG_MAX;
\r
93 //////////////////////////////////////////////////////////////////////
\r
94 // construction / destruction
\r
95 //////////////////////////////////////////////////////////////////////
\r
97 CProfilingInfo::CProfilingInfo()
\r
101 CProfilingInfo::~CProfilingInfo(void)
\r
103 if (records.size() > 0)
\r
105 // write profile to file
\r
107 TCHAR buffer [MAX_PATH];
\r
108 if (GetModuleFileNameEx (GetCurrentProcess(), NULL, buffer, MAX_PATH) > 0)
\r
111 std::wstring fileName (buffer);
\r
112 fileName += L".profile";
\r
114 std::string report = GetInstance()->GetReport();
\r
116 CFile file (fileName.c_str(), CFile::modeCreate | CFile::modeWrite );
\r
117 file.Write (report.c_str(), (UINT)report.size());
\r
121 // ignore all file errors etc.
\r
127 for (size_t i = 0; i < records.size(); ++i)
\r
132 //////////////////////////////////////////////////////////////////////
\r
133 // access to default instance
\r
134 //////////////////////////////////////////////////////////////////////
\r
136 CProfilingInfo* CProfilingInfo::GetInstance()
\r
138 static CProfilingInfo instance;
\r
142 //////////////////////////////////////////////////////////////////////
\r
144 //////////////////////////////////////////////////////////////////////
\r
146 static std::string IntToStr (unsigned __int64 value)
\r
149 _ui64toa_s (value, buffer, 100, 10);
\r
151 std::string result = buffer;
\r
152 for (size_t i = 3; i < result.length(); i += 4)
\r
153 result.insert (result.length() - i, 1, ',');
\r
158 std::string CProfilingInfo::GetReport() const
\r
160 enum { LINE_LENGTH = 500 };
\r
162 char lineBuffer [LINE_LENGTH];
\r
163 const char * const format ="%10s%17s%17s%17s%6s %s\t%s\n";
\r
165 std::string result;
\r
166 result.reserve (LINE_LENGTH * records.size());
\r
167 sprintf_s ( lineBuffer, format
\r
168 , "count", "sum", "min", "max"
\r
169 , "line", "name", "file");
\r
170 result += lineBuffer;
\r
172 for ( TRecords::const_iterator iter = records.begin(), end = records.end()
\r
176 unsigned __int64 minValue = (*iter)->GetMinValue();
\r
177 if (minValue == ULLONG_MAX)
\r
180 sprintf_s ( lineBuffer, format
\r
182 , IntToStr ((*iter)->GetCount()).c_str()
\r
183 , IntToStr ((*iter)->GetSum()).c_str()
\r
184 , IntToStr (minValue).c_str()
\r
185 , IntToStr ((*iter)->GetMaxValue()).c_str()
\r
187 , IntToStr ((*iter)->GetLine()).c_str()
\r
188 , (*iter)->GetName()
\r
189 , (*iter)->GetFile());
\r
191 result += lineBuffer;
\r
197 //////////////////////////////////////////////////////////////////////
\r
198 // add a new record
\r
199 //////////////////////////////////////////////////////////////////////
\r
201 CProfilingRecord* CProfilingInfo::Create ( const char* name
\r
205 CProfilingRecord* record = new CProfilingRecord (name, file, line);
\r
206 records.push_back (record);
\r