]> Dogcows Code - chaz/yoink/blobdiff - src/timer.cc
big batch of progress
[chaz/yoink] / src / timer.cc
index 2c7a1cbc39e05f3957422cc7de6f7d0f71db6b64..de601ee5db999fa8e54ce456ac7a840216565bbb 100644 (file)
@@ -30,8 +30,6 @@
 #include <ctime>
 #include <cerrno>
 
-#include <SDL/SDL.h>
-
 #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 <SDL/SDL.h>
 
 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: *************************************************/
+
This page took 0.019923 seconds and 4 git commands to generate.