$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
Subject: [Boost-commit] svn:boost r55644 - trunk/libs/spirit/benchmarks
From: hartmut.kaiser_at_[hidden]
Date: 2009-08-17 22:17:03
Author: hkaiser
Date: 2009-08-17 22:17:03 EDT (Mon, 17 Aug 2009)
New Revision: 55644
URL: http://svn.boost.org/trac/boost/changeset/55644
Log:
Applied more high_resolution_timer fixes provided by Edward Grace
Text files modified: 
   trunk/libs/spirit/benchmarks/high_resolution_timer.hpp |    59 +++++++++++++++++++++++++++++++-------- 
   1 files changed, 47 insertions(+), 12 deletions(-)
Modified: trunk/libs/spirit/benchmarks/high_resolution_timer.hpp
==============================================================================
--- trunk/libs/spirit/benchmarks/high_resolution_timer.hpp	(original)
+++ trunk/libs/spirit/benchmarks/high_resolution_timer.hpp	2009-08-17 22:17:03 EDT (Mon, 17 Aug 2009)
@@ -323,6 +323,36 @@
     ///////////////////////////////////////////////////////////////////////////
     class high_resolution_timer
     {
+    private:
+        template <typename U>
+        static inline double unsigned_diff(const U &a, const U &b)
+        {
+            if (a > b)
+                return static_cast<double>(a-b);
+            return -static_cast<double>(b-a);
+        }
+
+        // @brief Return the difference between two timeval types.
+        // 
+        // @param t1 The most recent timeval.
+        // @param t0 The historical timeval.
+        // 
+        // @return The difference between the two in seconds.
+        double elapsed(const timeval &t1, const timeval &t0) const
+        { 
+            if (t1.tv_sec == t0.tv_sec)
+                return unsigned_diff(t1.tv_usec,t0.tv_usec) * 1e-6;
+
+            // We do it this way as the result of the difference of the
+            // microseconds can be negative if the clock is implemented so
+            // that the seconds timer increases in large steps.
+            //
+            // Naive subtraction of the unsigned types and conversion to
+            // double can wreak havoc!
+            return unsigned_diff(t1.tv_sec,t0.tv_sec) + 
+                unsigned_diff(t1.tv_usec,t0.tv_usec) * 1e-6; 
+        }
+
     public:
         high_resolution_timer() 
         {
@@ -368,12 +398,7 @@
             timeval now;
             if (gettimeofday(&now, NULL))
                 boost::throw_exception(std::runtime_error("Couldn't get current time"));
-
-            if (now.tv_sec == start_time.tv_sec)
-                return double(now.tv_usec - start_time.tv_usec) * 1e-6;
-
-            return double(now.tv_usec - start_time.tv_sec) + 
-                (double(now.tv_usec - start_time.tv_usec) * 1e-6);
+            return elapsed(now,start_time);
         }
 
         double elapsed_max() const   // return estimated maximum value for elapsed()
@@ -388,19 +413,18 @@
             // by repeatedly calling the gettimeofday function.  This
             // is often likely to be indicative of the true
             // resolution.
-            timeval a, b;
+            timeval t1, t2;
             double delta(0);
 
-            if (gettimeofday(&a, NULL)) 
+            if (gettimeofday(&t0, NULL)) 
                 boost::throw_exception(std::runtime_error("Couldn't get resolution."));
 
             // Spin around in a tight loop until we observe a change
             // in the reported timer value.
             do {
-                if (gettimeofday(&b, NULL)) 
+                if (gettimeofday(&t1, NULL)) 
                     boost::throw_exception(std::runtime_error("Couldn't get resolution."));
-                delta = double(b.tv_sec - a.tv_sec) + 
-                    double(b.tv_usec - a.tv_usec) * 1e-6;
+                delta = elapsed(t1, t0);
             } while (delta <= 0.0);
 
             return delta;
@@ -434,6 +458,17 @@
 
 #endif
 
-#endif
+#endif  // HIGH_RESOLUTION_TIMER_AUG_14_2009_0425PM
+
+//
+// $Log: high_resolution_timer.hpp,v $
+// Revision 1.4  2009/08/14 15:28:10  graceej
+// * It is entirely possible for the updating clock to increment the
+// * seconds and *decrement* the microseconds field.  Consequently
+// * when subtracting these unsigned microseconds fields a wrap-around
+// * error can occur.  For this reason elapsed(t1, t0) is used in a
+// * similar maner to cycle.h this preserves the sign of the
+// * difference.
+//