00001 /*!@file Util/Timer.H A simple class for precise time measurements */ 00002 00003 // //////////////////////////////////////////////////////////////////// // 00004 // The iLab Neuromorphic Vision C++ Toolkit - Copyright (C) 2001 by the // 00005 // University of Southern California (USC) and the iLab at USC. // 00006 // See http://iLab.usc.edu for information about this project. // 00007 // //////////////////////////////////////////////////////////////////// // 00008 // Major portions of the iLab Neuromorphic Vision Toolkit are protected // 00009 // under the U.S. patent ``Computation of Intrinsic Perceptual Saliency // 00010 // in Visual Environments, and Applications'' by Christof Koch and // 00011 // Laurent Itti, California Institute of Technology, 2001 (patent // 00012 // pending; application number 09/912,225 filed July 23, 2001; see // 00013 // http://pair.uspto.gov/cgi-bin/final/home.pl for current status). // 00014 // //////////////////////////////////////////////////////////////////// // 00015 // This file is part of the iLab Neuromorphic Vision C++ Toolkit. // 00016 // // 00017 // The iLab Neuromorphic Vision C++ Toolkit is free software; you can // 00018 // redistribute it and/or modify it under the terms of the GNU General // 00019 // Public License as published by the Free Software Foundation; either // 00020 // version 2 of the License, or (at your option) any later version. // 00021 // // 00022 // The iLab Neuromorphic Vision C++ Toolkit is distributed in the hope // 00023 // that it will be useful, but WITHOUT ANY WARRANTY; without even the // 00024 // implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // 00025 // PURPOSE. See the GNU General Public License for more details. // 00026 // // 00027 // You should have received a copy of the GNU General Public License // 00028 // along with the iLab Neuromorphic Vision C++ Toolkit; if not, write // 00029 // to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, // 00030 // Boston, MA 02111-1307 USA. // 00031 // //////////////////////////////////////////////////////////////////// // 00032 // 00033 // Primary maintainer for this file: Laurent Itti <itti@usc.edu> 00034 // $HeadURL: svn://isvn.usc.edu/software/invt/trunk/saliency/src/Util/Timer.H $ 00035 // $Id: Timer.H 14168 2010-10-27 00:44:20Z farhan $ 00036 // 00037 00038 #ifndef TIMER_H_DEFINED 00039 #define TIMER_H_DEFINED 00040 00041 #include "Util/SimTime.H" 00042 #include "Util/Types.H" // for uint64 00043 #include "Util/log.H" 00044 #include <sys/time.h> 00045 #include <unistd.h> 00046 00047 //! This class implements a real-time timer 00048 /*! Timing starts at construction or reset(). 00049 00050 At construction, you can decide on a number of timer ticks per second; 00051 use 1000 to count in milliseconds, 1000000 to count in microseconds, 00052 etc. The best resolution achievable is 1us, as this timer relies on 00053 the gettimeofday() system call, which has microsecond resolution. Use 00054 get() to measure the number of elapsed ticks since last reset(), or 00055 getSecs() to get the fractional number of seconds. Use ticksPerSec() 00056 to retrieve this value, for example to convert yourself your measured 00057 times back to seconds instead of using getSecs(). */ 00058 class Timer { 00059 public: 00060 //! Constructor; immediately start timing 00061 /*! @param tickspersec number of timer ticks per second; use 1000 to 00062 count in milliseconds, 1000000 to count in microseconds, 00063 etc. Values larger than 1000000 will throw a fatal error. If 00064 1000000/tickspersec is not integer, a fatal error will also 00065 occur. */ 00066 inline Timer(const int tickspersec = 1000); 00067 00068 //! Reset the timer and immediately start timing again 00069 inline void reset(); 00070 00071 //! Return elapsed time 00072 /*! Return value is the number of ticks since last reset or since 00073 construction. */ 00074 inline uint64 get() const; 00075 00076 //! Return elapsed time since last reset, and reset 00077 inline uint64 getReset(); 00078 00079 //! Returns number of ticks per second, as specified at construction 00080 inline int ticksPerSec() const; 00081 00082 //! Returns number of seconds since last reset 00083 inline double getSecs() const; 00084 00085 //! Returns number of milliseconds since last reset 00086 inline double getMilliSecs() const; 00087 00088 //! Returns the elapsed SimTime since last reset 00089 inline SimTime getSimTime() const; 00090 00091 //! Pause the timer 00092 inline void pause(); 00093 00094 //! Resume the timer 00095 inline void resume(); 00096 00097 protected: 00098 //! time unit multipliers 00099 int64 div, mul; 00100 //! timestamp of last reset() 00101 struct timeval tv; 00102 //! timer offset of pause()/resume() 00103 int64 offset; 00104 bool pauseFlag; 00105 }; 00106 00107 // ###################################################################### 00108 // ##### INLINE FUNCTIONS: 00109 // ###################################################################### 00110 00111 inline Timer::Timer(const int tickspersec) : 00112 div(1000000LL / int64(tickspersec)), mul(int64(tickspersec)),offset(0L),pauseFlag(false) 00113 { 00114 if (tickspersec > 1000000LL) LFATAL("tickspersec too large"); 00115 if (1000000LL % tickspersec) LFATAL("1000000/tickspersec not integer"); 00116 reset(); 00117 } 00118 00119 // ###################################################################### 00120 inline void Timer::reset() 00121 { gettimeofday(&tv, NULL); 00122 pauseFlag = false; 00123 offset = 0L; 00124 } 00125 00126 // ###################################################################### 00127 inline uint64 Timer::get() const 00128 { 00129 if(pauseFlag) 00130 return offset; 00131 00132 struct timeval tv2; gettimeofday(&tv2, NULL); 00133 return uint64(int64(tv2.tv_usec - tv.tv_usec) / div + 00134 int64(tv2.tv_sec - tv.tv_sec ) * mul) + offset; 00135 } 00136 00137 // ###################################################################### 00138 inline uint64 Timer::getReset() 00139 { 00140 struct timeval tv2; gettimeofday(&tv2, NULL); 00141 uint64 ret = uint64(int64(tv2.tv_usec - tv.tv_usec) / div + 00142 int64(tv2.tv_sec - tv.tv_sec ) * mul); 00143 tv.tv_sec = tv2.tv_sec; tv.tv_usec = tv2.tv_usec; 00144 return ret; 00145 } 00146 00147 // ###################################################################### 00148 inline int Timer::ticksPerSec() const 00149 { return int(mul); } 00150 00151 // ###################################################################### 00152 inline double Timer::getSecs() const 00153 { 00154 struct timeval tv2; gettimeofday(&tv2, NULL); 00155 return double(tv2.tv_usec - tv.tv_usec) / 1000000.0 + 00156 double(tv2.tv_sec - tv.tv_sec); 00157 } 00158 00159 // ###################################################################### 00160 inline double Timer::getMilliSecs() const 00161 { 00162 struct timeval tv2; gettimeofday(&tv2, NULL); 00163 return (double(tv2.tv_usec - tv.tv_usec) / 1000000.0 + 00164 double(tv2.tv_sec - tv.tv_sec))*1000; 00165 } 00166 00167 // ###################################################################### 00168 inline SimTime Timer::getSimTime() const 00169 { 00170 return SimTime::SECS(this->getSecs()); 00171 } 00172 00173 // ###################################################################### 00174 inline void Timer::pause() 00175 { 00176 if(!pauseFlag){ 00177 offset = get(); 00178 pauseFlag = true; 00179 } 00180 } 00181 // ###################################################################### 00182 inline void Timer::resume() 00183 { 00184 if(pauseFlag){ 00185 pauseFlag = false; 00186 gettimeofday(&tv, NULL); 00187 } 00188 } 00189 #endif 00190 00191 // ###################################################################### 00192 /* So things look consistent in everyone's emacs... */ 00193 /* Local Variables: */ 00194 /* indent-tabs-mode: nil */ 00195 /* End: */