00001 00019 #ifndef TBCI_STOPWATCH_H 00020 #define TBCI_STOPWATCH_H 00021 00040 /* We need to know about certain settings, but we don't want to include basics.h */ 00041 #ifdef HAVE_TBCICONFIG_H 00042 # include "tbciconfig.h" 00043 #else 00044 # include "config_manual.h" 00045 #endif 00046 00047 //#define _ANSI_C_SOURCE 00048 #include <time.h> 00054 #ifdef HAVE_UNISTD_H 00055 # include <unistd.h> 00056 #endif 00057 #if defined (__linux__) && !defined(CLK_TCK) 00058 # define CLK_TCK ((clock_t) sysconf (_SC_CLK_TCK)) 00059 #endif 00060 00061 #ifdef HAVE_LIMITS_H 00062 # include <limits.h> 00063 #else 00064 # ifndef LONG_MIN 00065 # if defined(__WORDSIZE) && __WORDSIZE == 64 00066 # define LONG_MIN (-9223372036854775807L - 1L) 00067 # else 00068 # define LONG_MIN (-2147483647L - 1L) 00069 # endif 00070 # endif 00071 #endif 00072 00073 /* Maybe we use a Linux kernel with changed HZ ... */ 00074 #if defined(__linux__) && defined(BROKEN_HZ) /* && defined(__i386__) */ 00075 # include <asm/param.h> 00076 # define CPS (CLOCKS_PER_SEC*HZ/CLK_TCK) 00077 #else 00078 # define CPS CLOCKS_PER_SEC 00079 #endif 00080 00086 class stopw_base 00087 { 00088 protected: 00090 double last_time; 00092 double total; 00094 const double secs_per_tick; 00099 const double overflow_secs; 00101 int running; 00102 00104 virtual double seconds() const 00105 { 00106 return ((double) clock()) * secs_per_tick; 00107 } 00109 double adv_stopwatch() 00110 { 00111 const double secs = seconds(); 00112 double diff = secs - last_time; 00113 #ifdef __i386__ /* Extra precision is killing us on i386 */ 00114 if (diff < 0.0 && -diff < secs_per_tick/4) 00115 diff = 0.0; 00116 #endif 00117 if (overflow_secs != 0.0 && diff < 0.0) 00118 diff += overflow_secs; 00119 00120 last_time = secs; 00121 total += diff; 00122 return diff; 00123 } 00124 00125 public: 00127 stopw_base(const double tick, const double over = -1.0) 00128 : last_time(0.0) 00129 , total(0.0) 00130 , secs_per_tick (tick) 00131 , overflow_secs (over == -1.0 ? -tick * (2.0 * LONG_MIN): over) 00132 , running(0) 00133 {} 00135 virtual ~stopw_base() {} 00137 double reset() 00138 { 00139 const double t = total; 00140 last_time = 0.0; 00141 total = 0.0; running = 0; 00142 return t; 00143 } 00145 void start() 00146 { 00147 if (!running) { 00148 running = 1; last_time = seconds(); 00149 } else 00150 adv_stopwatch(); 00151 } 00153 double stop() 00154 { 00155 if (running) { 00156 running = 0; 00157 adv_stopwatch(); 00158 } 00159 return total; 00160 } 00162 double stop_d() 00163 { 00164 if (running) { 00165 running = 0; 00166 return adv_stopwatch(); 00167 } else 00168 return 0.0; 00169 } 00173 double read() 00174 { 00175 if (running) 00176 adv_stopwatch(); 00177 return total; 00178 } 00181 double read_d() 00182 { 00183 if (running) 00184 return adv_stopwatch(); 00185 else 00186 return 0.0; 00187 } 00188 }; 00189 00193 class stopwatch : public stopw_base 00194 { 00195 public: 00196 stopwatch() : stopw_base(1.0/CPS) {} 00197 }; 00198 00199 #ifndef unix 00200 typedef stopwatch stopwatch_u; 00201 typedef stopwatch stopwatch_us; 00202 #else 00203 //#ifdef HAVE_SYS_TIMES_H 00204 #include <sys/times.h> 00205 //#endif 00210 class stopwatch_u : public stopw_base 00211 { 00212 protected: 00213 virtual double seconds() const 00214 { 00215 struct tms tims; 00216 /*if (*/times (&tims)/* < 0) STD__ cerr << "Error reading time!" << STD__ endl*/; 00217 return (double)(tims.tms_utime+tims.tms_cutime) * secs_per_tick; 00218 } 00219 00220 public: 00221 stopwatch_u() : stopw_base(1000000.0 / (CPS * CLK_TCK)) {} 00222 }; 00223 00228 class stopwatch_us : public stopw_base 00229 { 00230 protected: 00231 virtual double seconds() const 00232 { 00233 struct tms tims; 00234 /*if (*/times (&tims)/* < 0) STD__ cerr << "Error reading time!" << STD__ endl*/; 00235 return (double)(tims.tms_utime+tims.tms_cutime+tims.tms_stime+tims.tms_cstime) 00236 * secs_per_tick; 00237 } 00238 00239 public: 00240 stopwatch_us() : stopw_base(1000000.0 / (CPS * CLK_TCK)) {} 00241 }; 00242 00243 #endif /* unix */ 00244 00250 #ifdef unix 00251 //#ifdef HAVE_SYS_TIME_H 00252 #include <sys/time.h> 00253 //#endif 00254 00255 //#ifdef HAVE_GETTIMEOFDAY 00256 class stopwatch_e : public stopw_base 00257 { 00258 protected: 00259 double seconds() const 00260 { 00261 struct timeval tv; 00262 gettimeofday(&tv, NULL); 00263 return (double)tv.tv_sec + (double)tv.tv_usec * 0.000001; 00264 } 00265 00266 public: 00267 stopwatch_e() : stopw_base(0.000001, 0) {} 00268 }; 00269 //#endif /* HAVE_GETTIMEOFDAY */ 00270 00271 #else /* unix */ 00272 # ifdef _MSC_VER 00273 00274 #include <sys/timeb.h> 00275 00276 class stopwatch_e : public stopw_base 00277 { 00278 protected: 00279 double seconds() const 00280 { 00281 struct _timeb tb; 00282 _ftime(&tb); 00283 return (double)tb.time + (double)tb.millitm * 0.001; 00284 } 00285 00286 public: 00287 stopwatch_e() : stopw_base(0.001) {} 00288 }; 00289 00290 # else /* _MSC_VER */ 00291 00292 class stopwatch_e : public stopw_base 00293 { 00294 protected: 00295 double seconds() const 00296 { 00297 //time_t tm; 00298 return (double) time(0); 00299 } 00300 00301 public: 00302 stopwatch_e() : stopw_base(1.0) {} 00303 }; 00304 00305 # endif /* _MSC_VER */ 00306 00307 #endif /* unix */ 00308 00309 #endif /* TBCI_STOPWATCH_H */
1.5.6