Main Page   Modules   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members   Related Pages  

stopwatch.hpp

00001 //------------------------------------------------------------------------------
00002 // Stopwatch -- a cross platform performance timing class 
00003 // $Id: stopwatch.hpp,v 1.9 2001/10/04 13:21:59 baxter Exp $
00004 //------------------------------------------------------------------------------
00005 
00006 //------------------------------------------------------------------------------
00007 //  The interface is as follows:
00008 //   The first call to Start() begins the timer counting.
00009 //   Stop() stops the clock.
00010 //   Reset() clears the elapsed time to zero.
00011 //   The Stopwatch can be stopped and restarted.  Or even restarted without
00012 //   stopping.  This is useful for timing several periods of an event to get
00013 //   an average.  Everytime Start() is called an internal counter is 
00014 //   incremented.  The GetAvgTime() method reports the total elapsed time
00015 //   divided by the number of starts, while GetTime() just reports the 
00016 //   elapsed time.
00017 //
00018 //   The Stopwatch class measures wall clock time.
00019 //   The CPUStopwatch measures CPU time.  
00020 //
00021 //   Both will hopefully be implemented with best possible precision on
00022 //   your platform.
00023 //
00024 //   Watch out for GetTime() and GetAvgTime().  They both report time in terms 
00025 //   of the most recent Stop() or re- Start()
00026 //
00027 //------------------------------------------------------------------------------
00028 
00029 //------------------------------------------------------------------------------
00030 // This has been tested on the following systems:
00031 //   OS                                   (COMPILER)
00032 //   --                                   ----------
00033 //   HP-UX B.10.20 A 9000/735 2006086919  (gcc 2.7.2.2)
00034 //   IRIX64 evans 6.5 11051731 IP27 (CC MipsPro 7.2.1 and gcc 2.7.2.1)
00035 //   SunOS 5.5.1 Generic_103640-24 sun4u sparc SUNW,Ultra-2 (gcc 2.7.2)
00036 //   Windows NT 4.0/2000 (MSVC 5.0/6.0)
00037 //------------------------------------------------------------------------------
00038 #ifndef GLVU_STOPWATCH_INCLUDED
00039 #define GLVU_STOPWATCH_INCLUDED
00040 
00041 
00042 #include <time.h>            // FOR clock and clock_gettime CALL
00043 #include <sys/timeb.h>       // FOR ftime CALL
00044 #ifndef _WIN32
00045 #include <sys/time.h>        // FOR gettimeofday CALL
00046 #else 
00047 #include <windows.h>
00048 #endif /* !_WIN32 */
00049 
00050 #define STOPWATCH_MAX_NAME 40
00051 
00052 //------------------------------------------------------------------------------
00053 // Base Interface
00054 //------------------------------------------------------------------------------
00055 class StopwatchBase
00056 {
00057 public:
00058   explicit StopwatchBase(const char *name=0);
00059   virtual ~StopwatchBase();
00060   inline void Start();
00061   inline void Stop();
00062   inline void Reset();       // Like a real stopwatch, DOES NOT STOP THE CLOCK
00063   inline float GetTime() const;     // Instantaneous elapsed time
00064   float GetAvgTime() const;  // NOT ACCURATE IF NOT STOPPED!
00065   int GetNumStarts() const;
00066   void SetName(const char *n);   // sets identifier for this timer
00067   void SetName(int id);          // converts the int to a string name
00068   const char* GetName() const;
00069   const char* GetType() const;   // Return short description of implemntation
00070 
00071 protected:
00072   float elapsedTime;     // the accumulated elapsed time
00073   int numStarts;         // number of calls to Start since last Reset
00074   char sw_name[STOPWATCH_MAX_NAME];  // a name for the stopwatch
00075   const char *sw_type;
00076   bool running;
00077 
00078   // THESE ARE THE METHODS SUBCLASSES NEED TO IMPLEMENT
00079   virtual void markTime()=0;   // jot down the current timestamp
00080   virtual float diffTime() const =0; // return  current_timestamp - last_mark
00081 };
00082 
00083 
00084 // Ostream operator to report elapsed time results 
00085 // (defined as a template so you can call with either old- or
00086 // new-style io headers.  I.e. you can use either 'std::cout<<' or
00087 // 'cout<<', or any other object with an operator << for that matter)
00088 template <class _OSTREAM>
00089 inline _OSTREAM& operator<< (_OSTREAM& o, const StopwatchBase& s)
00090 {
00091   if (s.GetNumStarts() > 1) 
00092     o << s.GetName() << " avg time: " 
00093       << s.GetAvgTime() << " sec, (avg of " << s.GetNumStarts() << " periods)";
00094   else
00095     o << s.GetName() << " time: " << s.GetTime() << " sec";
00096   return o;
00097 }
00098 
00099 
00100 
00101 //------------------------------------------------------------------------------
00102 // Implementations
00103 //------------------------------------------------------------------------------
00104 
00105 class StopwatchGeneric : public StopwatchBase
00106 {
00107 public:
00108   StopwatchGeneric(const char* name=0);
00109   virtual ~StopwatchGeneric();
00110 protected:
00111   void markTime();
00112   float diffTime() const;
00113   struct timeb lastStamp;
00114 };
00115 
00116 #ifdef _WIN32
00117 class StopwatchWin32 : public StopwatchBase
00118 {
00119 public:
00120   StopwatchWin32(const char* name=0);
00121   virtual ~StopwatchWin32();
00122 protected:
00123   void markTime();
00124   float diffTime() const;
00125   LARGE_INTEGER lastStamp;
00126   static LARGE_INTEGER clockFreq;
00127   static bool clockFreqSet;
00128 };
00129 #endif
00130 
00131 class CPUStopwatchGeneric : public StopwatchBase
00132 {
00133 public:
00134   CPUStopwatchGeneric(const char* name=0);
00135   virtual ~CPUStopwatchGeneric();
00136 protected:
00137   void markTime();
00138   float diffTime() const;
00139   clock_t lastStamp;
00140 };
00141 
00142 #ifndef _WIN32
00143 class StopwatchGTOD : public StopwatchBase
00144 {
00145 public:
00146   StopwatchGTOD(const char* name=0);
00147   virtual ~StopwatchGTOD();
00148 protected:
00149   void markTime();
00150   float diffTime() const;
00151   struct timeval lastStamp;
00152 };
00153 #endif /* !_WIN32 */
00154 
00155 #ifdef CLOCK_SGI_CYCLE
00156 class StopwatchSGI : public StopwatchBase
00157 {
00158 public:
00159   StopwatchSGI(const char* name=0);
00160   virtual ~StopwatchSGI();
00161 protected:
00162   void markTime();
00163   float diffTime() const;
00164   timespec_t lastStamp;
00165 };
00166 #endif /* CLOCK_SGI_CYCLE */
00167 
00168 
00169 //------------------------------------------------------------------------------
00170 // Define Stopwatch and CPUStopwatch to be the best known clocks for platform
00171 //------------------------------------------------------------------------------
00172 typedef CPUStopwatchGeneric CPUStopwatch;  // Is there any other?
00173 
00174 #ifdef _WIN32
00175 //typedef StopwatchGeneric Stopwatch;
00176 typedef StopwatchWin32 Stopwatch;
00177 #else /* UNIX */
00178 #ifdef CLOCK_SGI_CYCLE
00179 typedef StopwatchSGI Stopwatch;
00180 #else /* !CLOCK_SGI_CYCLE */
00181 typedef StopwatchGTOD Stopwatch;
00182 #endif /* !CLOCK_SGI_CYCLE */
00183 #endif /* !_WIN32 */
00184 
00185 
00186 
00187 
00188 
00189 
00190 //------------------------------------------------------------------------------
00191 // Inline method implementations
00192 //------------------------------------------------------------------------------
00193 void StopwatchBase::Start()
00194 {
00195   if (running) {
00196     numStarts++;
00197     return;
00198   }
00199   running = true;
00200   numStarts++;
00201   // markTime call should be last thing in function so we avoid timing 
00202   // our own activity as much as possible.
00203   markTime();
00204 }
00205 
00206 void StopwatchBase::Stop()
00207 {
00208   if (running) {
00209     elapsedTime += diffTime();
00210     running = false;
00211   }
00212 }
00213 
00214 void StopwatchBase::Reset()
00215 {
00216   if (running) { markTime(); numStarts=1; }
00217   else numStarts = 0;
00218   elapsedTime = 0.0f;
00219 }
00220 
00221 float StopwatchBase::GetTime() const
00222 {
00223   if (running) return (elapsedTime + diffTime());
00224   else return (elapsedTime);
00225 }
00226 
00227 
00228 
00229 
00230 #endif /* GLVU_STOPWATCH_INCLUDED */

Generated at Fri Oct 12 15:12:21 2001 for GLVU by doxygen1.2.10 written by Dimitri van Heesch, © 1997-2001