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