#include "TStopwatch.h"
#include "TTimeStamp.h"
#include "TString.h"
#if defined(R__UNIX)
# include <sys/times.h>
# include <unistd.h>
static Double_t gTicks = 0;
#elif defined(WIN32)
# include "TError.h"
const Double_t gTicks = 1.0e-7;
# include "Windows4Root.h"
#endif
ClassImp(TStopwatch)
TStopwatch::TStopwatch()
{
#ifdef R__UNIX
if (gTicks <= 0.0)
gTicks = (Double_t)sysconf(_SC_CLK_TCK);
#endif
fStopRealTime = 0;
fStopCpuTime = 0;
Start();
}
void TStopwatch::Start(Bool_t reset)
{
if (reset) {
fState = kUndefined;
fTotalCpuTime = 0;
fTotalRealTime = 0;
fCounter = 0;
}
if (fState != kRunning) {
fStartRealTime = GetRealTime();
fStartCpuTime = GetCPUTime();
}
fState = kRunning;
fCounter++;
}
void TStopwatch::Stop()
{
fStopRealTime = GetRealTime();
fStopCpuTime = GetCPUTime();
if (fState == kRunning) {
fTotalCpuTime += fStopCpuTime - fStartCpuTime;
fTotalRealTime += fStopRealTime - fStartRealTime;
}
fState = kStopped;
}
void TStopwatch::Continue()
{
if (fState == kUndefined)
Error("Continue", "stopwatch not started");
if (fState == kStopped) {
fTotalCpuTime -= fStopCpuTime - fStartCpuTime;
fTotalRealTime -= fStopRealTime - fStartRealTime;
}
fState = kRunning;
}
Double_t TStopwatch::RealTime()
{
if (fState == kUndefined)
Error("RealTime", "stopwatch not started");
if (fState == kRunning)
Stop();
return fTotalRealTime;
}
Double_t TStopwatch::CpuTime()
{
if (fState == kUndefined)
Error("CpuTime", "stopwatch not started");
if (fState == kRunning)
Stop();
return fTotalCpuTime;
}
Double_t TStopwatch::GetRealTime()
{
#if defined(R__UNIX)
return TTimeStamp();
#elif defined(WIN32)
union {
FILETIME ftFileTime;
__int64 ftInt64;
} ftRealTime;
SYSTEMTIME st;
GetSystemTime(&st);
SystemTimeToFileTime(&st,&ftRealTime.ftFileTime);
return (Double_t)ftRealTime.ftInt64 * gTicks;
#endif
}
Double_t TStopwatch::GetCPUTime()
{
#if defined(R__UNIX)
struct tms cpt;
times(&cpt);
return (Double_t)(cpt.tms_utime+cpt.tms_stime) / gTicks;
#elif defined(WIN32)
OSVERSIONINFO OsVersionInfo;
OsVersionInfo.dwOSVersionInfoSize=sizeof(OSVERSIONINFO);
GetVersionEx(&OsVersionInfo);
if (OsVersionInfo.dwPlatformId == VER_PLATFORM_WIN32_NT) {
DWORD ret;
FILETIME ftCreate,
ftExit;
union {
FILETIME ftFileTime;
__int64 ftInt64;
} ftKernel;
union {
FILETIME ftFileTime;
__int64 ftInt64;
} ftUser;
HANDLE hThread = GetCurrentThread();
ret = GetThreadTimes (hThread, &ftCreate, &ftExit,
&ftKernel.ftFileTime,
&ftUser.ftFileTime);
if (ret != TRUE) {
ret = GetLastError ();
::Error ("GetCPUTime", " Error on GetProcessTimes 0x%lx", (int)ret);
}
return (Double_t) (ftKernel.ftInt64 + ftUser.ftInt64) * gTicks;
} else
return GetRealTime();
#endif
}
void TStopwatch::Print(Option_t *opt) const
{
Double_t realt = const_cast<TStopwatch*>(this)->RealTime();
Double_t cput = const_cast<TStopwatch*>(this)->CpuTime();
Int_t hours = Int_t(realt / 3600);
realt -= hours * 3600;
Int_t min = Int_t(realt / 60);
realt -= min * 60;
Int_t sec = Int_t(realt);
if (realt < 0) realt = 0;
if (cput < 0) cput = 0;
if (opt && *opt == 'm') {
if (Counter() > 1) {
Printf("Real time %d:%02d:%06.3f, CP time %.3f, %d slices", hours, min, realt, cput, Counter());
} else {
Printf("Real time %d:%02d:%06.3f, CP time %.3f", hours, min, realt, cput);
}
} else if (opt && *opt == 'u') {
if (Counter() > 1) {
Printf("Real time %d:%02d:%09.6f, CP time %.3f, %d slices", hours, min, realt, cput, Counter());
} else {
Printf("Real time %d:%02d:%09.6f, CP time %.3f", hours, min, realt, cput);
}
} else {
if (Counter() > 1) {
Printf("Real time %d:%02d:%02d, CP time %.3f, %d slices", hours, min, sec, cput, Counter());
} else {
Printf("Real time %d:%02d:%02d, CP time %.3f", hours, min, sec, cput);
}
}
}