00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
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
00065
00066
00067
00068
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
00163
00164
00165 bool
00166 TimeVal::is_past(const This& now) const {
00167
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 ::timeval res = _tv;
00190
00191 res.tv_usec = unsigned(res.tv_usec * f);
00192 res.tv_sec = unsigned(res.tv_sec * (f + res.tv_usec / 1000000));
00193 res.tv_usec %= 1000000;
00194
00195 return This(res);
00196 }
00197
00198 TimeVal
00199 TimeVal::operator/(const double& f) const {
00200 assert(f > 0);
00201 ::timeval res;
00202 double sec = _tv.tv_sec / f;
00203 res.tv_sec = unsigned(sec);
00204 res.tv_usec = unsigned((sec - double(unsigned(sec))) * 1e6 +
00205 _tv.tv_usec / double(f));
00206 return This(res);
00207 }
00208
00209 TimeVal
00210 TimeVal::jitter(const This& j) {
00211 double usecs = j._tv.tv_sec * 1e6 + j._tv.tv_usec;
00212 double rands = usecs * (rand() / (RAND_MAX + 1.));
00213 ::timeval res;
00214 res.tv_sec = unsigned(rands / 1e6);
00215 res.tv_usec = unsigned(rands - res.tv_sec * 1e6);
00216 return This(res);
00217 }
00218
00219 void
00220 TimeVal::set_now(const This& now) {
00221 _now = now;
00222 }
00223
00224 float
00225 TimeVal::to_float() const {
00226 return _tv.tv_sec + _tv.tv_usec / 1e6f;
00227 }
00228
00229 const TimeVal
00230 TimeVal::real_now() {
00231 ::timeval tmp;
00232 # ifndef NDEBUG
00233 assert(::gettimeofday(&tmp, NULL) == 0);
00234 # else
00235 ::gettimeofday(&tmp, NULL);
00236 # endif
00237 return TimeVal(tmp);
00238 }
00239
00240 const TimeVal
00241 TimeVal::in(const This& x) {
00242 return _now + x;
00243 }
00244
00245 inline
00246 std::ostream& operator<<(std::ostream& o, const TimeVal& t)
00247 {
00248 return o << "{ sec = " << static_cast<timeval>(t).tv_sec
00249 << ", usec = " << static_cast<timeval>(t).tv_usec << " }";
00250 }
00251
00252 }
00253
00254 }
00255
00256 #endif // ! QOLYESTER_UTL_TIMEVAL_HXX