lmi-commits
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[lmi-commits] [lmi] master 8e64944 4/4: Change timer class's internal ti


From: Greg Chicares
Subject: [lmi-commits] [lmi] master 8e64944 4/4: Change timer class's internal time type
Date: Mon, 28 May 2018 20:45:40 -0400 (EDT)

branch: master
commit 8e649447064939f32467d865978c9941a3d54a6c
Author: Gregory W. Chicares <address@hidden>
Commit: Gregory W. Chicares <address@hidden>

    Change timer class's internal time type
    
    Rationale: see (removed) excerpt from glibc documentation.
---
 timer.cpp      | 50 +++++++++++++++++++++++++++-----------------------
 timer.hpp      | 51 ++++++++++++++-------------------------------------
 timer_test.cpp |  4 ++--
 3 files changed, 43 insertions(+), 62 deletions(-)

diff --git a/timer.cpp b/timer.cpp
index 33d40af..6182a47 100644
--- a/timer.cpp
+++ b/timer.cpp
@@ -23,7 +23,9 @@
 
 #include "timer.hpp"
 
-#if defined LMI_MSW
+#if defined LMI_POSIX
+#   include <sys/time.h>                // gettimeofday()
+#elif defined LMI_MSW
     // TRICKY !! There being no standard way to ascertain whether
     // <windows.h> has been included, we resort to this hack:
 #   if defined STDCALL || defined WM_COMMAND
@@ -37,14 +39,18 @@
     // increase compile times for small programs, and because it requires
     // ms extensions and defines many macros.
 #   if !defined LMI_MS_HEADER_INCLUDED
-    // These declarations would be erroneous if the ms headers were
-    // included. It's necessary to guard against that explicitly,
-    // because those headers might be implicitly included by a pch
-    // mechanism.
-        extern "C" int __stdcall QueryPerformanceCounter(elapsed_t*);
-        extern "C" int __stdcall QueryPerformanceFrequency(elapsed_t*);
+#       include <cstdint>
+        typedef std::uint64_t msw_elapsed_t;
+        // These declarations would be erroneous if the ms headers were
+        // included. It's necessary to guard against that explicitly,
+        // because those headers might be implicitly included by a pch
+        // mechanism.
+        extern "C" int __stdcall QueryPerformanceCounter  (msw_elapsed_t*);
+        extern "C" int __stdcall QueryPerformanceFrequency(msw_elapsed_t*);
 #   endif // !defined LMI_MS_HEADER_INCLUDED
-#endif // defined LMI_MSW
+#else // Unknown platform.
+#   include <ctime>                     // clock()
+#endif // Unknown platform.
 
 /// Suspend execution for a given number of seconds.
 
@@ -128,8 +134,6 @@ std::string Timer::elapsed_msec_str() const
 ///  - Timer must have been stopped; throws if it is still running.
 ///  - frequency_ must be nonzero (guaranteed by ctor), so that
 ///    dividing by it is safe.
-///
-/// The static_casts are necessary in case elapsed_t is integral.
 
 double Timer::elapsed_seconds() const
 {
@@ -140,27 +144,27 @@ double Timer::elapsed_seconds() const
             );
         }
 
-    return static_cast<double>(elapsed_time_) / 
static_cast<double>(frequency_);
+    return elapsed_time_ / frequency_;
 }
 
 /// Ascertain timer frequency in ticks per second.
 
-elapsed_t Timer::calibrate()
+double Timer::calibrate()
 {
 #if defined LMI_POSIX
-    return 1000000;
+    return 1000000.0;
 #elif defined LMI_MSW
 #   if defined LMI_MS_HEADER_INCLUDED
     LARGE_INTEGER z;
     QueryPerformanceFrequency(&z);
-    return z.QuadPart;
+    return static_cast<double>(z.QuadPart);
 #   else  // !defined LMI_MS_HEADER_INCLUDED
-    elapsed_t z;
+    msw_elapsed_t z;
     QueryPerformanceFrequency(&z);
-    return z;
+    return static_cast<double>(z);
 #   endif // !defined LMI_MS_HEADER_INCLUDED
 #else // Unknown platform.
-    return CLOCKS_PER_SEC;
+    return static_cast<double>(CLOCKS_PER_SEC);
 #endif // Unknown platform.
 }
 
@@ -181,24 +185,24 @@ void Timer::start()
 
 /// Ticks elapsed since timer started.
 
-elapsed_t Timer::inspect() const
+double Timer::inspect() const
 {
 #if defined LMI_POSIX
     timeval x;
     gettimeofday(&x, nullptr);
-    return elapsed_t(1000000) * x.tv_sec + x.tv_usec;
+    return x.tv_usec + 1000000.0 * x.tv_sec;
 #elif defined LMI_MSW
 #   if defined LMI_MS_HEADER_INCLUDED
     LARGE_INTEGER z;
     QueryPerformanceCounter(&z);
-    return z.QuadPart;
+    return static_cast<double>(z.QuadPart);
 #   else  // !defined LMI_MS_HEADER_INCLUDED
-    elapsed_t z;
+    msw_elapsed_t z;
     QueryPerformanceCounter(&z);
-    return z;
+    return static_cast<double>(z);
 #   endif // !defined LMI_MS_HEADER_INCLUDED
 #else // Unknown platform.
-    return std::clock();
+    return static_cast<double>(std::clock());
 #endif // Unknown platform.
 }
 
diff --git a/timer.hpp b/timer.hpp
index 9261995..ab3cd27 100644
--- a/timer.hpp
+++ b/timer.hpp
@@ -26,20 +26,6 @@
 
 #include "so_attributes.hpp"
 
-#if defined LMI_POSIX
-#   include <sys/time.h>                // gettimeofday()
-    typedef double elapsed_t;
-#elif defined LMI_MSW
-    // Compilers for this platform use various types for its high-
-    // resolution timer, but they use the same platform API, so
-    // it's sufficient to use the same 64-bit integer type for all.
-#   include <cstdint>
-    typedef std::uint64_t elapsed_t;
-#else // Unknown platform.
-#   include <ctime>
-    typedef std::clock_t elapsed_t;
-#endif // Unknown platform.
-
 #include <iomanip>
 #include <ios>
 #include <ostream>
@@ -57,15 +43,6 @@ void lmi_sleep(unsigned int seconds);
 /// and that latency is a significant concern. This class uses a high-
 /// resolution timer if available; it's a sharp tool that lets you
 /// make your own decision about that rationale.
-///
-/// SOMEDAY !! Following the glibc guidance below, replace elapsed_t
-/// with double in the interface and the implementation.
-///
-/// 
http://www.gnu.org/software/libc/manual/html_node/Processor-And-CPU-Time.html
-/// "clock_t and ... CLOCKS_PER_SEC can be either integer or floating-point
-/// types. Casting CPU time values to double ... makes sure that operations
-/// such as arithmetic and printing work properly and consistently no matter
-/// what the underlying representation is."
 
 class LMI_SO Timer
 {
@@ -76,8 +53,8 @@ class LMI_SO Timer
     Timer();
     ~Timer() = default;
 
-    Timer&      restart();
-    Timer&      stop();
+    Timer& restart();
+    Timer& stop();
 
     static std::string elapsed_msec_str(double seconds);
     std::string        elapsed_msec_str() const;
@@ -87,16 +64,16 @@ class LMI_SO Timer
     Timer(Timer const&) = delete;
     Timer& operator=(Timer const&) = delete;
 
-    elapsed_t   calibrate();
-    void        start();
+    double calibrate();
+    void   start();
 
-    elapsed_t   inspect() const;
+    double inspect() const;
 
-    elapsed_t   elapsed_time_;
-    elapsed_t   frequency_;
-    bool        is_running_;
-    elapsed_t   time_when_started_;
-    elapsed_t   time_when_stopped_;
+    double elapsed_time_;
+    double frequency_;
+    bool   is_running_;
+    double time_when_started_;
+    double time_when_stopped_;
 };
 
 /// Time an operation over an actively-adjusted number of repetitions.
@@ -173,7 +150,7 @@ AliquotTimer<F>::AliquotTimer(F f, double max_seconds)
     ,max_seconds_(max_seconds)
 {
     Timer timer;
-    if(max_seconds_ * static_cast<double>(timer.frequency_) < 1.0)
+    if(max_seconds_ * timer.frequency_ < 1.0)
         {
         std::ostringstream oss;
         oss
@@ -213,9 +190,9 @@ AliquotTimer<F>& AliquotTimer<F>::operator()()
         }
 
     Timer timer;
-    double const dbl_freq   = static_cast<double>(timer.frequency_);
+    double const dbl_freq   = timer.frequency_;
     double const limit      = max_seconds_ * dbl_freq;
-    double const start_time = static_cast<double>(timer.time_when_started_);
+    double const start_time = timer.time_when_started_;
     double const expiry_min = start_time + 0.01 * limit;
     double const expiry_max = start_time +        limit;
     double       now        = start_time;
@@ -226,7 +203,7 @@ AliquotTimer<F>& AliquotTimer<F>::operator()()
         {
         f_();
         previous = now;
-        now = static_cast<double>(timer.inspect());
+        now = timer.inspect();
         if(now - previous < minimum)
             {
             minimum = now - previous;
diff --git a/timer_test.cpp b/timer_test.cpp
index e94fb51..729c82e 100644
--- a/timer_test.cpp
+++ b/timer_test.cpp
@@ -27,7 +27,7 @@
 #include "miscellany.hpp"
 #include "test_tools.hpp"
 
-#include <cmath>
+#include <cmath>                        // log10()
 #include <functional>                   // bind()
 
 inline void do_nothing()
@@ -64,7 +64,7 @@ struct TimerTest
 void TimerTest::WaitTenMsec()
 {
     Timer timer;
-    double limit = 0.01 * static_cast<double>(timer.frequency_);
+    double limit = 0.01 * timer.frequency_;
     for(;timer.inspect() - timer.time_when_started_ <= limit;) {}
 }
 



reply via email to

[Prev in Thread] Current Thread [Next in Thread]