Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Namespace Members | Class Members | File Members | Related Pages

/ray/src/lib/htime.h

Go to the documentation of this file.
00001 /*
00002  * lib/htime.h
00003  * 
00004  * Time representation class. 
00005  * 
00006  * Copyright (c) 2001--2004 by Wolfgang Wieser ] wwieser (a) gmx <*> de [ 
00007  * 
00008  * This file may be distributed and/or modified under the terms of the 
00009  * GNU General Public License version 2 as published by the Free Software 
00010  * Foundation. (See COPYING.GPL for details.)
00011  * 
00012  * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
00013  * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
00014  * 
00015  */
00016 
00017 #ifndef _SRC_HTIME_H_
00018 #define _SRC_HTIME_H_ 1
00019 
00027 #include <lib/sconfig.h>    /* MUST be first */
00028 
00029 
00030 
00031 #if TIME_WITH_SYS_TIME
00032 # include <sys/time.h>
00033 # include <time.h>
00034 #else
00035 # if HAVE_SYS_TIME_H
00036 #  include <sys/time.h>
00037 # else
00038 #  include <time.h>
00039 # endif
00040 #endif
00041 
00042 #if !USE_PRIVATE__TIMEVAL
00043 # include <glib/gmain.h>   /* for g_get_current_time */
00044 # include <glib/gtimer.h>  /* for g_time_val_add */
00045 #endif  /* !USE_PRIVATE__TIMEVAL */
00046 
00047 #define HTIME_WITH_MOST_CURRENT 0
00048 
00049 
00060 class HTime
00061 {
00062     public:
00063         enum TimeSpec
00064         {  usec=0,msec,seconds,minutes,hours,days,_tslast  };
00065         enum _CurrentTime { Curr };
00066         enum _NullTime { Null };
00067         enum _InvalidTime { Invalid };
00068 #if HTIME_WITH_MOST_CURRENT
00069         enum _MostCurr { MostCurr };
00070     private:
00074         static FastMutex most_current_mutex;
00075         static HTime most_current;
00076 #endif
00077         
00078     public:
00079 #if USE_PRIVATE__TIMEVAL
00080         typedef ::timeval timeval;
00081 #else
00082         typedef ::GTimeVal timeval;
00083 #endif
00084         
00085     private:
00086         static inline void _gettimeofday(timeval *tv)
00087 #if USE_PRIVATE__TIMEVAL
00088         {  gettimeofday(tv,NULL);  }
00089 #else
00090         {  g_get_current_time(tv);  }
00091 #endif
00092         
00093         // Always use this instead of ::gettimeofday(). 
00094         static inline void do_gettimeofday(timeval *tv)
00095         {
00096             _gettimeofday(tv);
00097 #if HTIME_WITH_MOST_CURRENT
00098             most_current_mutex.lock();
00099             most_current.tv=*tv;
00100             most_current_mutex.unlock();
00101 #endif
00102         }
00103         
00104         // Conversion factors (constants): 
00105         static const int64_t conv_fact[];
00106         static const int64_t round_delta[];
00107         static const double conv_factD[];
00108         
00109     private:
00111         timeval tv;
00112         
00113         static inline void _Normalize(timeval *tv)
00114         {  register long m=tv->tv_usec/1000000;  if(tv->tv_usec<0)  --m;
00115             tv->tv_sec+=m;  tv->tv_usec-=1000000*m;  }
00116         
00117         void _SetVal(long val,TimeSpec sp,timeval *tv);
00118         void _SetValL(int64_t val,TimeSpec sp,timeval *tv);
00119         int64_t _Delta(const HTime *endtime) const;
00120         
00121         static inline int64_t _LLConv(const timeval *tv)
00122             {  return(int64_t(tv->tv_sec)*int64_t(1000000)+int64_t(tv->tv_usec));  }
00123         static inline int64_t _RoundAdd(int64_t x,TimeSpec sp)
00124             {  return(x + (x<0 ? (-round_delta[sp]) : round_delta[sp]));  }
00125         static inline long _RoundAddMs(long x)
00126             {  return((x<0) ? (x-500) : (x+500));  }
00127         
00128         int _DoReadTime(const char *str);  // See ReadTime(). 
00129         
00130     public:
00132         inline HTime()  {  tv.tv_usec=-2000000;  }  // see SetInvalid()
00134         HTime(_CurrentTime)  {  SetCurr();  }
00136         inline HTime(_NullTime)  {  tv.tv_sec=0;  tv.tv_usec=0;  }
00138         inline HTime(_InvalidTime)  {  tv.tv_usec=-2000000;  }  // see SetInvalid()
00139 #if HTIME_WITH_MOST_CURRENT
00143         inline HTime(_MostCurr)  {  tv=most_current.tv;  }
00144 #endif
00145         inline ~HTime()  { }
00146         
00148         inline HTime(const HTime &h) : tv(h.tv) { }
00149         inline HTime &operator=(const HTime &h)  {  tv=h.tv;  return(*this);  }
00150         
00154         inline void SetInvalid()  {  tv.tv_usec=-2000000;  }
00155         inline int IsInvalid() const  {  return(tv.tv_usec==-2000000);  }
00156         
00158         inline HTime(long val,TimeSpec sp=msec)  {  _SetVal(val,sp,&tv);  }
00159         inline void SetCurr()  {  do_gettimeofday(&tv);  }
00160         HTime &operator=(_CurrentTime)  {  SetCurr();  return(*this);  }
00161         HTime &operator=(_InvalidTime)  {  SetInvalid();  return(*this);  }
00162         HTime &operator=(_NullTime)     {  tv.tv_sec=0;  tv.tv_usec=0;  return(*this);  }
00163 #if HTIME_WITH_MOST_CURRENT
00164         HTime &operator=(_MostCurr)     {  tv=most_current.tv;  return(*this);  }
00165 #endif
00166         HTime &Set(long val,TimeSpec sp=msec)
00167             {  _SetVal(val,sp,&tv);  return(*this);  }
00168         HTime &SetL(int64_t val,TimeSpec sp=msec)
00169             {  _SetValL(val,sp,&tv);  return(*this);  }
00170         
00173         inline void PruneUsec()
00174             {  if(!IsInvalid())  tv.tv_usec=0;  }
00175         
00182         long   Get (TimeSpec sp) const
00183             {  return((sp<_tslast) ? long(_LLConv(&tv)/conv_fact[sp]) : (-1));  }
00187         long   GetR(TimeSpec sp) const
00188             {  return((sp<_tslast) ? long(_RoundAdd(_LLConv(&tv),sp)/conv_fact[sp]) : (-1));  }
00192         int64_t GetL(TimeSpec sp) const
00193             {  return((sp<_tslast) ? (_LLConv(&tv)/conv_fact[sp]) : (-1));  }
00197         int64_t GetLR(TimeSpec sp) const
00198             {  return((sp<_tslast) ? (_RoundAdd(_LLConv(&tv),sp)/conv_fact[sp]) : (-1));  }
00202         double GetD(TimeSpec sp) const
00203             {  return((sp<_tslast) ? (double(_LLConv(&tv))/conv_factD[sp]) : (-1.0));  }
00204         
00205 #if 0
00206         // This should not be used if avoidable: 
00207         void SetTimeval(timeval *stv)
00208             {  tv=*stv;  _Normalize(&tv);  }
00209         void SetTimeT(time_t st)
00210             {  tv.tv_sec=st;  tv.tv_usec=0;  }
00211 #endif
00212         
00215         HTime &Add(long val,TimeSpec sp=msec);
00216         HTime &Sub(long val,TimeSpec sp=msec);
00217         
00220         HTime operator-(const HTime &start) const;
00221         HTime &operator-=(const HTime &start);
00222         
00225         HTime operator+(const HTime &start) const;
00226         HTime &operator+=(const HTime &start);
00227         
00229         HTime &operator-();
00230         
00235         HTime &Div(int fact);
00236         
00242         inline int operator==(const HTime &h) const
00243             {  return(!IsInvalid() && !h.IsInvalid() && 
00244                       tv.tv_sec==h.tv.tv_sec && tv.tv_usec==h.tv.tv_usec);  }
00245         inline int operator!=(const HTime &h) const
00246             {  return(IsInvalid() || h.IsInvalid() || 
00247                       tv.tv_sec!=h.tv.tv_sec || tv.tv_usec!=h.tv.tv_usec);  }
00248         inline int operator>(const HTime &h) const
00249             {  return(tv.tv_sec>h.tv.tv_sec || 
00250                      (tv.tv_sec==h.tv.tv_sec && tv.tv_usec>h.tv.tv_usec));  }
00251         inline int operator<(const HTime &h) const
00252             {  return(tv.tv_sec<h.tv.tv_sec || 
00253                      (tv.tv_sec==h.tv.tv_sec && tv.tv_usec<h.tv.tv_usec));  }
00254         inline int operator>=(const HTime &h) const
00255             {  return(tv.tv_sec>h.tv.tv_sec || 
00256                      (tv.tv_sec==h.tv.tv_sec && tv.tv_usec>=h.tv.tv_usec));  }
00257         inline int operator<=(const HTime &h) const
00258             {  return(tv.tv_sec<h.tv.tv_sec || 
00259                      (tv.tv_sec==h.tv.tv_sec && tv.tv_usec<=h.tv.tv_usec));  }
00262         inline int operator==(_InvalidTime) const
00263             {  return(IsInvalid());  }
00264         inline int operator!=(_InvalidTime) const
00265             {  return(!IsInvalid());  }
00266         inline int operator==(_NullTime) const
00267             {  return(!IsInvalid() && !tv.tv_sec && !tv.tv_usec);  }
00268         inline int operator!=(_NullTime) const
00269             {  return(!IsInvalid() && (tv.tv_sec || tv.tv_usec));  }
00270         inline int operator>(_NullTime) const
00271             {  return(tv.tv_sec>0 || (tv.tv_sec==0 && tv.tv_usec>0));  }
00272         inline int operator<(_NullTime) const
00273         //  {  return(tv.tv_sec<0 || (tv.tv_sec==0 && tv.tv_usec<0));  }
00274             {  return(tv.tv_sec<0);  }   // because tv.tv_usec<0 NEVER 
00275         inline int operator>=(_NullTime) const
00276         //  {  return(tv.tv_sec>0 || (tv.tv_sec==0 && tv.tv_usec>=0));  }
00277             {  return(tv.tv_sec>=0);  }  // because tv.tv_usec>=0 ALWAYS 
00278         inline int operator<=(_NullTime) const
00279             {  return(tv.tv_sec<0 || (tv.tv_sec==0 && tv.tv_usec<=0));  }
00280         
00281         // True if time value is 0, otherwise false: [not needed]
00282         //inline bool operator!() const
00283         //  {  return(!tv.tv_sec && !tv.tv_usec);  }
00284         
00292         long   Elapsed (TimeSpec sp,const HTime *endtime=NULL) const
00293             {  return((sp<_tslast) ? long(_Delta(endtime)/conv_fact[sp]) : (-1L));  }
00294         int64_t ElapsedL(TimeSpec sp,const HTime *endtime=NULL) const
00295             {  return((sp<_tslast) ? (_Delta(endtime)/conv_fact[sp]) : (-1L));  }
00296         long   ElapsedR(TimeSpec sp,const HTime *endtime=NULL) const
00297             {  return((sp<_tslast) ? long(_RoundAdd(_Delta(endtime),sp)/conv_fact[sp]) : (-1L));  }
00298         double ElapsedD(TimeSpec sp,const HTime *endtime=NULL) const
00299             {  return((sp<_tslast) ? (double(_Delta(endtime))/conv_factD[sp]) : (-1.0));  }
00306         long MsecElapsed(const HTime *endtime) const  // endtime is NON-NULL
00307             {  return((endtime->tv.tv_sec  - tv.tv_sec )*1000L + 
00308                       (endtime->tv.tv_usec - tv.tv_usec)/1000L );  }
00309         long MsecElapsedR(const HTime *endtime) const  // endtime is NON-NULL
00310             {  return( (endtime->tv.tv_sec  - tv.tv_sec )*1000L + 
00311             _RoundAddMs(endtime->tv.tv_usec - tv.tv_usec)/1000L );  }
00312         long MsecElapsed() const;
00313         long MsecElapsedR() const;
00314         
00323         char *PrintTime(char *buf,size_t len,int local=1,int with_msec=0) const;
00324         
00325         // FIXME: could add a function using strftime(3) 
00326         //        (time formatting like date(1)). 
00327         
00333         char *PrintElapsed(char *buf,size_t len,int with_msec=1) const;
00334         
00372         int ReadTime(const char *str)
00373             {  int rv=_DoReadTime(str);  if(rv) SetInvalid();  return(rv);  }
00374 };
00375 
00376 #endif  /* _SRC_HTIME_H_ */

Generated on Sat Feb 19 22:33:45 2005 for Ray by doxygen 1.3.5