00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #ifndef _SRC_HTIME_H_
00018 #define _SRC_HTIME_H_ 1
00019
00027 #include <lib/sconfig.h>
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>
00044 # include <glib/gtimer.h>
00045 #endif
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
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
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);
00129
00130 public:
00132 inline HTime() { tv.tv_usec=-2000000; }
00134 HTime(_CurrentTime) { SetCurr(); }
00136 inline HTime(_NullTime) { tv.tv_sec=0; tv.tv_usec=0; }
00138 inline HTime(_InvalidTime) { tv.tv_usec=-2000000; }
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
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
00274 { return(tv.tv_sec<0); }
00275 inline int operator>=(_NullTime) const
00276
00277 { return(tv.tv_sec>=0); }
00278 inline int operator<=(_NullTime) const
00279 { return(tv.tv_sec<0 || (tv.tv_sec==0 && tv.tv_usec<=0)); }
00280
00281
00282
00283
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
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
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
00326
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