mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-02-18 06:45:33 +00:00
Added nsIStopwatch for timing analysis.
This commit is contained in:
parent
c3c3652080
commit
9531c0b6ae
164
xpcom/ds/nsIStopwatch.idl
Normal file
164
xpcom/ds/nsIStopwatch.idl
Normal file
@ -0,0 +1,164 @@
|
||||
/* -*- Mode: IDL; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*/
|
||||
|
||||
#include "nsIProperties.idl"
|
||||
|
||||
typedef unsigned long PRIntervalTime;
|
||||
|
||||
interface nsIStopwatch;
|
||||
interface nsILog;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsIStopwatchService
|
||||
|
||||
[scriptable, uuid(0aeb95e0-be2c-11d3-93bd-000064657374)]
|
||||
interface nsIStopwatchService : nsIProperties
|
||||
{
|
||||
nsIStopwatch createStopwatch(in string name,
|
||||
in string countUnits,
|
||||
in boolean perThread);
|
||||
void describeTimings(in nsILog output);
|
||||
};
|
||||
|
||||
%{C++
|
||||
#define NS_STOPWATCHSERVICE_CID \
|
||||
{ /* 10231fc0-be2c-11d3-93bd-000064657374 */ \
|
||||
0x10231fc0, \
|
||||
0xbe2c, \
|
||||
0x11d3, \
|
||||
{0x93, 0xbd, 0x00, 0x00, 0x64, 0x65, 0x73, 0x74} \
|
||||
}
|
||||
|
||||
#define NS_STOPWATCHSERVICE_PROGID "component://netscape/stopwatch-service"
|
||||
#define NS_STOPWATCHSERVICE_CLASSNAME "Stopwatch Service"
|
||||
%}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsIStopwatch
|
||||
|
||||
[scriptable, uuid(32c89070-b98b-11d3-93bb-00104ba0fd40)]
|
||||
interface nsIStopwatch : nsISupports
|
||||
{
|
||||
void init(in string name,
|
||||
in string countUnits,
|
||||
in boolean perThread);
|
||||
|
||||
readonly attribute string name;
|
||||
|
||||
void start();
|
||||
|
||||
void stop(in double count, out PRIntervalTime elapsed);
|
||||
|
||||
void reset();
|
||||
|
||||
/**
|
||||
* @param realTimeSamples - units countUnits
|
||||
* @param realTimeMean - units milliseconds
|
||||
* @param realTimeStdDev - units milliseconds
|
||||
*/
|
||||
void getRealTimeStats(out double realTimeSamples,
|
||||
out double realTimeMean,
|
||||
out double realTimeStdDev);
|
||||
|
||||
/**
|
||||
* @param cpuTimeSamples - units countUnits
|
||||
* @param cpuTimeMean - units milliseconds
|
||||
* @param cpuTimeStdDev - units milliseconds
|
||||
*/
|
||||
void getCPUTimeStats(out double cpuTimeSamples,
|
||||
out double cpuTimeMean,
|
||||
out double cpuTimeStdDev);
|
||||
|
||||
void describe(in nsILog log, in string msg);
|
||||
};
|
||||
|
||||
%{C++
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#define NS_STOPWATCH_CID \
|
||||
{ /* 46fa0bc0-b98b-11d3-93bb-00104ba0fd40 */ \
|
||||
0x46fa0bc0, \
|
||||
0xb98b, \
|
||||
0x11d3, \
|
||||
{0x93, 0xbb, 0x00, 0x10, 0x4b, 0xa0, 0xfd, 0x40} \
|
||||
}
|
||||
#define NS_STOPWATCH_PROGID "component://netscape/stopwatch"
|
||||
#define NS_STOPWATCH_CLASSNAME "Stopwatch"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#if (defined(DEBUG) || defined(NS_DEBUG)) && !defined(WIN16)
|
||||
// enable STOPWATCH by default
|
||||
#define NS_ENABLE_STOPWATCH
|
||||
#endif
|
||||
|
||||
#ifdef NS_DISABLE_STOPWATCH
|
||||
// override, if you want DEBUG, but *not* STOPWATCH (for some reason)
|
||||
#undef NS_ENABLE_STOPWATCH
|
||||
#endif
|
||||
|
||||
#ifdef NS_ENABLE_STOPWATCH
|
||||
|
||||
#define NS_DECL_STOPWATCH(_name) nsIStopwatch* _name
|
||||
#define NS_INIT_STOPWATCH(_stopwatch, _countUnits, _perThread) \
|
||||
PR_BEGIN_MACRO \
|
||||
if (_stopwatch == nsnull) { \
|
||||
nsresult _rv; \
|
||||
static NS_DEFINE_CID(kStopwatchServiceCID, NS_STOPWATCHSERVICE_CID); \
|
||||
NS_WITH_SERVICE(nsIStopwatchService, _serv, kStopwatchServiceCID, &_rv); \
|
||||
if (NS_SUCCEEDED(_rv)) { \
|
||||
_rv = _serv->CreateStopwatch(#_stopwatch, _countUnits, _perThread, \
|
||||
&_stopwatch); \
|
||||
PR_ASSERT(NS_SUCCEEDED(_rv)); \
|
||||
} \
|
||||
} \
|
||||
PR_END_MACRO
|
||||
|
||||
#define NS_STOPWATCH_START(_sw) ((_sw)->Start())
|
||||
#define NS_STOPWATCH_STOP(_sw, _cnt, _elapsed) ((_sw)->Stop(_cnt, _elapsed))
|
||||
#define NS_STOPWATCH_RESET(_sw) ((_sw)->Reset())
|
||||
#define NS_STOPWATCH_GETREALTIMESTATS(_sw, _samples, _mean, _sd) \
|
||||
((_sw)->GetRealTimeStats(_samples, _mean, _sd))
|
||||
#define NS_STOPWATCH_GETCPUTIMESTATS(_sw, _samples, _mean, _sd) \
|
||||
((_sw)->GetCPUTimeStats(_samples, _mean, _sd))
|
||||
#define NS_STOPWATCH_DESCRIBE(_sw, _log, _msg) ((_sw)->Describe(_log, _msg))
|
||||
|
||||
#else // !NS_ENABLE_STOPWATCH
|
||||
|
||||
#define NS_DECL_STOPWATCH(_name) void _not_used() // something that can be used with extern
|
||||
#define NS_INIT_STOPWATCH(_stopwatch, _countUnits, _perThread) NS_OK
|
||||
|
||||
#define NS_STOPWATCH_START(_sw) NS_OK
|
||||
#define NS_STOPWATCH_STOP(_sw, _cnt, _elapsed) (*(_elapsed) = 0)
|
||||
#define NS_STOPWATCH_RESET(_sw) NS_OK
|
||||
#define NS_STOPWATCH_GETREALTIMESTATS(_sw, _samples, _mean, _sd) \
|
||||
(*(_samples) = 0, *(_mean) = 0, *(_sd) = 0)
|
||||
#define NS_STOPWATCH_GETCPUTIMESTATS(_sw, _samples, _mean, _sd) \
|
||||
(*(_samples) = 0, *(_mean) = 0, *(_sd) = 0)
|
||||
#define NS_STOPWATCH_DESCRIBE(_sw, _log, _msg) NS_OK
|
||||
|
||||
#endif // !NS_ENABLE_STOPWATCH
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
%}
|
404
xpcom/ds/nsStopwatch.cpp
Normal file
404
xpcom/ds/nsStopwatch.cpp
Normal file
@ -0,0 +1,404 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*/
|
||||
|
||||
#include "nsStopwatch.h"
|
||||
|
||||
#ifdef NS_ENABLE_STOPWATCH
|
||||
|
||||
#include "nsILoggingService.h"
|
||||
#include "prthread.h"
|
||||
#include <math.h>
|
||||
|
||||
extern NS_DECL_LOG(LogInfo);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsStopwatchService
|
||||
|
||||
nsStopwatchService::nsStopwatchService()
|
||||
: mStopwatches(16)
|
||||
{
|
||||
NS_INIT_REFCNT();
|
||||
}
|
||||
|
||||
nsStopwatchService::~nsStopwatchService()
|
||||
{
|
||||
DescribeTimings(LogInfo);
|
||||
}
|
||||
|
||||
NS_IMPL_ISUPPORTS1(nsStopwatchService, nsIStopwatchService)
|
||||
|
||||
nsresult
|
||||
nsStopwatchService::Init()
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_METHOD
|
||||
nsStopwatchService::Create(nsISupports* outer, const nsIID& aIID, void* *aInstancePtr)
|
||||
{
|
||||
nsresult rv;
|
||||
if (outer)
|
||||
return NS_ERROR_NO_AGGREGATION;
|
||||
|
||||
nsStopwatchService* sw = new nsStopwatchService();
|
||||
if (sw == NULL)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
rv = sw->Init();
|
||||
if (NS_FAILED(rv)) {
|
||||
delete sw;
|
||||
return rv;
|
||||
}
|
||||
|
||||
rv = sw->QueryInterface(aIID, aInstancePtr);
|
||||
if (NS_FAILED(rv)) {
|
||||
delete sw;
|
||||
return rv;
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsStopwatchService::CreateStopwatch(const char* name, const char* countUnits,
|
||||
PRBool perThread, nsIStopwatch* *result)
|
||||
{
|
||||
nsStopwatch* sw = new nsStopwatch();
|
||||
if (sw == nsnull)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
NS_ADDREF(sw);
|
||||
nsresult rv = sw->Init(name, countUnits, perThread);
|
||||
if (NS_FAILED(rv)) goto done;
|
||||
rv = Define(name, sw);
|
||||
if (NS_FAILED(rv)) goto done;
|
||||
*result = sw;
|
||||
NS_ADDREF(*result);
|
||||
done:
|
||||
NS_RELEASE(sw);
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsStopwatchService::Define(const char *prop, nsISupports *initialValue)
|
||||
{
|
||||
nsStringKey key(prop);
|
||||
nsCOMPtr<nsIStopwatch> prev = (nsStopwatch*)mStopwatches.Get(&key);
|
||||
NS_ASSERTION(prev == nsnull, "stopwatch redefinition");
|
||||
if (prev != nsnull)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
mStopwatches.Put(&key, initialValue);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsStopwatchService::Undefine(const char *prop)
|
||||
{
|
||||
nsStringKey key(prop);
|
||||
nsCOMPtr<nsIStopwatch> prev = (nsStopwatch*)mStopwatches.Get(&key);
|
||||
NS_ASSERTION(prev != nsnull, "stopwatch undefined");
|
||||
if (prev == nsnull)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
mStopwatches.Remove(&key);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsStopwatchService::Get(const char *prop, const nsIID & uuid, void * *result)
|
||||
{
|
||||
nsStringKey key(prop);
|
||||
nsCOMPtr<nsISupports> sw = (nsStopwatch*)mStopwatches.Get(&key);
|
||||
NS_ASSERTION(sw != nsnull, "stopwatch undefined");
|
||||
if (sw == nsnull)
|
||||
return NS_ERROR_FAILURE;
|
||||
return sw->QueryInterface(uuid, result);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsStopwatchService::Set(const char *prop, nsISupports *value)
|
||||
{
|
||||
nsStringKey key(prop);
|
||||
nsCOMPtr<nsISupports> prev = (nsStopwatch*)mStopwatches.Get(&key);
|
||||
NS_ASSERTION(prev != nsnull, "stopwatch undefined");
|
||||
if (prev == nsnull)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
mStopwatches.Put(&key, value);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsStopwatchService::Has(const char *prop, const nsIID & uuid, nsISupports *value,
|
||||
PRBool *result)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsStopwatch
|
||||
|
||||
nsStopwatch::nsStopwatch()
|
||||
: mName(nsnull),
|
||||
mCountUnits(nsnull),
|
||||
mPerThread(PR_TRUE),
|
||||
mThreadTimingDataIndex(0)
|
||||
{
|
||||
NS_INIT_REFCNT();
|
||||
}
|
||||
|
||||
nsStopwatch::~nsStopwatch()
|
||||
{
|
||||
if (mName) nsCRT::free(mName);
|
||||
if (mCountUnits) nsCRT::free(mCountUnits);
|
||||
}
|
||||
|
||||
NS_IMPL_ISUPPORTS1(nsStopwatch, nsIStopwatch)
|
||||
|
||||
NS_METHOD
|
||||
nsStopwatch::Create(nsISupports* outer, const nsIID& aIID, void* *aInstancePtr)
|
||||
{
|
||||
nsresult rv;
|
||||
if (outer)
|
||||
return NS_ERROR_NO_AGGREGATION;
|
||||
|
||||
nsStopwatch* sw = new nsStopwatch();
|
||||
if (sw == NULL)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
NS_ADDREF(sw);
|
||||
rv = sw->QueryInterface(aIID, aInstancePtr);
|
||||
NS_RELEASE(sw);
|
||||
return rv;
|
||||
}
|
||||
|
||||
void
|
||||
nsStopwatch::TimeUnits(double timeInMilliSeconds,
|
||||
double *adjustedValue, const char* *adjustedUnits,
|
||||
double *factorResult)
|
||||
{
|
||||
double time = timeInMilliSeconds;
|
||||
const char* units = "ms";
|
||||
double factor = 1;
|
||||
if (time < 1) {
|
||||
time *= 1000;
|
||||
factor *= 1000;
|
||||
units = "us";
|
||||
if (time < 1) {
|
||||
time *= 1000;
|
||||
factor *= 1000;
|
||||
units = "ns";
|
||||
}
|
||||
}
|
||||
else if (time > 1000) {
|
||||
time /= 1000;
|
||||
factor /= 1000;
|
||||
units = "sec";
|
||||
if (time > 60) {
|
||||
time /= 60;
|
||||
factor /= 60;
|
||||
units = "min";
|
||||
if (time > 60) {
|
||||
time /= 60;
|
||||
factor /= 60;
|
||||
units = "hours";
|
||||
if (time > 24) {
|
||||
time /= 24;
|
||||
factor /= 24;
|
||||
units = "days";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
*adjustedValue = time;
|
||||
*adjustedUnits = units;
|
||||
*factorResult = factor;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static void PR_CALLBACK
|
||||
DeleteTimingData(void *priv)
|
||||
{
|
||||
nsTimingData* data = (nsTimingData*)priv;
|
||||
delete data;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsStopwatch::Init(const char *name, const char* countUnits, PRBool perThread)
|
||||
{
|
||||
if (mName) nsCRT::free(mName);
|
||||
if (mCountUnits) nsCRT::free(mCountUnits);
|
||||
Reset();
|
||||
|
||||
mName = nsCRT::strdup(name);
|
||||
if (mName == nsnull)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
mCountUnits = nsCRT::strdup(countUnits);
|
||||
if (mCountUnits == nsnull)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
mPerThread = perThread;
|
||||
PRStatus status = PR_NewThreadPrivateIndex(&mThreadTimingDataIndex,
|
||||
DeleteTimingData);
|
||||
if (status != PR_SUCCESS)
|
||||
return NS_ERROR_FAILURE;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsStopwatch::GetName(char * *aName)
|
||||
{
|
||||
*aName = nsCRT::strdup(mName);
|
||||
return *aName ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsStopwatch::Start(void)
|
||||
{
|
||||
nsTimingData* data;
|
||||
if (mPerThread) {
|
||||
data = (nsTimingData*)PR_GetThreadPrivate(mThreadTimingDataIndex);
|
||||
if (data == nsnull) {
|
||||
data = new nsTimingData;
|
||||
if (data == nsnull)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
PRStatus status = PR_SetThreadPrivate(mThreadTimingDataIndex, data);
|
||||
if (status != PR_SUCCESS)
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
}
|
||||
else {
|
||||
data = &mTimingData;
|
||||
}
|
||||
|
||||
PR_ASSERT(data->mStartTime == 0);
|
||||
if (data->mStartTime != 0)
|
||||
return NS_ERROR_FAILURE;
|
||||
data->mStartTime = PR_IntervalNow();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsStopwatch::Stop(double count, PRIntervalTime *elapsedTime)
|
||||
{
|
||||
nsTimingData* data;
|
||||
if (mPerThread)
|
||||
data = (nsTimingData*)PR_GetThreadPrivate(mThreadTimingDataIndex);
|
||||
else
|
||||
data = &mTimingData;
|
||||
|
||||
PR_ASSERT(data->mStartTime != 0);
|
||||
if (data->mStartTime == 0)
|
||||
return NS_ERROR_FAILURE;
|
||||
PRIntervalTime elapsed = PR_IntervalNow();
|
||||
elapsed -= data->mStartTime;
|
||||
data->mStartTime = 0;
|
||||
data->mCount++;
|
||||
data->mTotalTime += elapsed;
|
||||
data->mTotalSquaredTime += elapsed * elapsed;
|
||||
*elapsedTime = elapsed;
|
||||
|
||||
if (mPerThread) {
|
||||
// dump per-thread data into per-log data:
|
||||
mTimingData.mTotalTime += data->mTotalTime;
|
||||
mTimingData.mTotalSquaredTime += data->mTotalSquaredTime;
|
||||
mTimingData.mCount += data->mCount;
|
||||
|
||||
// destroy TLS:
|
||||
PRStatus status = PR_SetThreadPrivate(mThreadTimingDataIndex, nsnull);
|
||||
if (status != PR_SUCCESS)
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsStopwatch::Reset(void)
|
||||
{
|
||||
mTimingData.mStartTime = 0;
|
||||
mTimingData.mTotalTime = 0;
|
||||
mTimingData.mTotalSquaredTime = 0;
|
||||
mTimingData.mCount = 0;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsStopwatch::GetRealTimeStats(double *realTimeSamples, double *realTimeMean, double *realTimeStdDev)
|
||||
{
|
||||
PRUint32 tps = PR_TicksPerSecond();
|
||||
|
||||
*realTimeSamples = mTimingData.mCount;
|
||||
double mean = mTimingData.mTotalTime / mTimingData.mCount;
|
||||
*realTimeMean = (PRIntervalTime)mean * 1000 / tps;
|
||||
double variance = fabs(mTimingData.mTotalSquaredTime / mTimingData.mCount - mean * mean);
|
||||
*realTimeStdDev = sqrt(variance) * 1000 / tps;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsStopwatch::GetCPUTimeStats(double *cpuTimeSamples, double *cpuTimeMean, double *cpuTimeStdDev)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsStopwatch::Describe(nsILog *out, const char* msg)
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
double realTimeSamples, realTimeMean, realTimeStdDev;
|
||||
rv = GetRealTimeStats(&realTimeSamples, &realTimeMean, &realTimeStdDev);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
double mean, factor, stdDev;
|
||||
const char* timeUnits;
|
||||
TimeUnits(realTimeMean, &mean, &timeUnits, &factor);
|
||||
stdDev = realTimeStdDev * factor;
|
||||
|
||||
if (realTimeSamples > 1) {
|
||||
NS_LOG(out, STDOUT, ("%s elapsed time: %.2f +/- %.2f %s (%d %s) [%s]\n",
|
||||
mName, mean, stdDev, timeUnits,
|
||||
(PRUint32)realTimeSamples, mCountUnits, msg));
|
||||
}
|
||||
else {
|
||||
NS_LOG(out, STDOUT, ("%s elapsed time: %.2f %s [%s]\n",
|
||||
mName, mean, timeUnits, msg));
|
||||
}
|
||||
|
||||
TimeUnits(1/realTimeMean, &mean, &timeUnits, &factor);
|
||||
NS_LOG(out, STDOUT, ("==> %.2f %s/%s\n", mean, mCountUnits, timeUnits));
|
||||
|
||||
double cpuTimeSamples, cpuTimeMean, cpuTimeStdDev;
|
||||
rv = GetCPUTimeStats(&cpuTimeSamples, &cpuTimeMean, &cpuTimeStdDev);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
TimeUnits(cpuTimeMean, &mean, &timeUnits, &factor);
|
||||
stdDev = cpuTimeStdDev * factor;
|
||||
NS_LOG(out, STDOUT, ("%s cpu time: %.2f +/- %.2f %s (%d %s)\n",
|
||||
mName, mean, stdDev, timeUnits,
|
||||
cpuTimeSamples, mCountUnits));
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#endif // NS_ENABLE_STOPWATCH
|
99
xpcom/ds/nsStopwatch.h
Normal file
99
xpcom/ds/nsStopwatch.h
Normal file
@ -0,0 +1,99 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*/
|
||||
|
||||
#ifndef nsStopwatch_h__
|
||||
#define nsStopwatch_h__
|
||||
|
||||
#include "nsIStopwatch.h"
|
||||
|
||||
#ifdef NS_ENABLE_STOPWATCH
|
||||
|
||||
#include "nsHashtable.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class nsStopwatchService : public nsIStopwatchService
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIPROPERTIES
|
||||
NS_DECL_NSISTOPWATCHSERVICE
|
||||
|
||||
nsStopwatchService();
|
||||
virtual ~nsStopwatchService();
|
||||
|
||||
static NS_METHOD
|
||||
Create(nsISupports* outer, const nsIID& aIID, void* *aInstancePtr);
|
||||
|
||||
nsresult Init();
|
||||
|
||||
protected:
|
||||
nsSupportsHashtable mStopwatches;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class nsTimingData {
|
||||
public:
|
||||
nsTimingData()
|
||||
: mStartTime(0),
|
||||
mTotalTime(0),
|
||||
mTotalSquaredTime(0),
|
||||
mCount(0) {
|
||||
}
|
||||
PRIntervalTime mStartTime;
|
||||
double mTotalTime;
|
||||
double mTotalSquaredTime;
|
||||
double mCount;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class nsStopwatch : public nsIStopwatch
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSISTOPWATCH
|
||||
|
||||
nsStopwatch();
|
||||
virtual ~nsStopwatch();
|
||||
|
||||
static NS_METHOD
|
||||
Create(nsISupports* outer, const nsIID& aIID, void* *aInstancePtr);
|
||||
|
||||
void TimeUnits(double timeInMilliSeconds,
|
||||
double *adjustedValue, const char* *adjustedUnits,
|
||||
double *factor);
|
||||
|
||||
protected:
|
||||
char* mName;
|
||||
char* mCountUnits;
|
||||
PRBool mPerThread;
|
||||
PRUintn mThreadTimingDataIndex;
|
||||
nsTimingData mTimingData;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#endif // NS_ENABLE_STOPWATCH
|
||||
|
||||
#endif // nsStopwatch_h__
|
Loading…
x
Reference in New Issue
Block a user