timeval.hxx

Go to the documentation of this file.
00001 // Copyright (C) 2003, 2004, 2005 Laboratoire de Recherche en Informatique
00002 
00003 // This file is part of Qolyester.
00004 
00005 // Qolyester is free software; you can redistribute it and/or
00006 // modify it under the terms of the GNU General Public License
00007 // as published by the Free Software Foundation; either version 2
00008 // of the License, or (at your option) any later version.
00009 
00010 // Qolyester is distributed in the hope that it will be useful,
00011 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00012 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013 // GNU General Public License for more details.
00014 
00015 // You should have received a copy of the GNU General Public License
00016 // along with this program; if not, write to the Free Software
00017 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
00018 
00019 #ifndef QOLYESTER_UTL_TIMEVAL_HXX
00020 # define QOLYESTER_UTL_TIMEVAL_HXX 1
00021 
00022 # include "timeval.hh"
00023 
00024 namespace olsr {
00025 
00026   namespace utl {
00027 
00028     TimeVal::TimeVal(unsigned sec, unsigned usec) {
00029       assert(usec < 1000000);
00030       _tv.tv_sec  = sec;
00031       _tv.tv_usec = usec;
00032     }
00033 
00034     TimeVal::TimeVal(const This& rhs) {
00035       assert(rhs._tv.tv_usec < 1000000);
00036       _tv = rhs._tv;
00037     }
00038 
00039     TimeVal::TimeVal(const ::timeval& rhs) {
00040       assert(rhs.tv_usec < 1000000);
00041       _tv = rhs;
00042     }
00043 
00044     TimeVal::TimeVal(const unsigned period) {
00045       _tv.tv_usec  = period * 1000;
00046       _tv.tv_sec   = _tv.tv_usec / 1000000;
00047       _tv.tv_usec %= 1000000;
00048     }
00049 
00050     TimeVal::TimeVal(const int period) {
00051       assert(period >= 0);
00052       _tv.tv_usec  = period * 1000;
00053       _tv.tv_sec   = _tv.tv_usec / 1000000;
00054       _tv.tv_usec %= 1000000;
00055     }
00056 
00057     TimeVal::TimeVal(const double seconds) {
00058       _tv.tv_sec  = (unsigned) seconds;
00059       _tv.tv_usec = (unsigned) ((seconds - _tv.tv_sec) * 1e6);
00060     }
00061     
00062     int
00063     TimeVal::poll_time() const {
00064 //    This is the way to have an exact condition, but since we don't
00065 //    care, we prefer the second way, which is faster.
00066 //       if (_tv.tv_sec == INT_MAX / 1000 &&
00067 //           _tv.tv_usec > INT_MAX % 1000 * 1000 ||
00068 //           _tv.tv_sec > INT_MAX / 1000)
00069 
00070       if (_tv.tv_sec >= INT_MAX / 1000)
00071         return INT_MAX;
00072       return _tv.tv_sec * 1000 + _tv.tv_usec / 1000;
00073     }
00074 
00075     TimeVal
00076     TimeVal::operator+(const This& rhs) const {
00077       TimeVal   res(rhs);
00078 
00079       res._tv.tv_usec += _tv.tv_usec;
00080       res._tv.tv_sec  += _tv.tv_sec + res._tv.tv_usec / 1000000;
00081       res._tv.tv_usec %= 1000000;
00082       
00083       return res;
00084     }
00085     
00086     TimeVal
00087     TimeVal::operator-(const This& rhs) const {
00088       assert(rhs <= *this);
00089 
00090       TimeVal   res(*this);
00091 
00092       res._tv.tv_usec -= rhs._tv.tv_usec;
00093       res._tv.tv_sec  -= rhs._tv.tv_sec;
00094 
00095       res._tv.tv_usec %= 1000000;
00096 
00097       if (res._tv.tv_usec < 0) {
00098         res._tv.tv_usec += 1000000;
00099         --res._tv.tv_sec;
00100       }
00101 
00102       return res;
00103     }
00104 
00105     float
00106     TimeVal::diff(const This& rhs) const {
00107       float     val = distance(rhs).to_float();
00108 
00109       if (rhs <= *this)
00110         return val;
00111       return -val;
00112     }
00113 
00114     TimeVal
00115     TimeVal::distance(const This& rhs) const {
00116       const This&       r = rhs < *this ? rhs : *this;
00117       const This&       l = *this < rhs ? rhs : *this;
00118 
00119       return l - r;
00120     }
00121 
00122     TimeVal
00123     TimeVal::operator+(unsigned msec) const {
00124       return *this + TimeVal(msec / 1000, (msec % 1000) * 1000);
00125     }
00126     
00127     TimeVal&
00128     TimeVal::operator+=(unsigned msec) {
00129       _tv.tv_usec += msec * 1000;
00130       _tv.tv_sec  += _tv.tv_usec / 1000000;
00131       _tv.tv_usec %= 1000000;
00132       return *this; 
00133     }
00134 
00135     TimeVal&    
00136     TimeVal::operator+=(const This& rhs) {
00137       _tv.tv_usec += rhs._tv.tv_usec;
00138       _tv.tv_sec  += rhs._tv.tv_sec + _tv.tv_usec / 1000000;
00139       _tv.tv_usec %= 1000000;
00140       assert(_tv.tv_sec >= 0);
00141       return *this;
00142     }
00143     
00144     bool
00145     TimeVal::operator<(const This& rhs) const {
00146       if (_tv.tv_sec == rhs._tv.tv_sec)
00147         return _tv.tv_usec < rhs._tv.tv_usec;
00148       return _tv.tv_sec < rhs._tv.tv_sec;
00149     }
00150     
00151     TimeVal
00152     TimeVal::abs() const {
00153       ::timeval ret = _tv;
00154         
00155       if (ret.tv_sec < 0)
00156         ret.tv_sec = -ret.tv_sec;
00157 
00158       return This(ret);
00159     }
00160 
00161     //
00162     // This method compares two TimeVals with a granularity of
00163     // utl::internal::delta.
00164     //
00165     bool
00166     TimeVal::is_past(const This& now) const {
00167 //       return *this < (now + internal::delta);
00168       return *this <= now;
00169     }
00170 
00171     bool
00172     TimeVal::operator==(const This& rhs) const {
00173       return _tv.tv_sec == rhs._tv.tv_sec && _tv.tv_usec == rhs._tv.tv_usec;
00174     }
00175     
00176     bool
00177     TimeVal::operator!=(const This& rhs) const {
00178       return !operator==(rhs);
00179     }
00180 
00181     bool
00182     TimeVal::operator<=(const This& rhs) const {
00183       return *this < rhs || *this == rhs;
00184     }
00185 
00186     TimeVal
00187     TimeVal::operator*(const double& f) const {
00188       assert(f >= 0);
00189 
00190 //       double value = _tv.tv_sec + _tv.tv_usec * 1e-6;
00191 //       return This(f * value);
00192 
00193       typedef std::numeric_limits<long> nl_t;
00194       
00195       ::timeval res = _tv;
00196 
00197       assert(res.tv_usec <= nl_t::max() / f);
00198 
00199       res.tv_usec = long(res.tv_usec * f);
00200 
00201       long      carry = res.tv_usec / 1000000;
00202 
00203       res.tv_usec %= 1000000;
00204 
00205       assert(res.tv_sec <= (nl_t::max() - carry) / f);
00206 
00207       res.tv_sec = long(res.tv_sec * f) + carry;
00208 
00209       res.tv_usec +=
00210         long((res.tv_sec * f - long(res.tv_sec * f)) * 1e6) % 1000000;
00211 
00212       assert((long) res.tv_sec <= nl_t::max() - res.tv_usec / 1000000);
00213 
00214       res.tv_sec += res.tv_usec / 1000000;
00215 
00216       res.tv_usec %= 1000000;
00217 
00218       return This(res);
00219     }
00220 
00221     TimeVal
00222     TimeVal::operator/(const double& f) const {
00223       assert(f > 0);
00224       ::timeval res;
00225       double            sec  = _tv.tv_sec / f;
00226       res.tv_sec  = unsigned(sec);
00227       res.tv_usec = unsigned((sec - double(unsigned(sec))) * 1e6 +
00228                              _tv.tv_usec / double(f));
00229       return This(res);
00230     }
00231 
00232     TimeVal
00233     TimeVal::jitter(const This& j) {
00234       double usecs = j._tv.tv_sec * 1e6 + j._tv.tv_usec;
00235       double rands = usecs * (rand() / (RAND_MAX + 1.));
00236       ::timeval res;
00237       res.tv_sec  = unsigned(rands / 1e6);
00238       res.tv_usec = unsigned(rands - res.tv_sec * 1e6);
00239       return This(res);
00240     }
00241 
00242     void
00243     TimeVal::set_now(const This& now) {
00244       _now = now;
00245     }
00246 
00247     float
00248     TimeVal::to_float() const {
00249       return _tv.tv_sec + _tv.tv_usec / 1e6f;
00250     }
00251 
00252     const TimeVal
00253     TimeVal::real_now() {
00254       ::timeval tmp;
00255 # ifndef NDEBUG
00256       assert(::gettimeofday(&tmp, NULL) == 0);
00257 # else
00258       ::gettimeofday(&tmp, NULL);
00259 # endif
00260       return TimeVal(tmp);
00261     }
00262 
00263     const TimeVal
00264     TimeVal::in(const This& x) {
00265       return _now + x;
00266     }
00267 
00268     inline
00269     std::ostream& operator<<(std::ostream& o, const TimeVal& t)
00270     {
00271       return o << "{ sec = " << static_cast<timeval>(t).tv_sec
00272                << ", usec = " << static_cast<timeval>(t).tv_usec << " }";
00273     }
00274 
00275   } // namespace utl
00276 
00277 } // namespace olsr
00278 
00279 #endif // ! QOLYESTER_UTL_TIMEVAL_HXX

Generated on Mon Sep 10 17:02:13 2007 for Qolyester daemon by  doxygen 1.5.1