1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_automation.hxx"
30 
31 
32 #include <tools/time.hxx>
33 #include <tools/string.hxx>
34 #include <unotools/localedatawrapper.hxx>
35 #include <vcl/svapp.hxx>
36 #ifndef _BASIC_TTRESHLP_HXX
37 #include <basic/ttstrhlp.hxx>
38 #endif
39 
40 
41 #include "profiler.hxx"
42 
43 
44 TTProfiler::TTProfiler()
45 : mpStart( NULL )
46 , mpEnd( NULL )
47 , bIsProfileIntervalStarted( sal_False )
48 , bIsProfilingPerCommand( sal_False )
49 , bIsPartitioning( sal_False )
50 , bIsAutoProfiling( sal_False )
51 , pSysDepStatic( NULL )
52 {
53 	InitSysdepProfiler();
54 	mpStart = new ProfileSnapshot;
55 	mpStart->pSysdepProfileSnapshot = NewSysdepSnapshotData();
56 	mpEnd = new ProfileSnapshot;
57 	mpEnd->pSysdepProfileSnapshot = NewSysdepSnapshotData();
58 	StartProfileInterval();
59 }
60 
61 TTProfiler::~TTProfiler()
62 {
63 	if ( IsAutoProfiling() )
64 		StopAutoProfiling();
65 	if ( mpStart )
66 	{
67 		if ( mpStart->pSysdepProfileSnapshot )
68 			DeleteSysdepSnapshotData( mpStart->pSysdepProfileSnapshot );
69 		delete mpStart;
70 		mpStart = NULL;
71 	}
72 	if ( mpEnd )
73 	{
74 		if ( mpEnd->pSysdepProfileSnapshot )
75 			DeleteSysdepSnapshotData( mpEnd->pSysdepProfileSnapshot );
76 		delete mpEnd;
77 		mpEnd = NULL;
78 	}
79 	DeinitSysdepProfiler();
80 }
81 
82 
83 String TTProfiler::GetProfileHeader()
84 {
85 	UniString aReturn;
86 	aReturn += '\n';
87 	if ( !IsAutoProfiling() )
88 		aReturn.AppendAscii("Befehl").Append(TabString(36));
89 
90 	aReturn.AppendAscii("   Zeitdauer");
91 	aReturn.AppendAscii("  Ticks in %");
92 	aReturn.Append( GetSysdepProfileHeader() );
93 	aReturn.AppendAscii("\n");
94 	return aReturn;
95 }
96 
97 
98 void TTProfiler::StartProfileInterval( sal_Bool bReadAnyway )
99 {
100 	if ( !bIsProfileIntervalStarted || bReadAnyway )
101 	{
102 		GetProfileSnapshot( mpStart );
103 		GetSysdepProfileSnapshot( mpStart->pSysdepProfileSnapshot, PROFILE_START );
104 		bIsProfileIntervalStarted = sal_True;
105 	}
106 }
107 
108 String TTProfiler::GetProfileLine( ProfileSnapshot *pStart, ProfileSnapshot *pEnd )
109 {
110 	String aProfileString;
111 
112 	aProfileString += Pad(GetpApp()->GetAppLocaleDataWrapper().getDuration( DIFF( pStart, pEnd, aTime) , sal_True, sal_True ), 12);
113 
114 	sal_uLong nProcessTicks = DIFF( pStart, pEnd, nProcessTicks );
115 	sal_uLong nSystemTicks = DIFF( pStart, pEnd, nSystemTicks );
116 	if ( nSystemTicks )
117 	{
118 		aProfileString += Pad(UniString::CreateFromInt32( (100 * nProcessTicks) / nSystemTicks ), 11);
119 		aProfileString += '%';
120 	}
121 	else
122 		aProfileString += Pad(CUniString("??  "), 12);
123 
124 	return aProfileString;
125 }
126 
127 
128 String TTProfiler::GetProfileLine( String &aPrefix )
129 {
130 	String aProfileString;
131 	if ( IsProfilingPerCommand() || IsAutoProfiling() )
132 	{
133 		aProfileString = aPrefix;
134 		aProfileString += TabString(35);
135 
136 
137 		aProfileString += GetProfileLine( mpStart, mpEnd );
138 		aProfileString += GetSysdepProfileLine( mpStart->pSysdepProfileSnapshot, mpEnd->pSysdepProfileSnapshot );
139 		aProfileString += '\n';
140 	}
141 
142 	return aProfileString;
143 }
144 
145 
146 void TTProfiler::EndProfileInterval()
147 {
148 	GetProfileSnapshot( mpEnd );
149 	GetSysdepProfileSnapshot( mpEnd->pSysdepProfileSnapshot, PROFILE_END );
150 	bIsProfileIntervalStarted = sal_False;
151 }
152 
153 
154 void TTProfiler::GetProfileSnapshot( ProfileSnapshot *pProfileSnapshot )
155 {
156 	pProfileSnapshot->aTime = Time();
157 	pProfileSnapshot->nProcessTicks = Time::GetProcessTicks();
158 	pProfileSnapshot->nSystemTicks = Time::GetSystemTicks();
159 }
160 
161 
162 void TTProfiler::StartProfilingPerCommand()		// Jeden Befehl mitschneiden
163 {
164 	bIsProfilingPerCommand = sal_True;
165 }
166 
167 void TTProfiler::StopProfilingPerCommand()
168 {
169 	bIsProfilingPerCommand = sal_False;
170 }
171 
172 void TTProfiler::StartPartitioning()
173 {
174 	bIsPartitioning = sal_True;
175 }
176 
177 void TTProfiler::StopPartitioning()
178 {
179 	bIsPartitioning = sal_True;
180 }
181 
182 sal_uLong TTProfiler::GetPartitioningTime()
183 {
184 	return DIFF( mpStart, mpEnd, nSystemTicks );
185 }
186 
187 
188 
189 void TTProfiler::StartAutoProfiling( sal_uLong nMSec )
190 {
191 	if ( !bIsAutoProfiling )
192 	{
193 		pAutoStart = new ProfileSnapshot;
194 		pAutoStart->pSysdepProfileSnapshot = NewSysdepSnapshotData();
195 		pAutoEnd = new ProfileSnapshot;
196 		pAutoEnd->pSysdepProfileSnapshot = NewSysdepSnapshotData();
197 		GetProfileSnapshot( pAutoStart );
198 		GetSysdepProfileSnapshot( pAutoStart->pSysdepProfileSnapshot, PROFILE_START );
199 		SetTimeout( nMSec );
200 		bIsAutoProfiling = sal_True;
201 		Start();
202 	}
203 
204 }
205 
206 void TTProfiler::Timeout()
207 {
208 	GetProfileSnapshot( pAutoEnd );
209 	GetSysdepProfileSnapshot( pAutoEnd->pSysdepProfileSnapshot, PROFILE_END );
210 	String aLine;
211 
212 	aLine += GetProfileLine( pAutoStart, pAutoEnd );
213 	aLine += GetSysdepProfileLine( pAutoStart->pSysdepProfileSnapshot, pAutoEnd->pSysdepProfileSnapshot );
214 	aLine += '\n';
215 
216 	aAutoProfileBuffer += aLine;
217 
218 	ProfileSnapshot *pTemp = pAutoStart;		// Tauschen, so da� jetziges Ende n�chsten Start wird
219 	pAutoStart = pAutoEnd;
220 	pAutoEnd = pTemp;
221 
222 	Start();	// Timer neu starten
223 }
224 
225 String TTProfiler::GetAutoProfiling()
226 {
227 	String aTemp(aAutoProfileBuffer);
228 	aAutoProfileBuffer.Erase();
229 	return aTemp;
230 }
231 
232 void TTProfiler::StopAutoProfiling()
233 {
234 	if ( bIsAutoProfiling )
235 	{
236 		Stop();
237 		bIsAutoProfiling = sal_False;
238 	}
239 }
240 
241 
242 
243 //String TTProfiler::Hex( sal_uLong nNr )
244 String TTProfiler::Dec( sal_uLong nNr )
245 {
246 	String aRet(UniString::CreateFromInt32(nNr));
247 	if ( nNr < 100 )
248 	{
249 		aRet = Pad( aRet, 3);
250 		aRet.SearchAndReplaceAll(' ','0');
251 	}
252 	aRet.Insert( ',', aRet.Len() - 2 );
253 	return aRet;
254 }
255 
256 String TTProfiler::Pad( const String aS, xub_StrLen nLen )
257 {
258 	if ( nLen > aS.Len() )
259 		return UniString().Fill( nLen - aS.Len() ).Append( aS );
260 	else
261 		return CUniString(" ").Append( aS );
262 }
263 
264 
265