30 #include <nsICategoryManager.h>
31 #include <nsIDateTimeFormat.h>
32 #include <nsILocale.h>
33 #include <nsILocaleService.h>
34 #include <nsIObserverService.h>
36 #include <nsAutoPtr.h>
37 #include <nsComponentManagerUtils.h>
38 #include <nsDateTimeFormatCID.h>
39 #include <nsILocalFile.h>
40 #include <nsNetUtil.h>
41 #include <nsServiceManagerUtils.h>
42 #include <nsXPCOMCID.h>
46 #define NS_APPSTARTUP_CATEGORY "app-startup"
47 #define NS_APPSTARTUP_TOPIC "app-startup"
73 mTimerLock = nsAutoLock::NewLock(
"sbTimingServiceTimer::mTimerLock");
74 NS_ENSURE_TRUE(
mTimerLock, NS_ERROR_OUT_OF_MEMORY);
84 NS_IMETHODIMP sbTimingServiceTimer::GetName(nsAString &
aName)
92 NS_IMETHODIMP sbTimingServiceTimer::GetStartTime(PRInt64 *aStartTime)
94 NS_ENSURE_ARG_POINTER(aStartTime);
102 NS_IMETHODIMP sbTimingServiceTimer::GetStopTime(PRInt64 *aStopTime)
104 NS_ENSURE_ARG_POINTER(aStopTime);
112 NS_IMETHODIMP sbTimingServiceTimer::GetTotalTime(PRInt64 *aTotalTime)
114 NS_ENSURE_ARG_POINTER(aTotalTime);
127 : mLoggingLock(nsnull)
128 , mLoggingEnabled(PR_TRUE)
129 , mTimersLock(nsnull)
130 , mResultsLock(nsnull)
140 nsAutoLock::DestroyLock(mLoggingLock);
143 nsAutoLock::DestroyLock(mTimersLock);
146 nsAutoLock::DestroyLock(mResultsLock);
156 const char* aLoaderStr,
158 const nsModuleComponentInfo *aInfo)
160 NS_ENSURE_ARG_POINTER(aCompMgr);
161 NS_ENSURE_ARG_POINTER(aPath);
162 NS_ENSURE_ARG_POINTER(aLoaderStr);
163 NS_ENSURE_ARG_POINTER(aType);
164 NS_ENSURE_ARG_POINTER(aInfo);
166 nsresult rv = NS_ERROR_UNEXPECTED;
167 nsCOMPtr<nsICategoryManager> categoryManager =
168 do_GetService(NS_CATEGORYMANAGER_CONTRACTID, &rv);
169 NS_ENSURE_SUCCESS(rv, rv);
175 PR_TRUE, PR_TRUE, nsnull);
176 NS_ENSURE_SUCCESS(rv, rv);
186 char const *
const fileName = getenv(
"SB_TIMING_SERVICE_LOG");
190 nsCOMPtr<nsILocalFile>
file =
191 do_CreateInstance(NS_LOCAL_FILE_CONTRACTID, &rv);
192 NS_ENSURE_SUCCESS(rv, rv);
194 rv = file->InitWithNativePath(nsDependentCString(fileName));
195 NS_ENSURE_SUCCESS(rv, rv);
197 return CallQueryInterface(file, aFile);
202 mLoggingLock = nsAutoLock::NewLock(
"sbTimingService::mLoggingLock");
203 NS_ENSURE_TRUE(mLoggingLock, NS_ERROR_OUT_OF_MEMORY);
205 mTimersLock = nsAutoLock::NewLock(
"sbTimingService::mTimersLock");
206 NS_ENSURE_TRUE(mTimersLock, NS_ERROR_OUT_OF_MEMORY);
208 mResultsLock = nsAutoLock::NewLock(
"sbTimingService::mResultsLock");
209 NS_ENSURE_TRUE(mResultsLock, NS_ERROR_OUT_OF_MEMORY);
211 PRBool success = mTimers.Init();
212 NS_ENSURE_TRUE(success, NS_ERROR_OUT_OF_MEMORY);
214 success = mResults.Init();
215 NS_ENSURE_TRUE(success, NS_ERROR_OUT_OF_MEMORY);
218 NS_WARN_IF_FALSE(NS_SUCCEEDED(rv),
"CheckEnvironmentVariable failed");
221 do_GetService(
"@mozilla.org/observer-service;1", &rv);
222 NS_ENSURE_SUCCESS(rv, rv);
224 rv = observerService->AddObserver(
this,
"profile-before-change", PR_FALSE);
225 NS_ENSURE_SUCCESS(rv, rv);
231 sbTimingService::GetEnabled(PRBool *aEnabled)
233 NS_ENSURE_ARG_POINTER(aEnabled);
235 nsAutoLock lock(mLoggingLock);
236 *aEnabled = mLoggingEnabled;
241 sbTimingService::SetEnabled(PRBool aEnabled)
243 nsAutoLock lock(mLoggingLock);
244 mLoggingEnabled = aEnabled;
250 sbTimingService::GetLogFile(nsIFile * *aLogFile)
252 NS_ENSURE_ARG_POINTER(aLogFile);
254 nsAutoLock lock(mLoggingLock);
255 NS_ADDREF(*aLogFile = mLogFile);
260 sbTimingService::SetLogFile(nsIFile * aLogFile)
262 NS_ENSURE_ARG_POINTER(aLogFile);
264 nsAutoLock lock(mLoggingLock);
271 sbTimingService::StartPerfTimer(
const nsAString & aTimerName)
273 nsRefPtr<sbTimingServiceTimer> timer;
275 NS_ENSURE_TRUE(timer, NS_ERROR_OUT_OF_MEMORY);
277 nsresult rv = timer->Init(aTimerName);
278 NS_ENSURE_SUCCESS(rv, rv);
280 nsAutoLock lockTimers(mTimersLock);
282 if(mTimers.Get(aTimerName, nsnull)) {
283 return NS_ERROR_ALREADY_INITIALIZED;
286 PRBool success = mTimers.Put(aTimerName, timer);
287 NS_ENSURE_TRUE(success, NS_ERROR_OUT_OF_MEMORY);
293 sbTimingService::StopPerfTimer(
const nsAString & aTimerName, PRInt64 *_retval)
295 NS_ENSURE_ARG_POINTER(_retval);
297 PRTime stopTime = PR_Now();
298 nsCOMPtr<sbITimingServiceTimer> timer;
301 nsAutoLock lockTimers(mTimersLock);
303 if(!mTimers.Get(aTimerName, getter_AddRefs(timer))) {
304 return NS_ERROR_NOT_INITIALIZED;
307 mTimers.Remove(aTimerName);
318 nsAutoLock lockResults(mResultsLock);
319 PRUint32 resultCount = mResults.Count();
321 PRBool success = mResults.Put(resultCount, timer);
322 NS_ENSURE_TRUE(success, NS_ERROR_OUT_OF_MEMORY);
331 const PRUnichar*
aData)
335 do_GetService(NS_OBSERVERSERVICE_CONTRACTID, &rv);
337 nsAutoLock lock(mLoggingLock);
339 if(strcmp(aTopic,
"profile-before-change") == 0) {
341 nsCOMPtr<nsIObserverService> observerService =
342 do_GetService(
"@mozilla.org/observer-service;1", &rv);
343 NS_ENSURE_SUCCESS(rv, rv);
345 rv = observerService->RemoveObserver(
this,
"profile-before-change");
346 NS_ENSURE_SUCCESS(rv, rv);
348 if(mLoggingEnabled) {
352 NS_ENSURE_SUCCESS(rv, rv);
354 printf(
"%s", output.BeginReading());
358 nsCOMPtr<nsIOutputStream> outputStream;
359 rv = NS_NewLocalFileOutputStream(getter_AddRefs(outputStream),
362 NS_ENSURE_SUCCESS(rv, rv);
364 PRUint32 bytesOut = 0;
365 rv = outputStream->Write(output.BeginReading(),
370 nsresult rvclose = outputStream->Close();
373 NS_ENSURE_SUCCESS(rv, rv);
374 NS_ENSURE_TRUE(bytesOut == output.Length(), NS_ERROR_UNEXPECTED);
377 NS_ENSURE_SUCCESS(rvclose, rvclose);
387 nsAutoLock lockResults(mResultsLock);
388 PRUint32 resultCount = mResults.Count();
390 nsresult rv = NS_ERROR_UNEXPECTED;
392 nsCOMPtr<nsILocaleService> localeService =
393 do_GetService(
"@mozilla.org/intl/nslocaleservice;1", &rv);
394 NS_ENSURE_SUCCESS(rv, rv);
396 nsCOMPtr<nsILocale> locale;
397 rv = localeService->GetApplicationLocale(getter_AddRefs(locale));
398 NS_ENSURE_SUCCESS(rv, rv);
400 nsCOMPtr<nsIDateTimeFormat> dateTimeFormat =
401 do_CreateInstance(NS_DATETIMEFORMAT_CONTRACTID, &rv);
403 PRTime startTime = 0;
405 PRTime totalTime = 0;
407 nsCOMPtr<sbITimingServiceTimer> timer;
409 nsString out,
output, timerName;
411 output.AppendLiteral(
"\n\n\t\tsbTimingService Results\n\n");
413 for(PRUint32 current = 0; current < resultCount; ++current) {
414 PRBool success = mResults.Get(current, getter_AddRefs(timer));
415 NS_ENSURE_TRUE(success, NS_ERROR_NOT_AVAILABLE);
417 rv = timer->GetStartTime(&startTime);
418 NS_ENSURE_SUCCESS(rv, rv);
420 rv = timer->GetStopTime(&stopTime);
421 NS_ENSURE_SUCCESS(rv, rv);
423 rv = timer->GetTotalTime(&totalTime);
424 NS_ENSURE_SUCCESS(rv, rv);
426 rv = timer->GetName(timerName);
427 NS_ENSURE_SUCCESS(rv, rv);
429 output.Append(timerName);
430 output.AppendLiteral(
"\t");
432 PRExplodedTime explodedTime = {0};
433 PR_ExplodeTime(startTime, PR_LocalTimeParameters, &explodedTime);
435 rv = dateTimeFormat->FormatPRExplodedTime(locale,
440 NS_ENSURE_SUCCESS(rv, rv);
443 output.AppendLiteral(
" ");
444 output.AppendInt(static_cast<PRInt32>((startTime % PR_USEC_PER_SEC) / PR_USEC_PER_MSEC ));
445 output.AppendLiteral(
"ms\t");
447 PR_ExplodeTime(stopTime, PR_LocalTimeParameters, &explodedTime);
449 rv = dateTimeFormat->FormatPRExplodedTime(locale,
454 NS_ENSURE_SUCCESS(rv, rv);
457 output.AppendLiteral(
" ");
458 output.AppendInt(static_cast<PRInt32>((stopTime % PR_USEC_PER_SEC) / PR_USEC_PER_MSEC ));
459 output.AppendLiteral(
"ms\t");
461 AppendInt(output, totalTime / PR_USEC_PER_MSEC);
462 output.AppendLiteral(
"ms\n");
465 output.AppendLiteral(
"\n\n");
466 aOutput.Assign(NS_ConvertUTF16toUTF8(output));
NS_IMPL_THREADSAFE_ISUPPORTS1(sbTimingServiceTimer, sbITimingServiceTimer) sbTimingServiceTimer
static nsCOMPtr< nsIObserverService > observerService
static nsresult CheckEnvironmentVariable(nsIFile **aFile)
#define NS_APPSTARTUP_CATEGORY
#define SB_TIMINGSERVICE_CONTRACTID
#define SB_TIMINGSERVICE_DESCRIPTION
nsresult FormatResultsToString(nsACString &aOutput)
static NS_METHOD RegisterSelf(nsIComponentManager *aCompMgr, nsIFile *aPath, const char *aLoaderStr, const char *aType, const nsModuleComponentInfo *aInfo)
An interface for running simple, time based, profiling.
nsresult Init(const nsAString &aTimerName)
_updateTextAndScrollDataForFrame aData