X-Git-Url: https://git.dogcows.com/gitweb?p=chaz%2Fyoink;a=blobdiff_plain;f=src%2Ftimer.cc;h=de601ee5db999fa8e54ce456ac7a840216565bbb;hp=2c7a1cbc39e05f3957422cc7de6f7d0f71db6b64;hb=7d15b919681bb9ec0088b4b27c6abf62d6dfb9b1;hpb=0fffd0097d7b496454413e57b398c903ecc252e4 diff --git a/src/timer.cc b/src/timer.cc index 2c7a1cb..de601ee 100644 --- a/src/timer.cc +++ b/src/timer.cc @@ -30,8 +30,6 @@ #include #include -#include - #include "timer.hh" @@ -40,44 +38,59 @@ namespace dc { #if HAVE_LIBRT -scalar ticks() +// Since the monotonic clock will provide us with the timer since the computer +// started, the number of seconds since that time could easily become so large +// that it cannot be accurately stored in a float (even with as little two days +// update), therefore we need to start from a more recent reference (when the +// program starts). Of course this isn't much of an issue if scalar is a +// double-precious number. + +static time_t setReference() { struct timespec ts; if (clock_gettime(CLOCK_MONOTONIC, &ts) != 0) { - throw std::runtime_error("cannot access monotonic clock"); + return 0; } - return scalar(ts.tv_sec) + scalar(ts.tv_nsec) / 1000000000.0; + return ts.tv_sec; } -void sleep(scalar seconds, bool absolute) +static const time_t reference = setReference(); + + +scalar ticks() { struct timespec ts; - int ret; - if (!absolute) seconds += ticks(); - ts.tv_sec = time_t(seconds); - ts.tv_nsec = time_t((seconds - scalar(ts.tv_sec)) * 1000000000.0); - - do + if (clock_gettime(CLOCK_MONOTONIC, &ts) != 0) { - ret = clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, &ts, 0); + throw std::runtime_error("cannot access monotonic clock"); } - while (ret == -1 && errno == EINTR); + + return scalar(ts.tv_sec - reference) + scalar(ts.tv_nsec) / 1000000000.0; } + #else // ! HAVE_LIBRT -// If we don't have librt, we'll have to use different timing methods. + +// If we don't have librt, we'll have to use a different timing method. SDL +// only promises centisecond accuracy, but it may be better than nothing. + +#include scalar ticks() { - unsigned ms = SDL_GetTicks(); + Uint32 ms = SDL_GetTicks(); return scalar(ms / 1000) + scalar(ms % 1000) / 1000.0; } + +#endif // HAVE_LIBRT + + void sleep(scalar seconds, bool absolute) { struct timespec ts; @@ -85,7 +98,7 @@ void sleep(scalar seconds, bool absolute) if (absolute) seconds -= ticks(); ts.tv_sec = time_t(seconds); - ts.tv_nsec = time_t((seconds - scalar(ts.tv_sec)) * 1000000000.0); + ts.tv_nsec = long((seconds - scalar(ts.tv_sec)) * 1000000000.0); do { @@ -94,8 +107,8 @@ void sleep(scalar seconds, bool absolute) while (ret == -1 && errno == EINTR); } -#endif // HAVE_LIBRT - } // namespace dc +/** vim: set ts=4 sw=4 tw=80: *************************************************/ +