00001
00002
00003
00004 #ifndef IBIS_HOROMETER_H
00005 #define IBIS_HOROMETER_H
00006 #include <stdio.h>
00007 #include <time.h>
00008 #if defined(sun) || defined(linux) || defined(__HOS_AIX__) || \
00009 defined(__CYGWIN__) || defined(__APPLE__) || defined(__FreeBSD__)
00010 # include <limits.h>
00011 # include <sys/time.h>
00012 # include <sys/times.h>
00013 # include <sys/resource.h>
00014 # ifndef RUSAGE_SELF
00015 # define RUSAGE_SELF 0
00016 # endif
00017 # ifndef RUSAGE_CHILDREN
00018 # define RUSAGE_CHILDRED -1
00019 # endif
00020 #elif defined(CRAY)
00021 # include <sys/times.h>
00022 #elif defined(sgi)
00023 # include <limits.h>
00024 # define RUSAGE_SELF 0
00025 # define RUSAGE_CHILDREN -1
00026 # include <sys/times.h>
00027
00028 # include <sys/time.h>
00029 # include <sys/resource.h>
00030 #elif defined(__MINGW32__)
00031 # include <limits.h>
00032 # include <sys/time.h>
00033 #elif defined(_WIN32)
00034 # include <windows.h>
00035 #elif defined(VMS)
00036 # include <unistd.h>
00037 #endif
00038
00041 namespace ibis {
00042 class horometer;
00043 }
00044
00061 class ibis::horometer {
00062 public:
00063 horometer() : startRealTime(0), totalRealTime(0),
00064 startCPUTime(0), totalCPUTime(0) {
00065 #if defined(_WIN32) && defined(_MSC_VER)
00066
00067 LARGE_INTEGER lFrequency;
00068 BOOL ret = QueryPerformanceFrequency(&lFrequency);
00069 if (ret != 0 && lFrequency.QuadPart != 0)
00070 countPeriod = 1.0/static_cast<double>(lFrequency.QuadPart);
00071 else
00072 countPeriod = 0.0;
00073 #endif
00074 };
00076 void start() {
00077 startRealTime = readWallClock();
00078 startCPUTime = readCPUClock();
00079 totalRealTime = 0.0;
00080 totalCPUTime = 0.0;
00081 };
00083 void stop() {
00084 double tmpr = readWallClock() - startRealTime;
00085 double tmpc = readCPUClock() - startCPUTime;
00086 if (tmpr > 0.0)
00087 totalRealTime += tmpr;
00088 if (tmpc > 0.0)
00089 totalCPUTime += tmpc;
00090 };
00092 void resume() {
00093 startRealTime = readWallClock();
00094 startCPUTime = readCPUClock();
00095 }
00097 double realTime() const {return totalRealTime;}
00099 double CPUTime() const {return totalCPUTime;}
00100
00101 private:
00102 double startRealTime;
00103 double totalRealTime;
00104 double startCPUTime;
00105 double totalCPUTime;
00106 #if defined(_WIN32) && defined(_MSC_VER)
00107 double countPeriod;
00108 #endif
00109
00113 inline double readWallClock();
00116 inline double readCPUClock();
00117 };
00118
00119
00120 inline double ibis::horometer::readWallClock() {
00121 #if defined(CLOCK_REALTIME) && !defined(__CYGWIN__)
00122 struct timespec tb;
00123 if (0 == clock_gettime(CLOCK_REALTIME, &tb)) {
00124 return static_cast<double>(tb.tv_sec) + (1e-9 * tb.tv_nsec);
00125 }
00126 else {
00127 struct timeval cpt;
00128 gettimeofday(&cpt, 0);
00129 return static_cast<double>(cpt.tv_sec) + (1e-6 * cpt.tv_usec);
00130 }
00131 #elif defined(HAVE_GETTIMEOFDAY) || defined(unix) || defined(CRAY) || \
00132 defined(linux) || defined(__HOS_AIX__) || defined(__APPLE__) || \
00133 defined(__FreeBSD__)
00134 struct timeval cpt;
00135 gettimeofday(&cpt, 0);
00136 return static_cast<double>(cpt.tv_sec) + (1e-6 * cpt.tv_usec);
00137 #elif defined(_WIN32) && defined(_MSC_VER)
00138 double ret = 0.0;
00139 if (countPeriod != 0) {
00140 LARGE_INTEGER cnt;
00141 if (QueryPerformanceCounter(&cnt)) {
00142 ret = countPeriod * cnt.QuadPart;
00143 }
00144 }
00145 if (ret == 0.0) {
00146 union {
00147 FILETIME ftFileTime;
00148 __int64 ftInt64;
00149 } ftRealTime;
00150 GetSystemTimeAsFileTime(&ftRealTime.ftFileTime);
00151 ret = (double) ftRealTime.ftInt64 * 1e-7;
00152 }
00153 return ret;
00154 #elif defined(VMS)
00155 return (double) clock() * 0.001;
00156 #else
00157 return (double) clock() / CLOCKS_PER_SEC;
00158 #endif
00159 }
00160
00161
00162 inline double ibis::horometer::readCPUClock() {
00163 #if defined(sun) || defined(sgi) || defined(linux) || defined(__APPLE__) \
00164 || defined(__HOS_AIX__) || defined(__CYGWIN__) || defined(__FreeBSD__)
00165
00166 double time=0;
00167 struct rusage ruse;
00168 if (0 == getrusage(RUSAGE_SELF, &ruse)) {
00169 time = (ruse.ru_utime.tv_usec + ruse.ru_stime.tv_usec) * 1e-6 +
00170 ruse.ru_utime.tv_sec + ruse.ru_stime.tv_sec;
00171 }
00172 else {
00173 fputs("Warning -- horometer::readCPUClock(): getrusage failed "
00174 "on RUSAGE_SELF", stderr);
00175 }
00176 if (0 == getrusage(RUSAGE_CHILDREN, &ruse)) {
00177 time += (ruse.ru_utime.tv_usec + ruse.ru_stime.tv_usec) * 1e-6 +
00178 ruse.ru_utime.tv_sec + ruse.ru_stime.tv_sec;
00179 }
00180 else {
00181 fputs("Warning -- horometer::readCPUClock(): getrusage failed on "
00182 "RUSAGE_CHILDRED", stderr);
00183 }
00184 return time;
00185 #elif defined(unix) || defined(CRAY)
00186 #if defined(__STDC__)
00187 struct tms cpt;
00188 times(&cpt);
00189 return (cpt.tms_utime + cpt.tms_stime + cpt.tms_cutime +
00190 (double)cpt.tms_cstime) / CLK_TCK;
00191 #else
00192 return (double) times() / CLK_TCK;
00193 #endif
00194 #elif defined(_WIN32)
00195 return (double) clock() / CLOCKS_PER_SEC;
00196 #elif defined(VMS)
00197 return (double) clock() * 0.001;
00198 #else
00199 return (double) clock() / CLOCKS_PER_SEC;
00200 #endif
00201 }
00202 #endif // IBIS_HOROMETER_H