Back to index

lightning-sunbird  0.9+nobinonly
stopwatch.cpp
Go to the documentation of this file.
00001 #include "stopwatch.h"
00002 #include <stdio.h>
00003 #include <time.h>
00004 #ifdef XP_UNIX
00005 #include <unistd.h>
00006 #include <sys/times.h>
00007 #endif
00008 #ifdef XP_WIN
00009 #include "windows.h"
00010 #endif
00011 #include "nsDebug.h"
00012 
00013 // #define MILLISECOND_RESOLUTION to track time with greater precision
00014 //  If not defined the resolution is to the second only
00015 //
00016 #define MILLISECOND_RESOLUTION
00017 #ifdef MILLISECOND_RESOLUTION
00018 double gTicks = 1.0e-4; // for millisecond resolution
00019 #else
00020 double gTicks = 1.0e-7; // for second resolution
00021 #endif
00022 
00023 Stopwatch::Stopwatch() {
00024 
00025 #ifdef R__UNIX
00026    if (!gTicks) gTicks = (clock_t)sysconf(_SC_CLK_TCK);
00027 #endif
00028    fState         = kUndefined;   
00029    fTotalCpuTime  = 0;
00030    fTotalRealTime = 0;   
00031    mCreatedStack = PR_FALSE;
00032    mSavedStates = nsnull;
00033    Start();
00034 }
00035 
00036 Stopwatch::~Stopwatch() {
00037   EState* state = 0;
00038   if (mSavedStates) {
00039     while ((state = (EState*) mSavedStates->Pop())) {
00040       delete state;
00041     } 
00042     delete mSavedStates;
00043   }
00044 }
00045 
00046 void Stopwatch::Start(PRBool reset) {
00047    if (reset) {
00048       fTotalCpuTime  = 0;
00049       fTotalRealTime = 0;
00050    }
00051    if (fState != kRunning) {
00052 #ifndef R__UNIX
00053       fStartRealTime = GetRealTime();
00054       fStartCpuTime  = GetCPUTime();
00055 #else
00056       struct tms cpt;
00057       fStartRealTime = (double)times(&cpt) / gTicks;
00058       fStartCpuTime  = (double)(cpt.tms_utime+cpt.tms_stime) / gTicks;
00059 #endif
00060    }
00061    fState = kRunning;
00062 }
00063 
00064 void Stopwatch::Stop() {
00065 
00066 #ifndef R__UNIX
00067    fStopRealTime = GetRealTime();
00068    fStopCpuTime  = GetCPUTime();
00069 #else
00070    struct tms cpt;
00071    fStopRealTime = (double)times(&cpt) / gTicks;
00072    fStopCpuTime  = (double)(cpt.tms_utime+cpt.tms_stime) / gTicks;
00073 #endif
00074    if (fState == kRunning) {
00075       fTotalCpuTime  += fStopCpuTime  - fStartCpuTime;
00076       fTotalRealTime += fStopRealTime - fStartRealTime;
00077    }
00078    fState = kStopped;
00079 }
00080 
00081 
00082 void Stopwatch::SaveState() {
00083   if (!mCreatedStack) {
00084     mSavedStates = new nsDeque(nsnull);
00085     if (!mSavedStates)
00086       return;
00087     mCreatedStack = PR_TRUE;
00088   }
00089   EState* state = new EState();
00090   if (state) {
00091     *state = fState;
00092     mSavedStates->PushFront((void*) state);
00093   }
00094 }
00095 
00096 void Stopwatch::RestoreState() {
00097   EState* state = nsnull;
00098   state = (EState*) mSavedStates->Pop();
00099   if (state) {
00100     if (*state == kRunning && fState == kStopped)
00101       Start(PR_FALSE);
00102     else if (*state == kStopped && fState == kRunning)
00103       Stop();
00104     delete state;
00105   }
00106   else {
00107     NS_WARNING("Stopwatch::RestoreState(): The saved state stack is empty.\n");
00108   }
00109 }
00110 
00111 void Stopwatch::Continue() {
00112 
00113   if (fState != kUndefined) {
00114 
00115     if (fState == kStopped) {
00116       fTotalCpuTime  -= fStopCpuTime  - fStartCpuTime;
00117       fTotalRealTime -= fStopRealTime - fStartRealTime;
00118     }
00119 
00120     fState = kRunning;
00121   }
00122 }
00123 
00124 
00125 // NOTE: returns seconds regardless of the state of the MILLISECOND_RESOLUTION #define
00126 //
00127 double Stopwatch::RealTime() {
00128 
00129   if (fState != kUndefined) {
00130     if (fState == kRunning)
00131       Stop();
00132   }
00133 
00134 #ifdef MILLISECOND_RESOLUTION
00135   return fTotalRealTime/1000;
00136 #else
00137   return fTotalRealTime;
00138 #endif
00139 }
00140 
00141 // NOTE: returns milliseconds regardless of the state of the MILLISECOND_RESOLUTION #define
00142 //
00143 double Stopwatch::RealTimeInMilliseconds() {
00144 
00145   if (fState != kUndefined) {
00146     if (fState == kRunning)
00147       Stop();
00148   }
00149 
00150 #ifdef MILLISECOND_RESOLUTION
00151   return fTotalRealTime;
00152 #else
00153   return fTotalRealTime * 1000; // we don;t have milliseconds, so fake it
00154 #endif
00155 }
00156 
00157 // NOTE: returns seconds regardless of the state of the MILLISECOND_RESOLUTION define
00158 //
00159 double Stopwatch::CpuTime() {
00160   if (fState != kUndefined) {
00161 
00162     if (fState == kRunning)
00163       Stop();
00164 
00165   }
00166 #ifdef MILLISECOND_RESOLUTION
00167   return fTotalCpuTime / 1000;  // adjust from milliseconds to seconds
00168 #else
00169   return fTotalCpuTime;
00170 #endif
00171 }
00172 
00173 
00174 double Stopwatch::GetRealTime(){ 
00175 #if defined(R__MAC)
00176 // return(double)clock() / gTicks;
00177    return(double)clock() / 1000000L;
00178 #elif defined(R__UNIX)
00179    struct tms cpt;
00180    return (double)times(&cpt) / gTicks;
00181 #elif defined(R__VMS)
00182   return(double)clock()/gTicks;
00183 #elif defined(WIN32)
00184   union     {FILETIME ftFileTime;
00185              __int64  ftInt64;
00186             } ftRealTime; // time the process has spent in kernel mode
00187   SYSTEMTIME st;
00188   GetSystemTime(&st);
00189   SystemTimeToFileTime(&st,&ftRealTime.ftFileTime);
00190   return (double)ftRealTime.ftInt64 * gTicks;
00191 #endif
00192 }
00193 
00194 
00195 double Stopwatch::GetCPUTime(){ 
00196 #if defined(R__MAC)
00197 // return(double)clock() / gTicks;
00198    return(double)clock();
00199 #elif defined(R__UNIX)
00200    struct tms cpt;
00201    times(&cpt);
00202    return (double)(cpt.tms_utime+cpt.tms_stime) / gTicks;
00203 #elif defined(R__VMS)
00204    return(double)clock()/gTicks;
00205 #elif defined(WINCE)
00206    return 0;
00207 #elif defined(WIN32)
00208 
00209   OSVERSIONINFO OsVersionInfo;
00210 
00211 //*-*         Value                      Platform
00212 //*-*  ----------------------------------------------------
00213 //*-*  VER_PLATFORM_WIN32_WINDOWS       Win32 on Windows 95
00214 //*-*  VER_PLATFORM_WIN32_NT            Windows NT
00215 //*-*
00216   OsVersionInfo.dwOSVersionInfoSize=sizeof(OSVERSIONINFO);
00217   GetVersionEx(&OsVersionInfo);
00218   if (OsVersionInfo.dwPlatformId == VER_PLATFORM_WIN32_NT) {
00219     DWORD       ret;
00220     FILETIME    ftCreate,       // when the process was created
00221                 ftExit;         // when the process exited
00222 
00223     union     {FILETIME ftFileTime;
00224                __int64  ftInt64;
00225               } ftKernel; // time the process has spent in kernel mode
00226 
00227     union     {FILETIME ftFileTime;
00228                __int64  ftInt64;
00229               } ftUser;   // time the process has spent in user mode
00230 
00231     HANDLE hProcess = GetCurrentProcess();
00232     ret = GetProcessTimes (hProcess, &ftCreate, &ftExit,
00233                                      &ftKernel.ftFileTime,
00234                                      &ftUser.ftFileTime);
00235     if (ret != PR_TRUE){
00236       ret = GetLastError ();
00237 #ifdef DEBUG
00238       printf("%s 0x%lx\n"," Error on GetProcessTimes", (int)ret);
00239 #endif
00240     }
00241 
00242     /*
00243      * Process times are returned in a 64-bit structure, as the number of
00244      * 100 nanosecond ticks since 1 January 1601.  User mode and kernel mode
00245      * times for this process are in separate 64-bit structures.
00246      * To convert to floating point seconds, we will:
00247      *
00248      *          Convert sum of high 32-bit quantities to 64-bit int
00249      */
00250 
00251       return (double) (ftKernel.ftInt64 + ftUser.ftInt64) * gTicks;
00252   }
00253   else
00254       return GetRealTime();
00255 
00256 #endif
00257 }
00258 
00259 
00260 void Stopwatch::Print(void) {
00261    // Print the real and cpu time passed between the start and stop events.
00262 
00263    double  realt = RealTimeInMilliseconds();
00264 
00265    int  hours = int(realt / 3600000);
00266    realt -= hours * 3600000;
00267    int  min   = int(realt / 60000);
00268    realt -= min * 60000;
00269    int  sec   = int(realt/1000);
00270    realt -= sec * 1000;
00271 #ifdef MOZ_PERF_METRICS
00272   int ms = int(realt);
00273    RAPTOR_STOPWATCH_TRACE(("Real time %d:%d:%d.%d, CP time %.3f\n", hours, min, sec, ms, CpuTime()));
00274 #elif defined(DEBUG)
00275   int ms = int(realt);
00276    printf("Real time %d:%d:%d.%d, CP time %.3f\n", hours, min, sec, ms, CpuTime());
00277 #endif
00278 }