PageRenderTime 26ms CodeModel.GetById 33ms RepoModel.GetById 1ms app.codeStats 0ms

/server/src/mozilla/modules/libutil/src/stopwatch.cpp

https://github.com/aptana/Jaxer
C++ | 265 lines | 206 code | 39 blank | 20 comment | 40 complexity | 0651fbbe29e24fd6aea9ab55d26570de MD5 | raw file
Possible License(s): Apache-2.0, BSD-3-Clause, GPL-2.0, MPL-2.0-no-copyleft-exception, LGPL-3.0
  1. #include "stopwatch.h"
  2. #include <stdio.h>
  3. #include <time.h>
  4. #ifdef XP_UNIX
  5. #include <unistd.h>
  6. #include <sys/times.h>
  7. #endif
  8. #ifdef XP_WIN
  9. #include "windows.h"
  10. #endif
  11. #include "nsDebug.h"
  12. // #define MILLISECOND_RESOLUTION to track time with greater precision
  13. // If not defined the resolution is to the second only
  14. //
  15. #define MILLISECOND_RESOLUTION
  16. #ifdef MILLISECOND_RESOLUTION
  17. double gTicks = 1.0e-4; // for millisecond resolution
  18. #else
  19. double gTicks = 1.0e-7; // for second resolution
  20. #endif
  21. Stopwatch::Stopwatch() {
  22. #ifdef R__UNIX
  23. if (!gTicks) gTicks = (clock_t)sysconf(_SC_CLK_TCK);
  24. #endif
  25. fState = kUndefined;
  26. fTotalCpuTime = 0;
  27. fTotalRealTime = 0;
  28. mCreatedStack = PR_FALSE;
  29. mSavedStates = nsnull;
  30. Start();
  31. }
  32. Stopwatch::~Stopwatch() {
  33. EState* state = 0;
  34. if (mSavedStates) {
  35. while ((state = (EState*) mSavedStates->Pop())) {
  36. delete state;
  37. }
  38. delete mSavedStates;
  39. }
  40. }
  41. void Stopwatch::Start(PRBool reset) {
  42. if (reset) {
  43. fTotalCpuTime = 0;
  44. fTotalRealTime = 0;
  45. }
  46. if (fState != kRunning) {
  47. #ifndef R__UNIX
  48. fStartRealTime = GetRealTime();
  49. fStartCpuTime = GetCPUTime();
  50. #else
  51. struct tms cpt;
  52. fStartRealTime = (double)times(&cpt) / gTicks;
  53. fStartCpuTime = (double)(cpt.tms_utime+cpt.tms_stime) / gTicks;
  54. #endif
  55. }
  56. fState = kRunning;
  57. }
  58. void Stopwatch::Stop() {
  59. #ifndef R__UNIX
  60. fStopRealTime = GetRealTime();
  61. fStopCpuTime = GetCPUTime();
  62. #else
  63. struct tms cpt;
  64. fStopRealTime = (double)times(&cpt) / gTicks;
  65. fStopCpuTime = (double)(cpt.tms_utime+cpt.tms_stime) / gTicks;
  66. #endif
  67. if (fState == kRunning) {
  68. fTotalCpuTime += fStopCpuTime - fStartCpuTime;
  69. fTotalRealTime += fStopRealTime - fStartRealTime;
  70. }
  71. fState = kStopped;
  72. }
  73. void Stopwatch::SaveState() {
  74. if (!mCreatedStack) {
  75. mSavedStates = new nsDeque(nsnull);
  76. if (!mSavedStates)
  77. return;
  78. mCreatedStack = PR_TRUE;
  79. }
  80. EState* state = new EState();
  81. if (state) {
  82. *state = fState;
  83. mSavedStates->PushFront((void*) state);
  84. }
  85. }
  86. void Stopwatch::RestoreState() {
  87. EState* state = nsnull;
  88. state = (EState*) mSavedStates->Pop();
  89. if (state) {
  90. if (*state == kRunning && fState == kStopped)
  91. Start(PR_FALSE);
  92. else if (*state == kStopped && fState == kRunning)
  93. Stop();
  94. delete state;
  95. }
  96. else {
  97. NS_WARNING("Stopwatch::RestoreState(): The saved state stack is empty.\n");
  98. }
  99. }
  100. void Stopwatch::Continue() {
  101. if (fState != kUndefined) {
  102. if (fState == kStopped) {
  103. fTotalCpuTime -= fStopCpuTime - fStartCpuTime;
  104. fTotalRealTime -= fStopRealTime - fStartRealTime;
  105. }
  106. fState = kRunning;
  107. }
  108. }
  109. // NOTE: returns seconds regardless of the state of the MILLISECOND_RESOLUTION #define
  110. //
  111. double Stopwatch::RealTime() {
  112. if (fState != kUndefined) {
  113. if (fState == kRunning)
  114. Stop();
  115. }
  116. #ifdef MILLISECOND_RESOLUTION
  117. return fTotalRealTime/1000;
  118. #else
  119. return fTotalRealTime;
  120. #endif
  121. }
  122. // NOTE: returns milliseconds regardless of the state of the MILLISECOND_RESOLUTION #define
  123. //
  124. double Stopwatch::RealTimeInMilliseconds() {
  125. if (fState != kUndefined) {
  126. if (fState == kRunning)
  127. Stop();
  128. }
  129. #ifdef MILLISECOND_RESOLUTION
  130. return fTotalRealTime;
  131. #else
  132. return fTotalRealTime * 1000; // we don;t have milliseconds, so fake it
  133. #endif
  134. }
  135. // NOTE: returns seconds regardless of the state of the MILLISECOND_RESOLUTION define
  136. //
  137. double Stopwatch::CpuTime() {
  138. if (fState != kUndefined) {
  139. if (fState == kRunning)
  140. Stop();
  141. }
  142. #ifdef MILLISECOND_RESOLUTION
  143. return fTotalCpuTime / 1000; // adjust from milliseconds to seconds
  144. #else
  145. return fTotalCpuTime;
  146. #endif
  147. }
  148. double Stopwatch::GetRealTime(){
  149. #if defined(R__MAC)
  150. // return(double)clock() / gTicks;
  151. return(double)clock() / 1000000L;
  152. #elif defined(R__UNIX)
  153. struct tms cpt;
  154. return (double)times(&cpt) / gTicks;
  155. #elif defined(R__VMS)
  156. return(double)clock()/gTicks;
  157. #elif defined(WIN32)
  158. union {FILETIME ftFileTime;
  159. __int64 ftInt64;
  160. } ftRealTime; // time the process has spent in kernel mode
  161. SYSTEMTIME st;
  162. GetSystemTime(&st);
  163. SystemTimeToFileTime(&st,&ftRealTime.ftFileTime);
  164. return (double)ftRealTime.ftInt64 * gTicks;
  165. #endif
  166. }
  167. double Stopwatch::GetCPUTime(){
  168. #if defined(R__MAC)
  169. // return(double)clock() / gTicks;
  170. return(double)clock();
  171. #elif defined(R__UNIX)
  172. struct tms cpt;
  173. times(&cpt);
  174. return (double)(cpt.tms_utime+cpt.tms_stime) / gTicks;
  175. #elif defined(R__VMS)
  176. return(double)clock()/gTicks;
  177. #elif defined(WINCE)
  178. return 0;
  179. #elif defined(WIN32)
  180. DWORD ret;
  181. FILETIME ftCreate, // when the process was created
  182. ftExit; // when the process exited
  183. union {FILETIME ftFileTime;
  184. __int64 ftInt64;
  185. } ftKernel; // time the process has spent in kernel mode
  186. union {FILETIME ftFileTime;
  187. __int64 ftInt64;
  188. } ftUser; // time the process has spent in user mode
  189. HANDLE hProcess = GetCurrentProcess();
  190. ret = GetProcessTimes (hProcess, &ftCreate, &ftExit,
  191. &ftKernel.ftFileTime,
  192. &ftUser.ftFileTime);
  193. if (ret != PR_TRUE){
  194. ret = GetLastError ();
  195. #ifdef DEBUG
  196. printf("%s 0x%lx\n"," Error on GetProcessTimes", (int)ret);
  197. #endif
  198. }
  199. /*
  200. * Process times are returned in a 64-bit structure, as the number of
  201. * 100 nanosecond ticks since 1 January 1601. User mode and kernel mode
  202. * times for this process are in separate 64-bit structures.
  203. * To convert to floating point seconds, we will:
  204. *
  205. * Convert sum of high 32-bit quantities to 64-bit int
  206. */
  207. return (double) (ftKernel.ftInt64 + ftUser.ftInt64) * gTicks;
  208. #endif
  209. }
  210. void Stopwatch::Print(void) {
  211. // Print the real and cpu time passed between the start and stop events.
  212. double realt = RealTimeInMilliseconds();
  213. int hours = int(realt / 3600000);
  214. realt -= hours * 3600000;
  215. int min = int(realt / 60000);
  216. realt -= min * 60000;
  217. int sec = int(realt/1000);
  218. realt -= sec * 1000;
  219. #ifdef MOZ_PERF_METRICS
  220. int ms = int(realt);
  221. RAPTOR_STOPWATCH_TRACE(("Real time %d:%d:%d.%d, CP time %.3f\n", hours, min, sec, ms, CpuTime()));
  222. #elif defined(DEBUG)
  223. int ms = int(realt);
  224. printf("Real time %d:%d:%d.%d, CP time %.3f\n", hours, min, sec, ms, CpuTime());
  225. #endif
  226. }