/root-5.34.01/core/base/src/TStopwatch.cxx

# · C++ · 254 lines · 155 code · 43 blank · 56 comment · 38 complexity · 19bfe7f6596e2149d3fdd422b0dc66cc MD5 · raw file

  1. // @(#)root/base:$Id: TStopwatch.cxx 37631 2010-12-17 15:24:29Z rdm $
  2. // Author: Fons Rademakers 11/10/95
  3. /*************************************************************************
  4. * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers. *
  5. * All rights reserved. *
  6. * *
  7. * For the licensing terms see $ROOTSYS/LICENSE. *
  8. * For the list of contributors see $ROOTSYS/README/CREDITS. *
  9. *************************************************************************/
  10. //////////////////////////////////////////////////////////////////////////
  11. // //
  12. // TStopwatch //
  13. // //
  14. // Stopwatch class. This class returns the real and cpu time between //
  15. // the start and stop events. //
  16. // //
  17. //////////////////////////////////////////////////////////////////////////
  18. #include "TStopwatch.h"
  19. #include "TTimeStamp.h"
  20. #include "TString.h"
  21. #if defined(R__UNIX)
  22. # include <sys/times.h>
  23. # include <unistd.h>
  24. static Double_t gTicks = 0;
  25. #elif defined(WIN32)
  26. # include "TError.h"
  27. const Double_t gTicks = 1.0e-7;
  28. # include "Windows4Root.h"
  29. #endif
  30. ClassImp(TStopwatch)
  31. //______________________________________________________________________________
  32. TStopwatch::TStopwatch()
  33. {
  34. // Create a stopwatch and start it.
  35. #ifdef R__UNIX
  36. if (gTicks <= 0.0)
  37. gTicks = (Double_t)sysconf(_SC_CLK_TCK);
  38. #endif
  39. fStopRealTime = 0;
  40. fStopCpuTime = 0;
  41. Start();
  42. }
  43. //______________________________________________________________________________
  44. void TStopwatch::Start(Bool_t reset)
  45. {
  46. // Start the stopwatch. If reset is kTRUE reset the stopwatch before
  47. // starting it (including the stopwatch counter).
  48. // Use kFALSE to continue timing after a Stop() without
  49. // resetting the stopwatch.
  50. if (reset) {
  51. fState = kUndefined;
  52. fTotalCpuTime = 0;
  53. fTotalRealTime = 0;
  54. fCounter = 0;
  55. }
  56. if (fState != kRunning) {
  57. fStartRealTime = GetRealTime();
  58. fStartCpuTime = GetCPUTime();
  59. }
  60. fState = kRunning;
  61. fCounter++;
  62. }
  63. //______________________________________________________________________________
  64. void TStopwatch::Stop()
  65. {
  66. // Stop the stopwatch.
  67. fStopRealTime = GetRealTime();
  68. fStopCpuTime = GetCPUTime();
  69. if (fState == kRunning) {
  70. fTotalCpuTime += fStopCpuTime - fStartCpuTime;
  71. fTotalRealTime += fStopRealTime - fStartRealTime;
  72. }
  73. fState = kStopped;
  74. }
  75. //______________________________________________________________________________
  76. void TStopwatch::Continue()
  77. {
  78. // Resume a stopped stopwatch. The stopwatch continues counting from the last
  79. // Start() onwards (this is like the laptimer function).
  80. if (fState == kUndefined)
  81. Error("Continue", "stopwatch not started");
  82. if (fState == kStopped) {
  83. fTotalCpuTime -= fStopCpuTime - fStartCpuTime;
  84. fTotalRealTime -= fStopRealTime - fStartRealTime;
  85. }
  86. fState = kRunning;
  87. }
  88. //______________________________________________________________________________
  89. Double_t TStopwatch::RealTime()
  90. {
  91. // Stop the stopwatch (if it is running) and return the realtime (in
  92. // seconds) passed between the start and stop events.
  93. if (fState == kUndefined)
  94. Error("RealTime", "stopwatch not started");
  95. if (fState == kRunning)
  96. Stop();
  97. return fTotalRealTime;
  98. }
  99. //______________________________________________________________________________
  100. Double_t TStopwatch::CpuTime()
  101. {
  102. // Stop the stopwatch (if it is running) and return the cputime (in
  103. // seconds) passed between the start and stop events.
  104. if (fState == kUndefined)
  105. Error("CpuTime", "stopwatch not started");
  106. if (fState == kRunning)
  107. Stop();
  108. return fTotalCpuTime;
  109. }
  110. //______________________________________________________________________________
  111. Double_t TStopwatch::GetRealTime()
  112. {
  113. // Private static method returning system realtime.
  114. #if defined(R__UNIX)
  115. return TTimeStamp();
  116. #elif defined(WIN32)
  117. union {
  118. FILETIME ftFileTime;
  119. __int64 ftInt64;
  120. } ftRealTime; // time the process has spent in kernel mode
  121. SYSTEMTIME st;
  122. GetSystemTime(&st);
  123. SystemTimeToFileTime(&st,&ftRealTime.ftFileTime);
  124. return (Double_t)ftRealTime.ftInt64 * gTicks;
  125. #endif
  126. }
  127. //______________________________________________________________________________
  128. Double_t TStopwatch::GetCPUTime()
  129. {
  130. // Private static method returning system CPU time.
  131. #if defined(R__UNIX)
  132. struct tms cpt;
  133. times(&cpt);
  134. return (Double_t)(cpt.tms_utime+cpt.tms_stime) / gTicks;
  135. #elif defined(WIN32)
  136. OSVERSIONINFO OsVersionInfo;
  137. // Value Platform
  138. //----------------------------------------------------
  139. // VER_PLATFORM_WIN32s Win32s on Windows 3.1
  140. // VER_PLATFORM_WIN32_WINDOWS Win32 on Windows 95
  141. // VER_PLATFORM_WIN32_NT Windows NT
  142. //
  143. OsVersionInfo.dwOSVersionInfoSize=sizeof(OSVERSIONINFO);
  144. GetVersionEx(&OsVersionInfo);
  145. if (OsVersionInfo.dwPlatformId == VER_PLATFORM_WIN32_NT) {
  146. DWORD ret;
  147. FILETIME ftCreate, // when the process was created
  148. ftExit; // when the process exited
  149. union {
  150. FILETIME ftFileTime;
  151. __int64 ftInt64;
  152. } ftKernel; // time the process has spent in kernel mode
  153. union {
  154. FILETIME ftFileTime;
  155. __int64 ftInt64;
  156. } ftUser; // time the process has spent in user mode
  157. HANDLE hThread = GetCurrentThread();
  158. ret = GetThreadTimes (hThread, &ftCreate, &ftExit,
  159. &ftKernel.ftFileTime,
  160. &ftUser.ftFileTime);
  161. if (ret != TRUE) {
  162. ret = GetLastError ();
  163. ::Error ("GetCPUTime", " Error on GetProcessTimes 0x%lx", (int)ret);
  164. }
  165. // Process times are returned in a 64-bit structure, as the number of
  166. // 100 nanosecond ticks since 1 January 1601. User mode and kernel mode
  167. // times for this process are in separate 64-bit structures.
  168. // To convert to floating point seconds, we will:
  169. //
  170. // Convert sum of high 32-bit quantities to 64-bit int
  171. return (Double_t) (ftKernel.ftInt64 + ftUser.ftInt64) * gTicks;
  172. } else
  173. return GetRealTime();
  174. #endif
  175. }
  176. //______________________________________________________________________________
  177. void TStopwatch::Print(Option_t *opt) const
  178. {
  179. // Print the real and cpu time passed between the start and stop events.
  180. // and the number of times (slices) this TStopwatch was called
  181. // (if this number > 1). If opt="m" print out realtime in milli second
  182. // precision. If opt="u" print out realtime in micro second precision.
  183. Double_t realt = const_cast<TStopwatch*>(this)->RealTime();
  184. Double_t cput = const_cast<TStopwatch*>(this)->CpuTime();
  185. Int_t hours = Int_t(realt / 3600);
  186. realt -= hours * 3600;
  187. Int_t min = Int_t(realt / 60);
  188. realt -= min * 60;
  189. Int_t sec = Int_t(realt);
  190. if (realt < 0) realt = 0;
  191. if (cput < 0) cput = 0;
  192. if (opt && *opt == 'm') {
  193. if (Counter() > 1) {
  194. Printf("Real time %d:%02d:%06.3f, CP time %.3f, %d slices", hours, min, realt, cput, Counter());
  195. } else {
  196. Printf("Real time %d:%02d:%06.3f, CP time %.3f", hours, min, realt, cput);
  197. }
  198. } else if (opt && *opt == 'u') {
  199. if (Counter() > 1) {
  200. Printf("Real time %d:%02d:%09.6f, CP time %.3f, %d slices", hours, min, realt, cput, Counter());
  201. } else {
  202. Printf("Real time %d:%02d:%09.6f, CP time %.3f", hours, min, realt, cput);
  203. }
  204. } else {
  205. if (Counter() > 1) {
  206. Printf("Real time %d:%02d:%02d, CP time %.3f, %d slices", hours, min, sec, cput, Counter());
  207. } else {
  208. Printf("Real time %d:%02d:%02d, CP time %.3f", hours, min, sec, cput);
  209. }
  210. }
  211. }