00001 #ifndef TIMER_HH 00002 #define TIMER_HH 00003 00004 #include <assert.h> 00005 #include <stdlib.h> 00006 #include <unistd.h> 00007 #include <time.h> 00008 #include <sys/times.h> 00009 #include <stdio.h> 00010 00017 class Timer { 00018 public: 00020 Timer(); 00021 00023 void start(); 00024 00026 void stop(); 00027 00030 void snapshot(); 00031 00033 void reset(); 00034 00036 clock_t real_ticks() const; 00037 00039 clock_t user_ticks() const; 00040 00042 clock_t sys_ticks() const; 00043 00045 clock_t user_sys_ticks() const; 00046 00048 float real_sec() const; 00049 00051 float user_sec() const; 00052 00054 float sys_sec() const; 00055 00057 float user_sys_sec() const; 00058 00059 protected: 00060 clock_t m_final_real_ticks; 00061 clock_t m_final_user_ticks; 00062 clock_t m_final_sys_ticks; 00063 clock_t m_temp_real_ticks; 00064 clock_t m_temp_user_ticks; 00065 clock_t m_temp_sys_ticks; 00066 clock_t m_real_start; 00067 clock_t m_user_start; 00068 clock_t m_sys_start; 00069 long m_ticks_per_sec; 00070 bool m_running; 00071 }; 00072 00073 inline 00074 Timer::Timer() 00075 { 00076 m_running = false; 00077 reset(); 00078 m_ticks_per_sec = sysconf(_SC_CLK_TCK); 00079 if (m_ticks_per_sec <= 0) { 00080 perror("ERROR: sysconf(_SC_CLK_TCK) failed"); 00081 exit(1); 00082 } 00083 } 00084 00085 inline 00086 void 00087 Timer::start() 00088 { 00089 assert(!m_running); 00090 m_running = true; 00091 00092 struct tms tms; 00093 clock_t ret = times(&tms); 00094 if (ret == (clock_t)-1) { 00095 perror("ERROR: times() failed"); 00096 exit(1); 00097 } 00098 m_real_start = ret; 00099 m_user_start = tms.tms_utime; 00100 m_sys_start = tms.tms_stime; 00101 m_temp_real_ticks = m_user_start; 00102 m_temp_user_ticks = m_user_start; 00103 m_temp_sys_ticks = m_sys_start; 00104 } 00105 00106 inline 00107 void 00108 Timer::stop() 00109 { 00110 assert(m_running); 00111 m_running = false; 00112 00113 struct tms tms; 00114 clock_t ret = times(&tms); 00115 if (ret < 0) { 00116 perror("ERROR: times() failed"); 00117 exit(1); 00118 } 00119 m_final_real_ticks += ret - m_real_start; 00120 m_final_user_ticks += tms.tms_utime - m_user_start; 00121 m_final_sys_ticks += tms.tms_stime - m_sys_start; 00122 } 00123 00124 inline 00125 void 00126 Timer::snapshot() 00127 { 00128 assert(m_running); 00129 00130 struct tms tms; 00131 clock_t ret = times(&tms); 00132 if (ret < 0) { 00133 perror("ERROR: times() failed"); 00134 exit(1); 00135 } 00136 m_temp_real_ticks = ret - m_real_start; 00137 m_temp_user_ticks = tms.tms_utime - m_user_start; 00138 m_temp_sys_ticks = tms.tms_stime - m_sys_start; 00139 } 00140 00141 inline 00142 void 00143 Timer::reset() 00144 { 00145 assert(!m_running); 00146 m_final_real_ticks = 0; 00147 m_final_user_ticks = 0; 00148 m_final_sys_ticks = 0; 00149 m_temp_real_ticks = 0; 00150 m_temp_user_ticks = 0; 00151 m_temp_sys_ticks = 0; 00152 m_real_start = 0; 00153 m_user_start = 0; 00154 m_sys_start = 0; 00155 } 00156 00157 inline 00158 clock_t 00159 Timer::real_ticks() const 00160 { 00161 if (m_running) 00162 return m_temp_real_ticks; 00163 return m_final_real_ticks; 00164 } 00165 00166 inline 00167 clock_t 00168 Timer::user_ticks() const 00169 { 00170 if (m_running) 00171 return m_temp_user_ticks; 00172 return m_final_user_ticks; 00173 } 00174 00175 inline 00176 clock_t 00177 Timer::sys_ticks() const 00178 { 00179 if (m_running) 00180 return m_temp_sys_ticks; 00181 return m_final_sys_ticks; 00182 } 00183 00184 inline 00185 clock_t 00186 Timer::user_sys_ticks() const 00187 { 00188 if (m_running) 00189 return m_temp_user_ticks + m_temp_sys_ticks; 00190 return m_final_user_ticks + m_final_sys_ticks; 00191 } 00192 00193 inline 00194 float 00195 Timer::real_sec() const 00196 { 00197 if (m_running) 00198 return (float)m_temp_real_ticks / (float)m_ticks_per_sec; 00199 return (float)m_final_real_ticks / (float)m_ticks_per_sec; 00200 } 00201 00202 inline 00203 float 00204 Timer::user_sec() const 00205 { 00206 if (m_running) 00207 return (float)m_temp_user_ticks / (float)m_ticks_per_sec; 00208 return (float)m_final_user_ticks / (float)m_ticks_per_sec; 00209 } 00210 00211 inline 00212 float 00213 Timer::sys_sec() const 00214 { 00215 if (m_running) 00216 return (float)m_temp_sys_ticks / (float)m_ticks_per_sec; 00217 return (float)m_final_sys_ticks / (float)m_ticks_per_sec; 00218 } 00219 00220 inline 00221 float 00222 Timer::user_sys_sec() const 00223 { 00224 return user_sys_ticks() / (float)m_ticks_per_sec; 00225 } 00226 00227 #endif /* TIMER_HH */