--- a/doc/tutorial/source/conceptual-overview.rst Sat Dec 15 11:32:58 2012 -0800
+++ b/doc/tutorial/source/conceptual-overview.rst Sat Dec 15 23:02:03 2012 -0800
@@ -340,20 +340,6 @@
the first function run. There is nothing at all special here. Your
|ns3| script is just a C++ program.
-The next line sets the time resolution to one nanosecond, which happens
-to be the default value:
-
-::
-
- Time::SetResolution (Time::NS);
-
-You can change the resolution exactly once (which must be before
-``Simulator::Run ()`` is called, below). The mechanism enabling this
-flexibility is somewhat memory hungry, so once the resolution has been
-set explicitly we release the memory, preventing further updates. (If
-you don't set the resolution explicitly, it will default to one nanosecond,
-and the memory will be released when the simulation starts.)
-
The next two lines of the script are used to enable two logging components that
are built into the Echo Client and Echo Server applications:
--- a/examples/tutorial/first.cc Sat Dec 15 11:32:58 2012 -0800
+++ b/examples/tutorial/first.cc Sat Dec 15 23:02:03 2012 -0800
@@ -27,7 +27,6 @@
int
main (int argc, char *argv[])
{
- Time::SetResolution (Time::NS);
LogComponentEnable ("UdpEchoClientApplication", LOG_LEVEL_INFO);
LogComponentEnable ("UdpEchoServerApplication", LOG_LEVEL_INFO);
--- a/src/core/bindings/callbacks_list.py Sat Dec 15 11:32:58 2012 -0800
+++ b/src/core/bindings/callbacks_list.py Sat Dec 15 23:02:03 2012 -0800
@@ -1,5 +1,5 @@
callback_classes = [
- ['void', 'unsigned char*', 'long', 'ns3::empty', 'ns3::empty', 'ns3::empty', 'ns3::empty', 'ns3::empty', 'ns3::empty', 'ns3::empty'],
+ ['void', 'unsigned char*', 'int', 'ns3::empty', 'ns3::empty', 'ns3::empty', 'ns3::empty', 'ns3::empty', 'ns3::empty', 'ns3::empty'],
['void', 'ns3::empty', 'ns3::empty', 'ns3::empty', 'ns3::empty', 'ns3::empty', 'ns3::empty', 'ns3::empty', 'ns3::empty', 'ns3::empty'],
['bool', 'std::string', 'ns3::empty', 'ns3::empty', 'ns3::empty', 'ns3::empty', 'ns3::empty', 'ns3::empty', 'ns3::empty', 'ns3::empty'],
]
--- a/src/core/bindings/modulegen__gcc_ILP32.py Sat Dec 15 11:32:58 2012 -0800
+++ b/src/core/bindings/modulegen__gcc_ILP32.py Sat Dec 15 23:02:03 2012 -0800
@@ -310,10 +310,6 @@
module.add_class('Vector3DChecker', parent=root_module['ns3::AttributeChecker'])
## vector.h (module 'core'): ns3::Vector3DValue [class]
module.add_class('Vector3DValue', parent=root_module['ns3::AttributeValue'])
- typehandlers.add_type_alias('ns3::Vector3D', 'ns3::Vector')
- typehandlers.add_type_alias('ns3::Vector3D*', 'ns3::Vector*')
- typehandlers.add_type_alias('ns3::Vector3D&', 'ns3::Vector&')
- module.add_typedef(root_module['ns3::Vector3D'], 'Vector')
typehandlers.add_type_alias('ns3::ObjectPtrContainerValue', 'ns3::ObjectVectorValue')
typehandlers.add_type_alias('ns3::ObjectPtrContainerValue*', 'ns3::ObjectVectorValue*')
typehandlers.add_type_alias('ns3::ObjectPtrContainerValue&', 'ns3::ObjectVectorValue&')
@@ -328,6 +324,10 @@
typehandlers.add_type_alias('void ( * ) ( std::ostream & ) *', 'ns3::LogNodePrinter')
typehandlers.add_type_alias('void ( * ) ( std::ostream & ) **', 'ns3::LogNodePrinter*')
typehandlers.add_type_alias('void ( * ) ( std::ostream & ) *&', 'ns3::LogNodePrinter&')
+ typehandlers.add_type_alias('ns3::Vector3D', 'ns3::Vector')
+ typehandlers.add_type_alias('ns3::Vector3D*', 'ns3::Vector*')
+ typehandlers.add_type_alias('ns3::Vector3D&', 'ns3::Vector&')
+ module.add_typedef(root_module['ns3::Vector3D'], 'Vector')
typehandlers.add_type_alias('ns3::Vector3DValue', 'ns3::VectorValue')
typehandlers.add_type_alias('ns3::Vector3DValue*', 'ns3::VectorValue*')
typehandlers.add_type_alias('ns3::Vector3DValue&', 'ns3::VectorValue&')
@@ -2382,11 +2382,6 @@
'int',
[param('ns3::Time const &', 'o')],
is_const=True)
- ## nstime.h (module 'core'): static void ns3::Time::FreezeResolution() [member function]
- cls.add_method('FreezeResolution',
- 'void',
- [],
- is_static=True)
## nstime.h (module 'core'): static ns3::Time ns3::Time::From(ns3::int64x64_t const & from, ns3::Time::Unit timeUnit) [member function]
cls.add_method('From',
'ns3::Time',
--- a/src/core/bindings/modulegen__gcc_LP64.py Sat Dec 15 11:32:58 2012 -0800
+++ b/src/core/bindings/modulegen__gcc_LP64.py Sat Dec 15 23:02:03 2012 -0800
@@ -310,10 +310,6 @@
module.add_class('Vector3DChecker', parent=root_module['ns3::AttributeChecker'])
## vector.h (module 'core'): ns3::Vector3DValue [class]
module.add_class('Vector3DValue', parent=root_module['ns3::AttributeValue'])
- typehandlers.add_type_alias('ns3::Vector3D', 'ns3::Vector')
- typehandlers.add_type_alias('ns3::Vector3D*', 'ns3::Vector*')
- typehandlers.add_type_alias('ns3::Vector3D&', 'ns3::Vector&')
- module.add_typedef(root_module['ns3::Vector3D'], 'Vector')
typehandlers.add_type_alias('ns3::ObjectPtrContainerValue', 'ns3::ObjectVectorValue')
typehandlers.add_type_alias('ns3::ObjectPtrContainerValue*', 'ns3::ObjectVectorValue*')
typehandlers.add_type_alias('ns3::ObjectPtrContainerValue&', 'ns3::ObjectVectorValue&')
@@ -328,6 +324,10 @@
typehandlers.add_type_alias('void ( * ) ( std::ostream & ) *', 'ns3::LogNodePrinter')
typehandlers.add_type_alias('void ( * ) ( std::ostream & ) **', 'ns3::LogNodePrinter*')
typehandlers.add_type_alias('void ( * ) ( std::ostream & ) *&', 'ns3::LogNodePrinter&')
+ typehandlers.add_type_alias('ns3::Vector3D', 'ns3::Vector')
+ typehandlers.add_type_alias('ns3::Vector3D*', 'ns3::Vector*')
+ typehandlers.add_type_alias('ns3::Vector3D&', 'ns3::Vector&')
+ module.add_typedef(root_module['ns3::Vector3D'], 'Vector')
typehandlers.add_type_alias('ns3::Vector3DValue', 'ns3::VectorValue')
typehandlers.add_type_alias('ns3::Vector3DValue*', 'ns3::VectorValue*')
typehandlers.add_type_alias('ns3::Vector3DValue&', 'ns3::VectorValue&')
@@ -2382,11 +2382,6 @@
'int',
[param('ns3::Time const &', 'o')],
is_const=True)
- ## nstime.h (module 'core'): static void ns3::Time::FreezeResolution() [member function]
- cls.add_method('FreezeResolution',
- 'void',
- [],
- is_static=True)
## nstime.h (module 'core'): static ns3::Time ns3::Time::From(ns3::int64x64_t const & from, ns3::Time::Unit timeUnit) [member function]
cls.add_method('From',
'ns3::Time',
--- a/src/core/model/nstime.h Sat Dec 15 11:32:58 2012 -0800
+++ b/src/core/model/nstime.h Sat Dec 15 23:02:03 2012 -0800
@@ -26,7 +26,6 @@
#include "int64x64.h"
#include <stdint.h>
#include <cmath>
-#include <set>
#include <ostream>
namespace ns3 {
@@ -37,48 +36,115 @@
*/
/**
* \ingroup time
- * \brief Keep track of time values and allow control of global simulation resolution.
+ * \brief keep track of time unit.
+ *
+ * This template class is used to keep track of the value
+ * of a specific time unit: the type TimeUnit<1> is used to
+ * keep track of seconds, the type TimeUnit<2> is used to keep
+ * track of seconds squared, the type TimeUnit<-1> is used to
+ * keep track of 1/seconds, etc.
+ *
+ * This base class defines all the functionality shared by all
+ * these time unit objects: it defines all the classic arithmetic
+ * operators +, -, *, /, and all the classic comparison operators:
+ * ==, !=, <, >, <=, >=. It is thus easy to add, substract, or
+ * multiply multiple TimeUnit objects. The return type of any such
+ * arithmetic expression is always a TimeUnit object.
+ *
+ * The ns3::uint64_t, ns3::Time, ns3::TimeSquare, and ns3::TimeInvert classes
+ * are aliases for the TimeUnit<0>, TimeUnit<1>, TimeUnit<2> and TimeUnit<-1>
+ * types respectively.
*
- * This class defines the classic addition/subtraction C++ arithmetic
- * operators +, -, +=, -=, and all the classic comparison operators:
+ * For example:
+ * \code
+ * Time<1> t1 = Seconds (10.0);
+ * Time<1> t2 = Seconds (10.0);
+ * Time<2> t3 = t1 * t2;
+ * Time<0> t4 = t1 / t2;
+ * Time<3> t5 = t3 * t1;
+ * Time<-2> t6 = t1 / t5;
+ * TimeSquare t7 = t3;
+ * uint64_t s = t4;
+ * \endcode
+ *
+ * If you try to assign the result of an expression which does not
+ * match the type of the variable it is assigned to, you will get a
+ * compiler error. For example, the following will not compile:
+ * \code
+ * Time<1> = Seconds (10.0) * Seconds (1.5);
+ * \endcode
+ *
+ * You can also use the following non-member functions to manipulate
+ * any of these ns3::TimeUnit object:
+ * - \ref ns3-Time-Abs ns3::Abs
+ * - \ref ns3-Time-Max ns3::Max
+ * - \ref ns3-Time-Min ns3::Min
+ */
+/**
+ * \ingroup time
+ * \brief keep track of time values and allow control of global simulation resolution
+ *
+ * This class defines all the classic C++ arithmetic
+ * operators +, -, *, /, and all the classic comparison operators:
* ==, !=, <, >, <=, >=. It is thus easy to add, substract, or
- * compare Time objects.
+ * multiply multiple Time objects.
+ *
+ * The ns3::uint64_t, ns3::TimeSquare, and ns3::TimeInvert classes
+ * are backward-compatibility aliases for ns3::Time.
*
* For example:
* \code
* Time t1 = Seconds (10.0);
* Time t2 = Seconds (10.0);
- * Time t3 = t1;
- * t3 += t2;
+ * Time t3 = t1 * t2;
+ * Time t4 = t1 / t2;
+ * Time t5 = t3 * t1;
+ * Time t6 = t1 / t5;
+ * Time t7 = t3;
* \endcode
*
* You can also use the following non-member functions to manipulate
* any of these ns3::Time object:
- * - \ref Abs()
- * - \ref Max()
- * - \ref Min()
+ * - \ref ns3-Time-Abs ns3::Abs
+ * - \ref ns3-Time-Max ns3::Max
+ * - \ref ns3-Time-Min ns3::Min
*
- * This class also controls the resolution of the underlying time value.
- * The resolution is the smallest representable time interval.
- * The default resolution is nanoseconds.
+ * This class also controls
+ * the resolution of the underlying time value . The default resolution
+ * is nanoseconds. That is, TimeStep (1).GetNanoSeconds () will return
+ * 1. It is possible to either increase or decrease the resolution and the
+ * code tries really hard to make this easy.
*
- * To change the resolution, use SetResolution(). All Time objects created
- * before the call to SetResolution() will be updated to the new resolution.
- * This can only be done once! (Tracking each Time object uses 4 pointers.
- * For speed, once we convert the existing instances we discard the recording
- * data structure and stop tracking new instances, so we have no way
- * to do a second conversion.)
+ * If your resolution is X (say, nanoseconds) and if you create Time objects
+ * with a lower resolution (say, picoseconds), don't expect that this
+ * code will return 1: PicoSeconds (1).GetPicoSeconds (). It will most
+ * likely return 0 because the Time object has only 64 bits of fractional
+ * precision which means that PicoSeconds (1) is stored as a 64-bit aproximation
+ * of 1/1000 in the Time object. If you later multiply it again by the exact
+ * value 1000, the result is unlikely to be 1 exactly. It will be close to
+ * 1 but not exactly 1.
+ *
+ * In general, it is thus a really bad idea to try to use time objects of a
+ * resolution higher than the global resolution controlled through
+ * Time::SetResolution. If you do need to use picoseconds, it's thus best
+ * to switch the global resolution to picoseconds to avoid nasty surprises.
*
- * Because of the memory (and modest construction cost) of tracking Time
- * objects, simulations should explicitly choose a resolution before
- * calling Simulator::Run ().
+ * Another important issue to keep in mind is that if you increase the
+ * global resolution, you also implicitely decrease the range of your simulation.
+ * i.e., the global simulation time is stored in a 64 bit integer whose interpretation
+ * will depend on the global resolution so, 2^64 picoseconds which is the maximum
+ * duration of your simulation if the global resolution is picoseconds
+ * is smaller than 2^64 nanoseconds which is the maximum duration of your simulation
+ * if the global resolution is nanoseconds.
*
- * If you increase the global resolution, you also implicitly decrease
- * the range of your simulation. The global simulation time is stored
- * in a 64 bit integer, whose interpretation will depend on the global
- * resolution. Therefore the maximum duration of your simulation,
- * if you use picoseconds, is 2^64 ps = 2^24 s = 7 months, whereas,
- * had you used nanoseconds, you could have run for 584 years.
+ * Finally, don't even think about ever changing the global resolution after
+ * creating Time objects: all Time objects created before the call to SetResolution
+ * will contain values which are not updated to the new resolution. In practice,
+ * the default value for the attributes of many models is indeed calculated
+ * before the main function of the main program enters. Because of this, if you
+ * use one of these models (and it's likely), it's going to be hard to change
+ * the global simulation resolution in a way which gives reasonable results. This
+ * issue has been filed as bug 954 in the ns-3 bugzilla installation.
*/
class Time
{
@@ -88,12 +154,12 @@
*/
enum Unit
{
- S = 0, //!< second
- MS = 1, //!< millisecond
- US = 2, //!< microsecond
- NS = 3, //!< nanosecond
- PS = 4, //!< picosecond
- FS = 5, //!< femtosecond
+ S = 0,
+ MS = 1,
+ US = 2,
+ NS = 3,
+ PS = 4,
+ FS = 5,
LAST = 6
};
@@ -102,66 +168,44 @@
m_data = o.m_data;
return *this;
}
- inline Time &operator = (const int64_t &value)
- {
- m_data = value;
- return *this;
- }
inline Time ()
: m_data ()
- {
- Time::Track (this);
- }
+ {}
inline Time(const Time &o)
: m_data (o.m_data)
- {
- Time::Track (this);
- }
+ {}
explicit inline Time (double v)
: m_data (lround (v))
- {
- Time::Track (this);
- }
+ {}
explicit inline Time (int v)
: m_data (v)
- {
- Time::Track (this);
- }
+ {}
explicit inline Time (long int v)
: m_data (v)
- {
- Time::Track (this);
- }
+ {}
explicit inline Time (long long int v)
: m_data (v)
- {
- Time::Track (this);
- }
+ {}
explicit inline Time (unsigned int v)
: m_data (v)
- {
- Time::Track (this);
- }
+ {}
explicit inline Time (unsigned long int v)
: m_data (v)
- {
- Time::Track (this);
- }
+ {}
explicit inline Time (unsigned long long int v)
: m_data (v)
- {
- Time::Track (this);
- }
+ {}
+
/**
- * \brief Construct Time object from common time expressions like "1ms"
- *
- * Supported units include:
- * - `s` (seconds)
- * - `ms` (milliseconds)
- * - `us` (microseconds)
- * - `ns` (nanoseconds)
- * - `ps` (picoseconds)
- * - `fs` (femtoseconds)
+ * \brief String constructor
+ * Construct Time object from common time expressions like "
+ * 1ms" or "10s". Supported units include:
+ * - s (seconds)
+ * - ms (milliseconds)
+ * - us (microseconds)
+ * - ns (nanoseconds)
+ * - ps (picoseconds)
+ * - fs (femtoseconds)
*
* There can be no white space between the numerical portion
* and the units. Any otherwise malformed string causes a fatal error to
@@ -171,14 +215,6 @@
explicit Time (const std::string & s);
/**
- * Destructor
- */
- ~Time ()
- {
- Time::UnTrack (this);
- }
-
- /**
* \return true if the time is zero, false otherwise.
*/
inline bool IsZero (void) const
@@ -213,9 +249,7 @@
{
return m_data > 0;
}
- /**
- * \return -1,0,+1 if `this < o`, `this == o`, or `this > o`
- */
+
inline int Compare (const Time &o) const
{
return (m_data < o.m_data) ? -1 : (m_data == o.m_data) ? 0 : 1;
@@ -271,7 +305,8 @@
return ToInteger (Time::FS);
}
/**
- * \returns the raw time value, in the current units
+ * \returns an approximation of the time stored in this
+ * instance in the units specified in m_tsPrecision.
*/
inline int64_t GetTimeStep (void) const
{
@@ -293,19 +328,9 @@
* Change the global resolution used to convert all
* user-provided time values in Time objects and Time objects
* in user-expected time units.
- *
- * This function can be called only once. Further calls
- * will trigger a forced crash.
*/
static void SetResolution (enum Unit resolution);
/**
- * Freeze the current time resolution. This function is called
- * internally from the Simulator::Run function. After this
- * function is called, calls to SetResolution will trigger
- * an assert.
- */
- static void FreezeResolution(void);
- /**
* \returns the current global resolution.
*/
static enum Unit GetResolution (void);
@@ -411,38 +436,30 @@
}
explicit inline Time (const int64x64_t &value)
: m_data (value.GetHigh ())
- {
- Time::Track (this);
- }
+ {}
inline static Time From (const int64x64_t &value)
{
return Time (value);
}
private:
- /**
- * How to convert between other units and the current unit
- */
struct Information
{
- bool toMul; //!< Multiply when converting To, otherwise divide
- bool fromMul; //!< Multiple when converting From, otherwise divide
- uint64_t factor; //!< Ratio of this unit / current unit
- int64x64_t timeTo; //!< Multiplier to convert to this unit
- int64x64_t timeFrom; //!< Multiplier to convert from this unit
+ bool toMul;
+ bool fromMul;
+ uint64_t factor;
+ int64x64_t timeTo;
+ int64x64_t timeFrom;
};
- /**
- * Current time unit, and conversion info.
- */
struct Resolution
{
- struct Information info[LAST]; //!< Conversion info from current unit
- enum Time::Unit unit; //!< Current time unit
+ struct Information info[LAST];
+ enum Time::Unit unit;
};
static inline struct Resolution *PeekResolution (void)
{
- static struct Time::Resolution resolution = SetDefaultNsResolution ();
+ static struct Time::Resolution resolution = GetNsResolution ();
return &resolution;
}
static inline struct Information *PeekInformation (enum Unit timeUnit)
@@ -450,40 +467,8 @@
return &(PeekResolution ()->info[timeUnit]);
}
- static struct Resolution SetDefaultNsResolution (void);
+ static struct Resolution GetNsResolution (void);
static void SetResolution (enum Unit unit, struct Resolution *resolution);
- static void DoSetResolution (enum Unit unit, struct Resolution *resolution);
- static void FreezeResolution(enum Unit unit);
-
- /**
- * Record all instances of Time, so we can rescale them when
- * the resolution changes.
- *
- * \internal
- *
- * We use a std::set so we can remove the record easily when
- * ~Time() is called.
- *
- * We don't use Ptr<Time>, because we would have to bloat every Time
- * instance with SimpleRefCount<Time>.
- *
- * Seems like this should be std::set< Time * const >, but
- * http://stackoverflow.com/questions/5526019/compile-errors-stdset-with-const-members
- * (and gcc 4.2) say no.
- */
- typedef std::set< Time * > TimesSet;
- static TimesSet * GetTimesSet ();
- static TimesSet ** PeekTimesSet ();
- /**
- * Start tracking a Time instance with the TimesSet
- * to be able to change the underlying value if the
- * time resolution changes later
- */
- static void Track (Time * const time);
- /**
- * We do not need to track a Time instance anymore
- */
- static void UnTrack (Time * const time);
friend bool operator == (const Time &lhs, const Time &rhs);
friend bool operator != (const Time &lhs, const Time &rhs);
@@ -552,8 +537,8 @@
}
/**
- * Absolute value function for Time
- *
+ * \anchor ns3-Time-Abs
+ * \relates ns3::TimeUnit
* \param time the input value
* \returns the absolute value of the input value.
*/
@@ -562,6 +547,8 @@
return Time ((time.m_data < 0) ? -time.m_data : time.m_data);
}
/**
+ * \anchor ns3-Time-Max
+ * \relates ns3::TimeUnit
* \param ta the first value
* \param tb the seconds value
* \returns the max of the two input values.
@@ -571,6 +558,8 @@
return Time ((ta.m_data < tb.m_data) ? tb : ta);
}
/**
+ * \anchor ns3-Time-Min
+ * \relates ns3::TimeUnit
* \param ta the first value
* \param tb the seconds value
* \returns the min of the two input values.
@@ -581,19 +570,7 @@
}
-/**
- * \brief Time output streamer.
- *
- * Generates output such as "3.96ns"
- * \relates ns3::Time
- */
std::ostream& operator<< (std::ostream& os, const Time & time);
-/**
- * \brief Time input streamer
- *
- * Uses the Time::Time (std::string) constructor
- * \relates ns3::Time
- */
std::istream& operator>> (std::istream& is, Time & time);
/**
@@ -605,7 +582,6 @@
* Simulator::Schedule (Seconds (5.0), ...);
* \endcode
* \param seconds seconds value
- * \relates ns3::Time
*/
inline Time Seconds (double seconds)
{
@@ -621,7 +597,6 @@
* Simulator::Schedule (MilliSeconds (5), ...);
* \endcode
* \param ms milliseconds value
- * \relates ns3::Time
*/
inline Time MilliSeconds (uint64_t ms)
{
@@ -636,7 +611,6 @@
* Simulator::Schedule (MicroSeconds (5), ...);
* \endcode
* \param us microseconds value
- * \relates ns3::Time
*/
inline Time MicroSeconds (uint64_t us)
{
@@ -651,7 +625,6 @@
* Simulator::Schedule (NanoSeconds (5), ...);
* \endcode
* \param ns nanoseconds value
- * \relates ns3::Time
*/
inline Time NanoSeconds (uint64_t ns)
{
@@ -666,7 +639,6 @@
* Simulator::Schedule (PicoSeconds (5), ...);
* \endcode
* \param ps picoseconds value
- * \relates ns3::Time
*/
inline Time PicoSeconds (uint64_t ps)
{
@@ -681,7 +653,6 @@
* Simulator::Schedule (FemtoSeconds (5), ...);
* \endcode
* \param fs femtoseconds value
- * \relates ns3::Time
*/
inline Time FemtoSeconds (uint64_t fs)
{
@@ -689,50 +660,26 @@
}
-/**
- * \see Seconds(double)
- * \relates ns3::Time
- */
inline Time Seconds (int64x64_t seconds)
{
return Time::From (seconds, Time::S);
}
-/**
- * \see MilliSeconds(uint64_t)
- * \relates ns3::Time
- */
inline Time MilliSeconds (int64x64_t ms)
{
return Time::From (ms, Time::MS);
}
-/**
- * \see MicroSeconds(uint64_t)
- * \relates ns3::Time
- */
inline Time MicroSeconds (int64x64_t us)
{
return Time::From (us, Time::US);
}
-/**
- * \see NanoSeconds(uint64_t)
- * \relates ns3::Time
- */
inline Time NanoSeconds (int64x64_t ns)
{
return Time::From (ns, Time::NS);
}
-/**
- * \see PicoSeconds(uint64_t)
- * \relates ns3::Time
- */
inline Time PicoSeconds (int64x64_t ps)
{
return Time::From (ps, Time::PS);
}
-/**
- * \see FemtoSeconds(uint64_t)
- * \relates ns3::Time
- */
inline Time FemtoSeconds (int64x64_t fs)
{
return Time::From (fs, Time::FS);
--- a/src/core/model/simulator.cc Sat Dec 15 11:32:58 2012 -0800
+++ b/src/core/model/simulator.cc Sat Dec 15 23:02:03 2012 -0800
@@ -157,9 +157,7 @@
Simulator::Run (void)
{
NS_LOG_FUNCTION_NOARGS ();
- SimulatorImpl *impl = GetImpl ();
- Time::FreezeResolution();
- impl->Run ();
+ GetImpl ()->Run ();
}
void
--- a/src/core/model/time.cc Sat Dec 15 11:32:58 2012 -0800
+++ b/src/core/model/time.cc Sat Dec 15 23:02:03 2012 -0800
@@ -26,14 +26,17 @@
#include "string.h"
#include "object.h"
#include "config.h"
-#include "simulator.h"
+#include "log.h"
#include <cmath>
#include <sstream>
namespace ns3 {
+NS_LOG_COMPONENT_DEFINE ("Time");
+
Time::Time (const std::string& s)
{
+ NS_LOG_FUNCTION (this << &s);
std::string::size_type n = s.find_first_not_of ("+-0123456789.");
if (n != std::string::npos)
{ // Found non-numeric
@@ -45,83 +48,62 @@
if (trailer == std::string ("s"))
{
*this = Time::FromDouble (r, Time::S);
+ return;
}
- else if (trailer == std::string ("ms"))
+ if (trailer == std::string ("ms"))
{
*this = Time::FromDouble (r, Time::MS);
+ return;
}
- else if (trailer == std::string ("us"))
+ if (trailer == std::string ("us"))
{
*this = Time::FromDouble (r, Time::US);
+ return;
}
- else if (trailer == std::string ("ns"))
+ if (trailer == std::string ("ns"))
{
*this = Time::FromDouble (r, Time::NS);
+ return;
}
- else if (trailer == std::string ("ps"))
+ if (trailer == std::string ("ps"))
{
*this = Time::FromDouble (r, Time::PS);
+ return;
}
- else if (trailer == std::string ("fs"))
+ if (trailer == std::string ("fs"))
{
*this = Time::FromDouble (r, Time::FS);
+ return;
}
- else
- {
- NS_ABORT_MSG ("Can't Parse Time " << s);
- }
+ NS_ABORT_MSG ("Can't Parse Time " << s);
}
- else
- {
- // they didn't provide units, assume seconds
- std::istringstream iss;
- iss.str (s);
- double v;
- iss >> v;
- *this = Time::FromDouble (v, Time::S);
- }
-
- Time::Track (this);
+ // else
+ // they didn't provide units, assume seconds
+ std::istringstream iss;
+ iss.str (s);
+ double v;
+ iss >> v;
+ *this = Time::FromDouble (v, Time::S);
}
-// static
struct Time::Resolution
-Time::SetDefaultNsResolution (void)
+Time::GetNsResolution (void)
{
+ NS_LOG_FUNCTION_NOARGS ();
struct Resolution resolution;
- DoSetResolution (Time::NS, &resolution);
+ SetResolution (Time::NS, &resolution);
return resolution;
}
-
-// static
void
Time::SetResolution (enum Unit resolution)
{
+ NS_LOG_FUNCTION (resolution);
SetResolution (resolution, PeekResolution ());
}
-
-// static
-enum Time::Unit
-Time::GetResolution (void)
-{
- return PeekResolution ()->unit;
-}
-
-// static
void
Time::SetResolution (enum Unit unit, struct Resolution *resolution)
{
- if (Time::GetTimesSet() == 0)
- {
- NS_FATAL_ERROR("The resolution has already been set once. You cannot set it again.");
- }
- Time::FreezeResolution(unit);
- Time::DoSetResolution(unit, resolution);
-}
-// static
-void
-Time::DoSetResolution (enum Unit unit, struct Resolution *resolution)
-{
+ NS_LOG_FUNCTION (unit << resolution);
int8_t power [LAST] = { 15, 12, 9, 6, 3, 0};
for (int i = 0; i < Time::LAST; i++)
{
@@ -154,90 +136,18 @@
}
resolution->unit = unit;
}
-
-// static
-Time::TimesSet **
-Time::PeekTimesSet (void)
+enum Time::Unit
+Time::GetResolution (void)
{
- static TimesSet *times = new TimesSet();
- return ×
-}
-
-// static
-Time::TimesSet *
-Time::GetTimesSet ()
-{
- TimesSet **ptimes = PeekTimesSet();
- return *ptimes;
+ NS_LOG_FUNCTION_NOARGS ();
+ return PeekResolution ()->unit;
}
-// static
-void
-Time::FreezeResolution (void)
-{
- TimesSet **ptimes = PeekTimesSet();
- if (*ptimes == 0)
- {
- // We froze the resolution more than once: no big deal
- return;
- }
- delete *ptimes;
- *ptimes = 0;
-}
-void
-Time::FreezeResolution(enum Time::Unit unit)
-{
- // We are careful to remove the timeset _first_ because the code in the loop below
- // actually invokes a Time constructor which invokes the Track method which
- // adds things to the array we are iterating over.
- TimesSet **ptimes = PeekTimesSet();
- TimesSet *times = *ptimes;
- *ptimes = 0;
-
- for ( TimesSet::iterator it = times->begin();
- it != times->end();
- it++ )
- {
- Time * const tp = *it;
- (*tp) = tp->ToInteger (unit);
- }
-
- delete times;
-}
-
-// static
-void
-Time::Track (Time * const time)
-{
- NS_ASSERT (time != 0);
-
- TimesSet * times = GetTimesSet();
- if (times != 0)
- {
- std::pair< TimesSet::iterator, bool> ret;
- ret = times->insert ( time);
- }
-}
-
-// static
-void
-Time::UnTrack (Time * const time)
-{
- NS_ASSERT (time != 0);
- TimesSet * times = GetTimesSet ();
- if (times != 0)
- {
- NS_ASSERT_MSG (times->count (time) == 1,
- "Time object " << time << " registered "
- << times->count (time) << " times (should be 1)." );
-
- times->erase (time);
- }
-}
std::ostream&
operator<< (std::ostream& os, const Time & time)
{
+ NS_LOG_FUNCTION (&os << time);
std::string unit;
switch (Time::GetResolution ())
{
@@ -270,6 +180,7 @@
}
std::istream& operator>> (std::istream& is, Time & time)
{
+ NS_LOG_FUNCTION (&is << time);
std::string value;
is >> value;
time = Time (value);
--- a/src/core/test/time-test-suite.cc Sat Dec 15 11:32:58 2012 -0800
+++ b/src/core/test/time-test-suite.cc Sat Dec 15 23:02:03 2012 -0800
@@ -27,26 +27,31 @@
class TimeSimpleTestCase : public TestCase
{
public:
- TimeSimpleTestCase ();
+ TimeSimpleTestCase (enum Time::Unit resolution);
private:
virtual void DoSetup (void);
virtual void DoRun (void);
virtual void DoTeardown (void);
+ enum Time::Unit m_originalResolution;
+ enum Time::Unit m_resolution;
};
-TimeSimpleTestCase::TimeSimpleTestCase ()
- : TestCase ("Sanity check of common time operations")
+TimeSimpleTestCase::TimeSimpleTestCase (enum Time::Unit resolution)
+ : TestCase ("Sanity check of common time operations"),
+ m_resolution (resolution)
{
}
void
TimeSimpleTestCase::DoSetup (void)
{
+ m_originalResolution = Time::GetResolution ();
}
void
TimeSimpleTestCase::DoRun (void)
{
+ Time::SetResolution (m_resolution);
NS_TEST_ASSERT_MSG_EQ_TOL (Seconds (1.0).GetSeconds (), 1.0, TimeStep (1).GetSeconds (),
"is 1 really 1 ?");
NS_TEST_ASSERT_MSG_EQ_TOL (Seconds (10.0).GetSeconds (), 10.0, TimeStep (1).GetSeconds (),
@@ -65,18 +70,12 @@
NS_TEST_ASSERT_MSG_EQ (FemtoSeconds (1).GetFemtoSeconds (), 1,
"is 1fs really 1fs ?");
#endif
-
- Time ten = NanoSeconds (10);
- int64_t tenValue = ten.GetInteger ();
- Time::SetResolution (Time::PS);
- int64_t tenKValue = ten.GetInteger ();
- NS_TEST_ASSERT_MSG_EQ (tenValue * 1000, tenKValue,
- "change resolution to PS");
}
void
TimeSimpleTestCase::DoTeardown (void)
{
+ Time::SetResolution (m_originalResolution);
}
class TimesWithSignsTestCase : public TestCase
@@ -140,7 +139,7 @@
TimeTestSuite ()
: TestSuite ("time", UNIT)
{
- AddTestCase (new TimeSimpleTestCase ());
+ AddTestCase (new TimeSimpleTestCase (Time::US));
AddTestCase (new TimesWithSignsTestCase ());
}
} g_timeTestSuite;