a 64bit time class
authorMathieu Lacage <mathieu.lacage@sophia.inria.fr>
Wed, 25 Aug 2010 10:05:01 +0200
changeset 7036 f94c610203be
parent 7035 8446ae042275
child 7037 76d6e8e13cb3
a 64bit time class
src/applications/onoff/onoff-application.cc
src/devices/spectrum/waveform-generator.cc
src/devices/wimax/bs-uplink-scheduler-mbqos.cc
src/simulator/nstime.h
src/simulator/time.cc
--- a/src/applications/onoff/onoff-application.cc	Wed Aug 25 10:04:47 2010 +0200
+++ b/src/applications/onoff/onoff-application.cc	Wed Aug 25 10:05:01 2010 +0200
@@ -168,7 +168,7 @@
       // Calculate residual bits since last packet sent
       Time delta(Simulator::Now() - m_lastStartTime);
       Scalar bits = delta * Scalar (m_cbrRate.GetBitRate ()) / Seconds (1.0);
-      m_residualBits += (uint32_t)bits.GetDouble ();
+      m_residualBits += bits;
     }
   Simulator::Cancel(m_sendEvent);
   Simulator::Cancel(m_startStopEvent);
--- a/src/devices/spectrum/waveform-generator.cc	Wed Aug 25 10:04:47 2010 +0200
+++ b/src/devices/spectrum/waveform-generator.cc	Wed Aug 25 10:05:01 2010 +0200
@@ -178,7 +178,7 @@
 
 double WaveformGenerator::GetDutyCycle () const
 {
-  return m_dutyCycle.GetDouble ();
+  return m_dutyCycle;
 }
 
 
--- a/src/devices/wimax/bs-uplink-scheduler-mbqos.cc	Wed Aug 25 10:04:47 2010 +0200
+++ b/src/devices/wimax/bs-uplink-scheduler-mbqos.cc	Wed Aug 25 10:05:01 2010 +0200
@@ -316,7 +316,7 @@
 
                       Scalar frame = ((timestamp - Simulator::Now ()) / frame_duration);
 
-                      if (frame.GetDouble () <= 1)
+                      if (frame <= 1)
                         {
                           // UGS Grants
                           // It is not necessary to enqueue UGS grants once it is periodically served
@@ -676,7 +676,7 @@
                                 <<" frame duration: "<< frame_duration );
 
               // should be schedule in this frame to max latency
-              if (frame.GetDouble () >= 3)
+              if (frame >= 3)
                 {
 
                   if (availableSymbols)
--- a/src/simulator/nstime.h	Wed Aug 25 10:04:47 2010 +0200
+++ b/src/simulator/nstime.h	Wed Aug 25 10:05:01 2010 +0200
@@ -26,10 +26,10 @@
 #include <stdint.h>
 #include <math.h>
 #include <ostream>
-#include "uint64x64.h"
 
 namespace ns3 {
 
+typedef uint64_t Scalar;
 
 /**
  * \ingroup simulator
@@ -175,26 +175,23 @@
   inline Time(const Time &o)
     : m_data (o.m_data)
   {}
-  explicit inline Time (const uint64x64_t &data)
-    : m_data (data)
-  {}
   explicit inline Time (double v)
-    : m_data (uint64x64_t (v))
+    : m_data (v)
   {}
   explicit inline Time (int v)
-    : m_data (uint64x64_t (v, 0))
+    : m_data (v)
   {}
   explicit inline Time (unsigned int v)
-    : m_data (uint64x64_t (v, 0))
+    : m_data (v)
   {}
   explicit inline Time (long int v)
-    : m_data (uint64x64_t (v, 0))
+    : m_data (v)
   {}
   explicit inline Time (unsigned long int v)
-    : m_data (uint64x64_t (v, 0))
+    : m_data (v)
   {}
   explicit inline Time (unsigned long long int v)
-    : m_data (uint64x64_t (v, 0))
+    : m_data (v)
   {}
 
   /**
@@ -220,35 +217,35 @@
    */
   inline bool IsZero (void) const
   {
-    return m_data == uint64x64_t ();
+    return m_data == 0;
   }
   /**
    * \return true if the time is negative or zero, false otherwise.
    */
   inline bool IsNegative (void) const
   {
-    return m_data <= uint64x64_t ();
+    return m_data <= 0;
   }
   /**
    * \return true if the time is positive or zero, false otherwise.
    */
   inline bool IsPositive (void) const
   {
-    return m_data >= uint64x64_t ();
+    return m_data >= 0;
   }
   /**
    * \return true if the time is strictly negative, false otherwise.
    */
   inline bool IsStrictlyNegative (void) const
   {
-    return m_data < uint64x64_t ();
+    return m_data < 0;
   }
   /**
    * \return true if the time is strictly positive, false otherwise.
    */
   inline bool IsStrictlyPositive (void) const
   {
-    return m_data > uint64x64_t ();
+    return m_data > 0;
   }
 
   inline int Compare (const Time &o) const
@@ -311,12 +308,11 @@
    */
   inline int64_t GetTimeStep (void) const
   {
-    int64_t timeValue = m_data.GetHigh ();
-    return timeValue;
+    return m_data;
   }
   inline double GetDouble (void) const
   {
-    return m_data.GetDouble ();
+    return m_data;
   }
   inline int64_t GetInteger (void) const
   {
@@ -352,9 +348,12 @@
     if (info->fromMul)
       {
         value *= info->factor;
-        return Time (uint64x64_t (value, 0));
       }
-    return From (uint64x64_t (value, 0), timeUnit);
+    else
+      {
+        value /= info->factor;
+      }
+    return Time (value);
   }
   /**
    * \param value to convert into a Time object
@@ -365,7 +364,12 @@
    */
   inline static Time FromDouble (double value, enum Unit timeUnit)
   {
-    return From (uint64x64_t (value), timeUnit);
+    struct Information *info = PeekInformation (timeUnit);
+    // DO NOT REMOVE this temporary variable. It's here
+    // to work around a compiler bug in gcc 3.4
+    double retval = value;
+    retval *= info->timeFrom;
+    return Time (retval);
   }
   /**
    * \param time a Time object
@@ -374,10 +378,10 @@
    * Convert the input time into an integer value according to the requested
    * time unit.
    */
-  inline static uint64_t ToInteger (const Time &time, enum Unit timeUnit)
+  inline static int64_t ToInteger (const Time &time, enum Unit timeUnit)
   {
     struct Information *info = PeekInformation (timeUnit);
-    uint64_t v = time.m_data.GetHigh ();
+    int64_t v = time.m_data;
     if (info->toMul)
       {
         v *= info->factor;
@@ -397,7 +401,10 @@
    */
   inline static double ToDouble (const Time &time, enum Unit timeUnit)
   {
-    return To (time, timeUnit).GetDouble ();
+    struct Information *info = PeekInformation (timeUnit);
+    double retval = time.m_data;
+    retval *= info->timeTo;
+    return retval;
   }
 
 private:
@@ -406,8 +413,8 @@
     bool toMul;
     bool fromMul;
     uint64_t factor;
-    uint64x64_t timeTo;
-    uint64x64_t timeFrom;
+    double timeTo;
+    double timeFrom;
   };
   struct Resolution
   {
@@ -424,36 +431,6 @@
   {
     return &(PeekResolution ()->info[timeUnit]);
   }
-  static inline Time From (uint64x64_t from, enum Unit timeUnit)
-  {
-    struct Information *info = PeekInformation (timeUnit);
-    // DO NOT REMOVE this temporary variable. It's here
-    // to work around a compiler bug in gcc 3.4
-    uint64x64_t tmp = from; 
-    if (info->fromMul)
-      {
-        tmp *= info->timeFrom;
-      }
-    else
-      {
-        tmp.MulByInvert (info->timeFrom);
-      }
-    return Time (tmp);
-  }
-  static inline uint64x64_t To (const Time &time, enum Unit timeUnit)
-  {
-    struct Information *info = PeekInformation (timeUnit);
-    uint64x64_t tmp = time.m_data;
-    if (info->toMul)
-      {
-        tmp *= info->timeTo;
-      }
-    else
-      {
-        tmp.MulByInvert (info->timeTo);
-      }
-    return tmp;
-  }
 
   static struct Resolution GetNsResolution (void);
   static void SetResolution (enum Unit unit, struct Resolution *resolution);
@@ -466,17 +443,19 @@
   friend bool operator > (const Time &lhs, const Time &rhs);
   friend Time operator + (const Time &lhs, const Time &rhs);
   friend Time operator - (const Time &lhs, const Time &rhs);
-  friend Time operator * (const Time &lhs, const Time &rhs);
-  friend Time operator / (const Time &lhs, const Time &rhs);
+  friend Time operator * (const Time &lhs, Scalar rhs);
+  friend Time operator * (Scalar lhs, const Time &rhs);
+  friend Time operator / (const Time &lhs, Scalar rhs);
+  friend Scalar operator / (const Time &lhs, const Time &rhs);
   friend Time &operator += (Time &lhs, const Time &rhs);
   friend Time &operator -= (Time &lhs, const Time &rhs);
-  friend Time &operator *= (Time &lhs, const Time &rhs);
-  friend Time &operator /= (Time &lhs, const Time &rhs);
+  friend Time &operator *= (Time &lhs, Scalar rhs);
+  friend Time &operator /= (Time &lhs, Scalar rhs);
   friend Time Abs (const Time &time);
   friend Time Max (const Time &ta, const Time &tb);
   friend Time Min (const Time &ta, const Time &tb);
 
-  uint64x64_t m_data;
+  int64_t m_data;
 };
 
 inline bool
@@ -517,13 +496,26 @@
 {
   return Time (lhs.m_data - rhs.m_data);
 }
-inline Time operator * (const Time &lhs, const Time &rhs)
+inline Time operator * (const Time &lhs, Scalar rhs)
 {
-  return Time (lhs.m_data * rhs.m_data);
+  Time retval = lhs;
+  retval *= rhs;
+  return retval;
+}
+inline Time operator * (Scalar lhs, const Time &rhs)
+{
+  return rhs * lhs;
 }
-inline Time operator / (const Time &lhs, const Time &rhs)
+inline Time operator / (const Time &lhs, Scalar rhs)
 {
-  return Time (lhs.m_data / rhs.m_data);
+  Time retval = lhs;
+  retval /= rhs;
+  return retval;
+}
+inline Scalar operator / (const Time &lhs, const Time &rhs)
+{
+  int64_t retval = lhs.GetTimeStep () / rhs.GetTimeStep ();
+  return retval;
 }
 inline Time &operator += (Time &lhs, const Time &rhs)
 {
@@ -535,18 +527,17 @@
   lhs.m_data -= rhs.m_data;
   return lhs;
 }
-inline Time &operator *= (Time &lhs, const Time &rhs)
+inline Time &operator *= (Time &lhs, Scalar rhs)
 {
-  lhs.m_data *= rhs.m_data;
+  lhs.m_data *= rhs;
   return lhs;
 }
-inline Time &operator /= (Time &lhs, const Time &rhs)
+inline Time &operator /= (Time &lhs, Scalar rhs)
 {
-  lhs.m_data /= rhs.m_data;
+  lhs.m_data /= rhs;
   return lhs;
 }
 
-
 /**
  * \anchor ns3-Time-Abs
  * \relates ns3::TimeUnit
@@ -555,7 +546,7 @@
  */
 inline Time Abs (const Time &time)
 {
-  return Time ((time.m_data < uint64x64_t (0))?-time.m_data:time.m_data);
+  return Time ((time.m_data < 0)?-time.m_data:time.m_data);
 }
 /**
  * \anchor ns3-Time-Max
@@ -673,10 +664,9 @@
 // internal function not publicly documented
 inline Time TimeStep (uint64_t ts)
 {
-  return Time (uint64x64_t (ts, 0));
+  return Time (ts);
 }
 
-typedef Time Scalar;
 typedef Time TimeInvert;
 typedef Time TimeSquare;
 
--- a/src/simulator/time.cc	Wed Aug 25 10:04:47 2010 +0200
+++ b/src/simulator/time.cc	Wed Aug 25 10:05:01 2010 +0200
@@ -106,23 +106,23 @@
       info->factor = factor;
       if (shift == 0)
 	{
-	  info->timeFrom = uint64x64_t (1, 0);
-	  info->timeTo = uint64x64_t (1, 0);
+	  info->timeFrom = 1.0;
+	  info->timeTo = 1.0;
 	  info->toMul = true;
 	  info->fromMul = true;
 	}
       else if (shift > 0)
 	{
-	  info->timeFrom = uint64x64_t (factor, 0);
-	  info->timeTo = uint64x64_t::Invert (factor);
+	  info->timeFrom = factor;
+	  info->timeTo = 1.0 / factor;
 	  info->toMul = false;
 	  info->fromMul = true;
 	}
       else
 	{
 	  NS_ASSERT (shift < 0);
-	  info->timeFrom = uint64x64_t::Invert (factor);
-	  info->timeTo = uint64x64_t (factor, 0);
+	  info->timeFrom = 1.0 / factor;
+	  info->timeTo = factor;
 	  info->toMul = true;
 	  info->fromMul = false;
 	}
@@ -186,27 +186,6 @@
 
 namespace ns3 {
 
-class Bug863TestCase : public TestCase
-{
-public:
-  Bug863TestCase ();
-  virtual bool DoRun (void);
-};
-
-Bug863TestCase::Bug863TestCase ()
-  : TestCase ("Bug 863")
-{
-}
-
-bool Bug863TestCase::DoRun (void)
-{
-  Scalar a = Scalar (0.9);
-  Scalar b = Scalar (1.0);
-  Scalar result = a / b;
-  NS_TEST_ASSERT_MSG_EQ ((result == Scalar (0.9)), true, "Invalid arithmetic result");
-  return false;
-}
-
 class TimeSimpleTestCase : public TestCase
 {
 public:
@@ -260,7 +239,6 @@
   TimeTestSuite ()
     : TestSuite ("time", UNIT)
   {
-    AddTestCase (new Bug863TestCase ());
     AddTestCase (new TimeSimpleTestCase (Time::US));
   }
 } g_timeTestSuite;