00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030 #include "w_defines.h"
00031
00032
00033
00034
00035 #include <ctime>
00036 #include <cstring>
00037 #include <w_base.h>
00038 #include <stime.h>
00039 #include <w_stream.h>
00040 #include <climits>
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052 #define NS_SECOND 1000000000
00053 #define US_SECOND 1000000
00054 #define MS_SECOND 1000
00055
00056 #ifdef USE_POSIX_TIME
00057 typedef struct timespec _stime_t;
00058 #define st_tod tv_sec
00059 #define st_hires tv_nsec
00060 #define HR_SECOND NS_SECOND
00061 #else
00062 typedef struct timeval _stime_t;
00063 #define st_tod tv_sec
00064 #define st_hires tv_usec
00065 #define HR_SECOND US_SECOND
00066 #endif
00067
00068 #define HR_MAX (HR_SECOND-1)
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083 stime_t::stime_t(time_t tod, long hires)
00084 {
00085 _time.st_tod = tod;
00086 _time.st_hires = hires;
00087
00088 normalize();
00089 }
00090
00091
00092 stime_t::stime_t(int secs)
00093 {
00094 _time.st_tod = secs;
00095 _time.st_hires = 0;
00096
00097
00098 }
00099
00100 stime_t::stime_t(long secs)
00101 {
00102 _time.st_tod = secs;
00103 _time.st_hires = 0;
00104
00105
00106 }
00107
00108
00109 stime_t::stime_t(double secs)
00110 {
00111 _time.st_tod = (long) secs;
00112 _time.st_hires = (long) ((secs - _time.st_tod) * HR_SECOND);
00113
00114
00115 }
00116
00117
00118 #ifdef USE_POSIX_TIME
00119 stime_t::stime_t(const struct timespec &tv)
00120 {
00121 _time.st_tod = tv.tv_sec;
00122 _time.st_hires = tv.tv_nsec * (HR_SECOND / NS_SECOND);
00123
00124 normalize();
00125 }
00126 #endif
00127
00128 stime_t::stime_t(const struct timeval &tv)
00129 {
00130 _time.st_tod = tv.tv_sec;
00131 _time.st_hires = tv.tv_usec * (HR_SECOND / US_SECOND);
00132
00133 normalize();
00134 }
00135
00136
00137 bool stime_t::operator==(const stime_t &r) const
00138 {
00139 return _time.st_tod == r._time.st_tod &&
00140 _time.st_hires == r._time.st_hires;
00141 }
00142
00143
00144 bool stime_t::operator<(const stime_t &r) const
00145 {
00146 if (_time.st_tod == r._time.st_tod)
00147 return _time.st_hires < r._time.st_hires;
00148 return _time.st_tod < r._time.st_tod;
00149 }
00150
00151
00152 bool stime_t::operator<=(const stime_t &r) const
00153 {
00154 return *this == r || *this < r;
00155 }
00156
00157
00158 static inline int sign(const int i)
00159 {
00160 return i > 0 ? 1 : i < 0 ? -1 : 0;
00161
00162 }
00163
00164
00165
00166
00167
00168
00169 void stime_t::signs()
00170 {
00171 if (_time.st_tod && _time.st_hires
00172 && sign(_time.st_tod) != sign(_time.st_hires)) {
00173
00174 if (sign(_time.st_tod) == 1) {
00175 _time.st_tod--;
00176 _time.st_hires += HR_SECOND;
00177 }
00178 else {
00179 _time.st_tod++;
00180 _time.st_hires -= HR_SECOND;
00181 }
00182 }
00183 }
00184
00185
00186 void stime_t::_normalize()
00187 {
00188 if (abs(_time.st_hires) >= HR_SECOND) {
00189 _time.st_tod += sign(_time.st_hires);
00190 _time.st_hires -= sign(_time.st_hires) * HR_SECOND;
00191 }
00192 signs();
00193 }
00194
00195
00196
00197 void stime_t::normalize()
00198 {
00199 int factor;
00200
00201 factor = _time.st_hires / HR_SECOND;
00202 if (factor) {
00203 _time.st_tod += factor;
00204 _time.st_hires -= HR_SECOND * factor;
00205 }
00206
00207 signs();
00208 }
00209
00210
00211 stime_t stime_t::operator-() const
00212 {
00213 stime_t result;
00214
00215 result._time.st_tod = -_time.st_tod;
00216 result._time.st_hires = -_time.st_hires;
00217
00218 return result;
00219 }
00220
00221
00222 stime_t stime_t::operator+(const stime_t &r) const
00223 {
00224 stime_t result;
00225
00226 result._time.st_tod = _time.st_tod + r._time.st_tod;
00227 result._time.st_hires = _time.st_hires + r._time.st_hires;
00228
00229 result._normalize();
00230
00231 return result;
00232 }
00233
00234
00235 stime_t stime_t::operator-(const stime_t &r) const
00236 {
00237 return *this + -r;
00238 }
00239
00240
00241 stime_t stime_t::operator*(const int factor) const
00242 {
00243 stime_t result;
00244
00245 result._time.st_tod = _time.st_tod * factor;
00246 result._time.st_hires = _time.st_hires * factor;
00247 result.normalize();
00248
00249 return result;
00250 }
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262 stime_t stime_t::operator/(const int factor) const
00263 {
00264 return *this / (double)factor;
00265 }
00266
00267
00268 stime_t stime_t::operator*(const double factor) const
00269 {
00270 double d = *this;
00271 d *= factor;
00272 stime_t result(d);
00273 result.normalize();
00274
00275 return result;
00276 }
00277
00278
00279 stime_t stime_t::operator/(const double factor) const
00280 {
00281 return *this * (1.0 / factor);
00282 }
00283
00284
00285
00286 stime_t &stime_t::operator+=(const stime_t &r)
00287 {
00288 _time.st_tod += r._time.st_tod;
00289 _time.st_hires += r._time.st_hires;
00290
00291 _normalize();
00292
00293 return *this;
00294 }
00295
00296
00297 stime_t &stime_t::operator-=(const stime_t &r)
00298 {
00299 _time.st_tod -= r._time.st_tod;
00300 _time.st_hires -= r._time.st_hires;
00301
00302 _normalize();
00303
00304 return *this;
00305 }
00306
00307
00308 stime_t::operator double() const
00309 {
00310 return _time.st_tod + _time.st_hires / (double) HR_SECOND;
00311 }
00312
00313
00314 stime_t::operator float() const
00315 {
00316 double res = (double) *this;
00317 return (float)res;
00318
00319 }
00320
00321
00322
00323
00324
00325
00326 #ifdef USE_POSIX_TIME
00327 stime_t::operator struct timespec() const
00328 {
00329 struct timespec tv;
00330 tv.tv_sec = _time.st_tod;
00331 tv.tv_nsec = _time.st_hires;
00332 return tv;
00333 }
00334 #endif
00335
00336
00337 stime_t::operator struct timeval() const
00338 {
00339 struct timeval tv;
00340 tv.tv_sec = _time.st_tod;
00341
00342
00343 tv.tv_usec = _time.st_hires / (HR_SECOND / US_SECOND);
00344 return tv;
00345 }
00346
00347
00348 void stime_t::gettime()
00349 {
00350 int kr;
00351 #ifdef USE_POSIX_TIME
00352 kr = clock_gettime(CLOCK_REALTIME, &_time);
00353 #else
00354 kr = gettimeofday(&_time, 0);
00355 #endif
00356 if (kr == -1)
00357 W_FATAL(fcOS);
00358 }
00359
00360
00361 ostream &stime_t::print(ostream &s) const
00362 {
00363 ctime(s);
00364
00365 if (_time.st_hires) {
00366 stime_t tod(_time.st_tod, 0);
00367
00368 s << " and " << sinterval_t(*this - tod);
00369 }
00370
00371 return s;
00372 }
00373
00374
00375 ostream &stime_t::ctime(ostream &s) const
00376 {
00377
00378 time_t kludge = _time.st_tod;
00379 const int buflen(26);
00380 char buf[buflen];
00381
00382
00383 #ifdef _POSIX_PTHREAD_SEMANTICS
00384 char *when = ctime_r(&kludge, buf);
00385 #elif defined(SOLARIS2)
00386 char *when = ctime_r(&kludge, buf, buflen);
00387 #else
00388 char *when = ctime_r(&kludge, buf);
00389 #endif
00390
00391
00392 char *nl = strchr(when, '\n');
00393 if (nl)
00394 *nl = '\0';
00395
00396 return s << when;
00397 }
00398
00399
00400 static void factor_print(ostream &s, long what)
00401 {
00402 struct {
00403 const char *label;
00404 int factor;
00405 } factors[] = {
00406 {"%02d:", 60*60},
00407 {"%02d:", 60},
00408 {0, 0}
00409 }, *f = factors;
00410 long mine;
00411 bool printed = false;
00412 bool negative = what < 0;
00413
00414 if (negative) {
00415 s << '-';
00416 what = -what;
00417 }
00418
00419 for (f = factors; f->label; f++) {
00420 mine = what / f->factor;
00421 what = what % f->factor;
00422 if (mine || printed) {
00423 W_FORM(s)(f->label, mine);
00424 printed = true;
00425 }
00426 }
00427
00428
00429 W_FORM(s)(printed ? "%02d" : "%d", what);
00430 }
00431
00432
00433 ostream &sinterval_t::print(ostream &s) const
00434 {
00435 factor_print(s, _time.st_tod);
00436
00437 if (_time.st_hires) {
00438 #ifdef USE_POSIX_TIME
00439 W_FORM(s)(".%09ld", _time.st_hires);
00440 #else
00441 W_FORM(s)(".%06ld", _time.st_hires);
00442 #endif
00443 }
00444
00445 return s;
00446 }
00447
00448
00449 ostream &operator<<(ostream &s, const stime_t &t)
00450 {
00451 return t.print(s);
00452 }
00453
00454
00455 ostream &operator<<(ostream &s, const sinterval_t &t)
00456 {
00457 return t.print(s);
00458 }
00459
00460
00461
00462
00463 static inline void from_linear(int sec, int xsec,
00464 int linear_secs, _stime_t &_time)
00465 {
00466 _time.st_tod = sec + xsec / linear_secs;
00467 xsec = xsec % linear_secs;
00468 if (linear_secs > HR_SECOND)
00469 _time.st_hires = xsec / (linear_secs / HR_SECOND);
00470 else
00471 _time.st_hires = xsec * (HR_SECOND / linear_secs);
00472 }
00473
00474
00475 stime_t stime_t::sec(int sec)
00476 {
00477 stime_t r;
00478
00479 r._time.st_tod = sec;
00480 r._time.st_hires = 0;
00481
00482 return r;
00483 }
00484
00485
00486 stime_t stime_t::msec(int ms, int sec)
00487 {
00488 stime_t r;
00489
00490 from_linear(sec, ms, MS_SECOND, r._time);
00491
00492
00493 return r;
00494 }
00495
00496
00497 stime_t stime_t::usec(int us, int sec)
00498 {
00499 stime_t r;
00500
00501 from_linear(sec, us, US_SECOND, r._time);
00502
00503
00504 return r;
00505 }
00506
00507
00508 stime_t stime_t::nsec(int ns, int sec)
00509 {
00510 stime_t r;
00511
00512 from_linear(sec, ns, NS_SECOND, r._time);
00513
00514
00515 return r;
00516 }
00517
00518
00519 stime_t stime_t::now()
00520 {
00521 stime_t now;
00522 now.gettime();
00523
00524 return now;
00525 }
00526
00527
00528
00529
00530
00531
00532 #define HR_ROUNDUP (HR_SECOND / 2)
00533
00534 static inline long to_linear(const _stime_t &_time, const int linear_secs)
00535 {
00536 long result;
00537 int factor;
00538
00539 result = _time.st_tod * linear_secs;
00540
00541 if (linear_secs > HR_SECOND) {
00542 factor = linear_secs / HR_SECOND;
00543 result += _time.st_hires * factor;
00544 }
00545 else {
00546 factor = HR_SECOND / linear_secs;
00547 result += _time.st_hires / factor;
00548 }
00549
00550 return result;
00551 }
00552
00553
00554 long stime_t::secs() const
00555 {
00556 long result;
00557
00558 result = _time.st_tod;
00559 if (_time.st_hires >= HR_ROUNDUP)
00560 result++;
00561
00562 return result;
00563 }
00564
00565 long stime_t::msecs() const
00566 {
00567 return to_linear(_time, MS_SECOND);
00568 }
00569
00570 long stime_t::usecs() const
00571 {
00572 return to_linear(_time, US_SECOND);
00573 }
00574
00575 long stime_t::nsecs() const
00576 {
00577 return to_linear(_time, NS_SECOND);
00578 }
00579
00580