coding style

This commit is contained in:
Mathieu Lacage
2010-04-08 13:39:07 +02:00
parent 4218e9690e
commit 3ccf6c8ee7
22 changed files with 1496 additions and 1183 deletions

View File

@@ -32,13 +32,13 @@ NS_LOG_COMPONENT_DEFINE ("CalendarScheduler");
NS_OBJECT_ENSURE_REGISTERED (CalendarScheduler);
TypeId
TypeId
CalendarScheduler::GetTypeId (void)
{
static TypeId tid = TypeId ("ns3::CalendarScheduler")
.SetParent<Scheduler> ()
.AddConstructor<CalendarScheduler> ()
;
;
return tid;
}
@@ -55,7 +55,7 @@ CalendarScheduler::~CalendarScheduler ()
m_buckets = 0;
}
void
CalendarScheduler::Init (uint32_t nBuckets,
CalendarScheduler::Init (uint32_t nBuckets,
uint64_t width,
uint64_t startPrio)
{
@@ -70,7 +70,7 @@ CalendarScheduler::Init (uint32_t nBuckets,
void
CalendarScheduler::PrintInfo (void)
{
std::cout << "nBuckets=" << m_nBuckets << ", width=" << m_width<< std::endl;
std::cout << "nBuckets=" << m_nBuckets << ", width=" << m_width << std::endl;
std::cout << "Bucket Distribution ";
for (uint32_t i = 0; i < m_nBuckets; i++)
{
@@ -95,7 +95,7 @@ CalendarScheduler::DoInsert (const Event &ev)
// insert in bucket list.
Bucket::iterator end = m_buckets[bucket].end ();
for (Bucket::iterator i = m_buckets[bucket].begin (); i != end; ++i)
for (Bucket::iterator i = m_buckets[bucket].begin (); i != end; ++i)
{
if (ev.key < i->key)
{
@@ -113,7 +113,7 @@ CalendarScheduler::Insert (const Event &ev)
m_qSize++;
ResizeUp ();
}
bool
bool
CalendarScheduler::IsEmpty (void) const
{
return m_qSize == 0;
@@ -126,23 +126,25 @@ CalendarScheduler::PeekNext (void) const
uint32_t i = m_lastBucket;
uint64_t bucketTop = m_bucketTop;
Scheduler::Event minEvent = {0, {~0, ~0}};
do {
if (!m_buckets[i].empty ())
{
Scheduler::Event next = m_buckets[i].front ();
if (next.key.m_ts < bucketTop)
{
return next;
}
if (next.key < minEvent.key)
{
minEvent = next;
}
}
i++;
i %= m_nBuckets;
bucketTop += m_width;
} while (i != m_lastBucket);
do
{
if (!m_buckets[i].empty ())
{
Scheduler::Event next = m_buckets[i].front ();
if (next.key.m_ts < bucketTop)
{
return next;
}
if (next.key < minEvent.key)
{
minEvent = next;
}
}
i++;
i %= m_nBuckets;
bucketTop += m_width;
}
while (i != m_lastBucket);
return minEvent;
}
@@ -153,27 +155,29 @@ CalendarScheduler::DoRemoveNext (void)
uint32_t i = m_lastBucket;
uint64_t bucketTop = m_bucketTop;
Scheduler::Event minEvent = {0, {~0, ~0}};
do {
if (!m_buckets[i].empty ())
{
Scheduler::Event next = m_buckets[i].front ();
if (next.key.m_ts < bucketTop)
{
m_lastBucket = i;
m_lastPrio = next.key.m_ts;
m_bucketTop = bucketTop;
m_buckets[i].pop_front ();
return next;
}
if (next.key < minEvent.key)
{
minEvent = next;
}
}
i++;
i %= m_nBuckets;
bucketTop += m_width;
} while (i != m_lastBucket);
do
{
if (!m_buckets[i].empty ())
{
Scheduler::Event next = m_buckets[i].front ();
if (next.key.m_ts < bucketTop)
{
m_lastBucket = i;
m_lastPrio = next.key.m_ts;
m_bucketTop = bucketTop;
m_buckets[i].pop_front ();
return next;
}
if (next.key < minEvent.key)
{
minEvent = next;
}
}
i++;
i %= m_nBuckets;
bucketTop += m_width;
}
while (i != m_lastBucket);
m_lastPrio = minEvent.key.m_ts;
m_lastBucket = Hash (minEvent.key.m_ts);
@@ -190,8 +194,8 @@ CalendarScheduler::RemoveNext (void)
NS_ASSERT (!IsEmpty ());
Scheduler::Event ev = DoRemoveNext ();
NS_LOG_LOGIC ("remove ts=" << ev.key.m_ts <<
", key=" << ev.key.m_uid <<
NS_LOG_LOGIC ("remove ts=" << ev.key.m_ts <<
", key=" << ev.key.m_uid <<
", from bucket=" << m_lastBucket);
m_qSize--;
ResizeDown ();
@@ -221,16 +225,16 @@ CalendarScheduler::Remove (const Event &ev)
NS_ASSERT (false);
}
void
void
CalendarScheduler::ResizeUp (void)
{
if (m_qSize > m_nBuckets * 2 &&
m_nBuckets < 32768)
if (m_qSize > m_nBuckets * 2
&& m_nBuckets < 32768)
{
Resize (m_nBuckets * 2);
}
}
void
void
CalendarScheduler::ResizeDown (void)
{
if (m_qSize < m_nBuckets / 2)
@@ -242,7 +246,7 @@ CalendarScheduler::ResizeDown (void)
uint32_t
CalendarScheduler::CalculateNewWidth (void)
{
if (m_qSize < 2)
if (m_qSize < 2)
{
return 1;
}
@@ -266,14 +270,14 @@ CalendarScheduler::CalculateNewWidth (void)
uint32_t lastBucket = m_lastBucket;
uint64_t bucketTop = m_bucketTop;
uint64_t lastPrio = m_lastPrio;
// gather requested events
for (uint32_t i = 0; i < nSamples; i++)
{
samples.push_back (DoRemoveNext ());
}
// put them back
for (std::list<Scheduler::Event>::const_iterator i = samples.begin ();
for (std::list<Scheduler::Event>::const_iterator i = samples.begin ();
i != samples.end (); ++i)
{
DoInsert (*i);
@@ -326,20 +330,20 @@ CalendarScheduler::DoResize (uint32_t newSize, uint32_t newWidth)
for (uint32_t i = 0; i < oldNBuckets; i++)
{
Bucket::iterator end = oldBuckets[i].end ();
for (Bucket::iterator j = oldBuckets[i].begin (); j != end; ++j)
for (Bucket::iterator j = oldBuckets[i].begin (); j != end; ++j)
{
DoInsert (*j);
}
}
delete [] oldBuckets;
}
void
void
CalendarScheduler::Resize (uint32_t newSize)
{
NS_LOG_FUNCTION (this << newSize);
//PrintInfo ();
uint32_t newWidth = CalculateNewWidth ();
// PrintInfo ();
uint32_t newWidth = CalculateNewWidth ();
DoResize (newSize, newWidth);
}

View File

@@ -44,7 +44,7 @@ class EventImpl;
* slightly tweak the resizing heuristics to obtain a better distribution of events
* across buckets.
*/
class CalendarScheduler : public Scheduler
class CalendarScheduler : public Scheduler
{
public:
static TypeId GetTypeId (void);
@@ -63,7 +63,7 @@ private:
void ResizeDown (void);
void Resize (uint32_t newSize);
uint32_t CalculateNewWidth (void);
void Init (uint32_t nBuckets,
void Init (uint32_t nBuckets,
uint64_t width,
uint64_t startPrio);
inline uint32_t Hash (uint64_t key) const;

View File

@@ -31,13 +31,13 @@ namespace ns3 {
NS_OBJECT_ENSURE_REGISTERED (HeapScheduler);
TypeId
TypeId
HeapScheduler::GetTypeId (void)
{
static TypeId tid = TypeId ("ns3::HeapScheduler")
.SetParent<Scheduler> ()
.AddConstructor<HeapScheduler> ()
;
;
return tid;
}
@@ -51,24 +51,25 @@ HeapScheduler::HeapScheduler ()
}
HeapScheduler::~HeapScheduler ()
{}
{
}
uint32_t
uint32_t
HeapScheduler::Parent (uint32_t id) const
{
return id / 2;
}
uint32_t
uint32_t
HeapScheduler::Sibling (uint32_t id) const
{
return id + 1;
}
uint32_t
uint32_t
HeapScheduler::LeftChild (uint32_t id) const
{
return id * 2;
}
uint32_t
uint32_t
HeapScheduler::RightChild (uint32_t id) const
{
return id * 2 + 1;
@@ -83,7 +84,7 @@ HeapScheduler::Root (void) const
bool
HeapScheduler::IsRoot (uint32_t id) const
{
return (id == Root ())?true:false;
return (id == Root ()) ? true : false;
}
uint32_t
@@ -96,11 +97,11 @@ HeapScheduler::Last (void) const
bool
HeapScheduler::IsBottom (uint32_t id) const
{
return (id >= m_heap.size ())?true:false;
return (id >= m_heap.size ()) ? true : false;
}
void
HeapScheduler::Exch (uint32_t a, uint32_t b)
HeapScheduler::Exch (uint32_t a, uint32_t b)
{
NS_ASSERT (b < m_heap.size () && a < m_heap.size ());
NS_LOG_DEBUG ("Exch " << a << ", " << b);
@@ -115,27 +116,27 @@ HeapScheduler::IsLessStrictly (uint32_t a, uint32_t b) const
return m_heap[a] < m_heap[b];
}
uint32_t
uint32_t
HeapScheduler::Smallest (uint32_t a, uint32_t b) const
{
return IsLessStrictly (a,b)?a:b;
return IsLessStrictly (a,b) ? a : b;
}
bool
HeapScheduler::IsEmpty (void) const
{
return (m_heap.size () == 1)?true:false;
return (m_heap.size () == 1) ? true : false;
}
void
HeapScheduler::BottomUp (void)
{
uint32_t index = Last ();
while (!IsRoot (index) &&
IsLessStrictly (index, Parent (index)))
{
Exch(index, Parent (index));
index = Parent (index);
while (!IsRoot (index)
&& IsLessStrictly (index, Parent (index)))
{
Exch (index, Parent (index));
index = Parent (index);
}
}
@@ -144,11 +145,11 @@ HeapScheduler::TopDown (uint32_t start)
{
uint32_t index = start;
uint32_t right = RightChild (index);
while (!IsBottom (right))
while (!IsBottom (right))
{
uint32_t left = LeftChild (index);
uint32_t tmp = Smallest (left, right);
if (IsLessStrictly (index, tmp))
if (IsLessStrictly (index, tmp))
{
return;
}
@@ -156,17 +157,17 @@ HeapScheduler::TopDown (uint32_t start)
index = tmp;
right = RightChild (index);
}
if (IsBottom (index))
if (IsBottom (index))
{
return;
}
NS_ASSERT (!IsBottom (index));
uint32_t left = LeftChild (index);
if (IsBottom (left))
if (IsBottom (left))
{
return;
}
if (IsLessStrictly (index, left))
if (IsLessStrictly (index, left))
{
return;
}

View File

@@ -30,9 +30,9 @@ namespace ns3 {
/**
* \ingroup scheduler
* \brief a binary heap event scheduler
*
*
* This code started as a c++ translation of a java-based code written in 2005
* to implement a heap sort. So, this binary heap is really a pretty
* to implement a heap sort. So, this binary heap is really a pretty
* straightforward implementation of the classic data structure. Not much to say
* about it.
*
@@ -44,7 +44,7 @@ namespace ns3 {
* - It uses a slightly non-standard while loop for top-down heapify
* to move one if statement out of the loop.
*/
class HeapScheduler : public Scheduler
class HeapScheduler : public Scheduler
{
public:
static TypeId GetTypeId (void);

View File

@@ -32,19 +32,19 @@
* This code is a bit ugly with a lot of inline methods for speed:
* profiling this code on anything but the simplest scenarios shows
* that it is a big bottleneck if great care in its implementation
* is not performed. My observations are that what dominates are
* is not performed. My observations are that what dominates are
* Division operations (there are really really super costly)
* and Comparison operations (because there are typically a lot of
* these in any complex timekeeping code).
*
* So, the code tries really hard to perform any of these 128 bit
* So, the code tries really hard to perform any of these 128 bit
* operations by doing all arithmetic on 64 bit integers when possible
* (i.e., when there is no fractional part. This is a very common case).
* Hence, the following code has a m_fastValue (64 bits) and a
* Hence, the following code has a m_fastValue (64 bits) and a
* m_slowValue (128 bits). m_fastValue is used by default and the code
* converts it to a m_slowValue when needed.
*
* If you want to monitor the efficiency of this strategy, you can
* If you want to monitor the efficiency of this strategy, you can
* enable the macro HP128INC below and call the HighPrecision::PrintStats
* method at the end of the simulation.
*
@@ -80,7 +80,7 @@
namespace ns3 {
class HighPrecision
class HighPrecision
{
public:
inline HighPrecision ();
@@ -88,7 +88,7 @@ public:
HighPrecision (double value);
static void PrintStats (void);
inline int64_t GetInteger (void) const;
inline double GetDouble (void) const;
inline bool Add (HighPrecision const &o);
@@ -105,7 +105,7 @@ private:
bool SlowSub (HighPrecision const &o);
bool SlowMul (HighPrecision const &o);
int SlowCompare (HighPrecision const &o) const;
cairo_uint128_t Mul128(cairo_uint128_t , cairo_uint128_t );
cairo_uint128_t Mul128 (cairo_uint128_t, cairo_uint128_t );
cairo_int128_t Div128 (cairo_int128_t sa, cairo_int128_t sb);
inline void EnsureSlow (void);
@@ -137,15 +137,17 @@ namespace ns3 {
HighPrecision::HighPrecision ()
: m_isFast (true),
m_fastValue (0)
{}
{
}
HighPrecision::HighPrecision (int64_t value, bool dummy)
: m_isFast (true),
m_fastValue (value)
{}
{
}
int64_t
int64_t
HighPrecision::GetInteger (void) const
{
if (m_isFast)
@@ -173,7 +175,7 @@ double HighPrecision::GetDouble (void) const
return SlowGetDouble ();
}
}
bool
bool
HighPrecision::Add (HighPrecision const &o)
{
if (m_isFast && o.m_isFast)
@@ -188,7 +190,7 @@ HighPrecision::Add (HighPrecision const &o)
return SlowAdd (o);
}
}
bool
bool
HighPrecision::Sub (HighPrecision const &o)
{
if (m_isFast && o.m_isFast)
@@ -203,7 +205,7 @@ HighPrecision::Sub (HighPrecision const &o)
return SlowSub (o);
}
}
bool
bool
HighPrecision::Mul (HighPrecision const &o)
{
if (m_isFast && o.m_isFast)
@@ -219,7 +221,7 @@ HighPrecision::Mul (HighPrecision const &o)
}
}
int
int
HighPrecision::Compare (HighPrecision const &o) const
{
if (m_isFast && o.m_isFast)
@@ -245,9 +247,9 @@ HighPrecision::Compare (HighPrecision const &o) const
}
// The below statement is unreachable but necessary for optimized
// builds with gcc-4.0.x due to a compiler bug.
return 0;
return 0;
}
HighPrecision
HighPrecision
HighPrecision::Zero (void)
{
return HighPrecision ();

View File

@@ -27,15 +27,18 @@ namespace ns3 {
HighPrecision::HighPrecision ()
: m_value (0.0)
{}
{
}
HighPrecision::HighPrecision (int64_t value, bool dummy)
: m_value ((double)value)
{}
{
}
HighPrecision::HighPrecision (double value)
: m_value (value)
{}
{
}
int64_t
HighPrecision::GetInteger (void) const
@@ -43,41 +46,41 @@ HighPrecision::GetInteger (void) const
return (int64_t)floor (m_value);
}
double
double
HighPrecision::GetDouble (void) const
{
return m_value;
}
bool
bool
HighPrecision::Add (HighPrecision const &o)
{
m_value += o.m_value;
return false;
}
bool
bool
HighPrecision::Sub (HighPrecision const &o)
{
m_value -= o.m_value;
return false;
}
bool
bool
HighPrecision::Mul (HighPrecision const &o)
{
m_value *= o.m_value;
return false;
}
bool
bool
HighPrecision::Div (HighPrecision const &o)
{
m_value /= o.m_value;
return false;
}
int
int
HighPrecision::Compare (HighPrecision const &o) const
{
return 0;
}
HighPrecision
HighPrecision
HighPrecision::Zero (void)
{
return HighPrecision (0,0);

View File

@@ -31,13 +31,13 @@ namespace ns3 {
* So, it is a nice shortcut but in no way a complete solution.
*/
class HighPrecision
class HighPrecision
{
public:
HighPrecision ();
HighPrecision (int64_t value, bool dummy);
HighPrecision (double value);
int64_t GetInteger (void) const;
double GetDouble (void) const;
bool Add (HighPrecision const &o);

View File

@@ -29,25 +29,27 @@ namespace ns3 {
NS_OBJECT_ENSURE_REGISTERED (ListScheduler);
TypeId
TypeId
ListScheduler::GetTypeId (void)
{
static TypeId tid = TypeId ("ns3::ListScheduler")
.SetParent<Scheduler> ()
.AddConstructor<ListScheduler> ()
;
;
return tid;
}
ListScheduler::ListScheduler ()
{}
{
}
ListScheduler::~ListScheduler ()
{}
{
}
void
ListScheduler::Insert (const Event &ev)
{
for (EventsI i = m_events.begin (); i != m_events.end (); i++)
for (EventsI i = m_events.begin (); i != m_events.end (); i++)
{
if (ev.key < i->key)
{
@@ -57,7 +59,7 @@ ListScheduler::Insert (const Event &ev)
}
m_events.push_back (ev);
}
bool
bool
ListScheduler::IsEmpty (void) const
{
return m_events.empty ();
@@ -79,7 +81,7 @@ ListScheduler::RemoveNext (void)
void
ListScheduler::Remove (const Event &ev)
{
for (EventsI i = m_events.begin (); i != m_events.end (); i++)
for (EventsI i = m_events.begin (); i != m_events.end (); i++)
{
if (i->key.m_uid == ev.key.m_uid)
{

View File

@@ -37,9 +37,9 @@ class EventImpl;
* This class implements an event scheduler using an std::list
* data structure, that is, a double linked-list.
*/
class ListScheduler : public Scheduler
class ListScheduler : public Scheduler
{
public:
public:
static TypeId GetTypeId (void);
ListScheduler ();
@@ -51,8 +51,7 @@ class ListScheduler : public Scheduler
virtual Event RemoveNext (void);
virtual void Remove (const Event &ev);
private:
private:
typedef std::list<Event> Events;
typedef std::list<Event>::iterator EventsI;
Events m_events;

View File

@@ -2,24 +2,28 @@
namespace ns3 {
EventImpl *MakeEvent (void (*f) (void))
EventImpl * MakeEvent (void (*f)(void))
{
// zero arg version
class EventFunctionImpl0 : public EventImpl
{
public:
public:
typedef void (*F)(void);
EventFunctionImpl0 (F function)
EventFunctionImpl0 (F function)
: m_function (function)
{}
virtual ~EventFunctionImpl0 () {}
protected:
virtual void Notify (void) {
(*m_function) ();
{
}
private:
F m_function;
virtual ~EventFunctionImpl0 ()
{
}
protected:
virtual void Notify (void)
{
(*m_function)();
}
private:
F m_function;
} *ev = new EventFunctionImpl0 (f);
return ev;
}

View File

@@ -6,49 +6,49 @@ namespace ns3 {
class EventImpl;
template <typename MEM, typename OBJ>
EventImpl *MakeEvent (MEM mem_ptr, OBJ obj);
EventImpl * MakeEvent (MEM mem_ptr, OBJ obj);
template <typename MEM, typename OBJ,
template <typename MEM, typename OBJ,
typename T1>
EventImpl *MakeEvent (MEM mem_ptr, OBJ obj, T1 a1);
EventImpl * MakeEvent (MEM mem_ptr, OBJ obj, T1 a1);
template <typename MEM, typename OBJ,
template <typename MEM, typename OBJ,
typename T1, typename T2>
EventImpl * MakeEvent (MEM mem_ptr, OBJ obj, T1 a1, T2 a2);
template <typename MEM, typename OBJ,
template <typename MEM, typename OBJ,
typename T1, typename T2, typename T3>
EventImpl * MakeEvent (MEM mem_ptr, OBJ obj, T1 a1, T2 a2, T3 a3);
template <typename MEM, typename OBJ,
template <typename MEM, typename OBJ,
typename T1, typename T2, typename T3, typename T4>
EventImpl * MakeEvent (MEM mem_ptr, OBJ obj, T1 a1, T2 a2, T3 a3, T4 a4);
template <typename MEM, typename OBJ,
template <typename MEM, typename OBJ,
typename T1, typename T2, typename T3, typename T4, typename T5>
EventImpl * MakeEvent (MEM mem_ptr, OBJ obj,
T1 a1, T2 a2, T3 a3, T4 a4, T5 a5);
EventImpl * MakeEvent (MEM mem_ptr, OBJ obj,
T1 a1, T2 a2, T3 a3, T4 a4, T5 a5);
EventImpl * MakeEvent (void (*f) (void));
template <typename U1,
EventImpl * MakeEvent (void (*f)(void));
template <typename U1,
typename T1>
EventImpl * MakeEvent (void (*f) (U1), T1 a1);
EventImpl * MakeEvent (void (*f)(U1), T1 a1);
template <typename U1, typename U2,
template <typename U1, typename U2,
typename T1, typename T2>
EventImpl * MakeEvent (void (*f) (U1,U2), T1 a1, T2 a2);
EventImpl * MakeEvent (void (*f)(U1,U2), T1 a1, T2 a2);
template <typename U1, typename U2, typename U3,
typename T1, typename T2, typename T3>
EventImpl * MakeEvent (void (*f) (U1,U2,U3), T1 a1, T2 a2, T3 a3);
EventImpl * MakeEvent (void (*f)(U1,U2,U3), T1 a1, T2 a2, T3 a3);
template <typename U1, typename U2, typename U3, typename U4,
typename T1, typename T2, typename T3, typename T4>
EventImpl * MakeEvent (void (*f) (U1,U2,U3,U4), T1 a1, T2 a2, T3 a3, T4 a4);
EventImpl * MakeEvent (void (*f)(U1,U2,U3,U4), T1 a1, T2 a2, T3 a3, T4 a4);
template <typename U1, typename U2, typename U3, typename U4, typename U5,
typename T1, typename T2, typename T3, typename T4, typename T5>
EventImpl * MakeEvent (void (*f) (U1,U2,U3,U4,U5), T1 a1, T2 a2, T3 a3, T4 a4, T5 a5);
EventImpl * MakeEvent (void (*f)(U1,U2,U3,U4,U5), T1 a1, T2 a2, T3 a3, T4 a4, T5 a5);
} // namespace ns3
@@ -67,50 +67,61 @@ struct EventMemberImplObjTraits;
template <typename T>
struct EventMemberImplObjTraits<T *>
{
static T &GetReference (T *p) {
static T &GetReference (T *p)
{
return *p;
}
};
template <typename MEM, typename OBJ>
EventImpl * MakeEvent (MEM mem_ptr, OBJ obj)
EventImpl * MakeEvent (MEM mem_ptr, OBJ obj)
{
// zero argument version
class EventMemberImpl0 : public EventImpl {
public:
EventMemberImpl0 (OBJ obj, MEM function)
: m_obj (obj),
class EventMemberImpl0 : public EventImpl
{
public:
EventMemberImpl0 (OBJ obj, MEM function)
: m_obj (obj),
m_function (function)
{}
virtual ~EventMemberImpl0 () {}
private:
virtual void Notify (void) {
(EventMemberImplObjTraits<OBJ>::GetReference (m_obj).*m_function) ();
{
}
virtual ~EventMemberImpl0 ()
{
}
private:
virtual void Notify (void)
{
(EventMemberImplObjTraits<OBJ>::GetReference (m_obj).*m_function)();
}
OBJ m_obj;
MEM m_function;
} * ev = new EventMemberImpl0 (obj, mem_ptr);
} *ev = new EventMemberImpl0 (obj, mem_ptr);
return ev;
}
template <typename MEM, typename OBJ,
template <typename MEM, typename OBJ,
typename T1>
EventImpl * MakeEvent (MEM mem_ptr, OBJ obj, T1 a1)
{
// one argument version
class EventMemberImpl1 : public EventImpl {
public:
EventMemberImpl1 (OBJ obj, MEM function, T1 a1)
: m_obj (obj),
class EventMemberImpl1 : public EventImpl
{
public:
EventMemberImpl1 (OBJ obj, MEM function, T1 a1)
: m_obj (obj),
m_function (function),
m_a1 (a1)
{}
protected:
virtual ~EventMemberImpl1 () {}
private:
virtual void Notify (void) {
(EventMemberImplObjTraits<OBJ>::GetReference (m_obj).*m_function) (m_a1);
{
}
protected:
virtual ~EventMemberImpl1 ()
{
}
private:
virtual void Notify (void)
{
(EventMemberImplObjTraits<OBJ>::GetReference (m_obj).*m_function)(m_a1);
}
OBJ m_obj;
MEM m_function;
@@ -119,24 +130,29 @@ EventImpl * MakeEvent (MEM mem_ptr, OBJ obj, T1 a1)
return ev;
}
template <typename MEM, typename OBJ,
template <typename MEM, typename OBJ,
typename T1, typename T2>
EventImpl * MakeEvent (MEM mem_ptr, OBJ obj, T1 a1, T2 a2)
EventImpl * MakeEvent (MEM mem_ptr, OBJ obj, T1 a1, T2 a2)
{
// two argument version
class EventMemberImpl2 : public EventImpl {
public:
EventMemberImpl2 (OBJ obj, MEM function, T1 a1, T2 a2)
: m_obj (obj),
class EventMemberImpl2 : public EventImpl
{
public:
EventMemberImpl2 (OBJ obj, MEM function, T1 a1, T2 a2)
: m_obj (obj),
m_function (function),
m_a1 (a1),
m_a2 (a2)
{ }
protected:
virtual ~EventMemberImpl2 () {}
private:
virtual void Notify (void) {
(EventMemberImplObjTraits<OBJ>::GetReference (m_obj).*m_function) (m_a1, m_a2);
{
}
protected:
virtual ~EventMemberImpl2 ()
{
}
private:
virtual void Notify (void)
{
(EventMemberImplObjTraits<OBJ>::GetReference (m_obj).*m_function)(m_a1, m_a2);
}
OBJ m_obj;
MEM m_function;
@@ -146,25 +162,30 @@ EventImpl * MakeEvent (MEM mem_ptr, OBJ obj, T1 a1, T2 a2)
return ev;
}
template <typename MEM, typename OBJ,
template <typename MEM, typename OBJ,
typename T1, typename T2, typename T3>
EventImpl * MakeEvent (MEM mem_ptr, OBJ obj, T1 a1, T2 a2, T3 a3)
EventImpl * MakeEvent (MEM mem_ptr, OBJ obj, T1 a1, T2 a2, T3 a3)
{
// three argument version
class EventMemberImpl3 : public EventImpl {
public:
EventMemberImpl3 (OBJ obj, MEM function, T1 a1, T2 a2, T3 a3)
: m_obj (obj),
class EventMemberImpl3 : public EventImpl
{
public:
EventMemberImpl3 (OBJ obj, MEM function, T1 a1, T2 a2, T3 a3)
: m_obj (obj),
m_function (function),
m_a1 (a1),
m_a2 (a2),
m_a3 (a3)
{ }
protected:
virtual ~EventMemberImpl3 () {}
private:
virtual void Notify (void) {
(EventMemberImplObjTraits<OBJ>::GetReference (m_obj).*m_function) (m_a1, m_a2, m_a3);
{
}
protected:
virtual ~EventMemberImpl3 ()
{
}
private:
virtual void Notify (void)
{
(EventMemberImplObjTraits<OBJ>::GetReference (m_obj).*m_function)(m_a1, m_a2, m_a3);
}
OBJ m_obj;
MEM m_function;
@@ -175,26 +196,31 @@ EventImpl * MakeEvent (MEM mem_ptr, OBJ obj, T1 a1, T2 a2, T3 a3)
return ev;
}
template <typename MEM, typename OBJ,
template <typename MEM, typename OBJ,
typename T1, typename T2, typename T3, typename T4>
EventImpl * MakeEvent (MEM mem_ptr, OBJ obj, T1 a1, T2 a2, T3 a3, T4 a4)
EventImpl * MakeEvent (MEM mem_ptr, OBJ obj, T1 a1, T2 a2, T3 a3, T4 a4)
{
// four argument version
class EventMemberImpl4 : public EventImpl {
public:
EventMemberImpl4 (OBJ obj, MEM function, T1 a1, T2 a2, T3 a3, T4 a4)
: m_obj (obj),
class EventMemberImpl4 : public EventImpl
{
public:
EventMemberImpl4 (OBJ obj, MEM function, T1 a1, T2 a2, T3 a3, T4 a4)
: m_obj (obj),
m_function (function),
m_a1 (a1),
m_a2 (a2),
m_a3 (a3),
m_a4 (a4)
{ }
protected:
virtual ~EventMemberImpl4 () {}
private:
virtual void Notify (void) {
(EventMemberImplObjTraits<OBJ>::GetReference (m_obj).*m_function) (m_a1, m_a2, m_a3, m_a4);
{
}
protected:
virtual ~EventMemberImpl4 ()
{
}
private:
virtual void Notify (void)
{
(EventMemberImplObjTraits<OBJ>::GetReference (m_obj).*m_function)(m_a1, m_a2, m_a3, m_a4);
}
OBJ m_obj;
MEM m_function;
@@ -206,28 +232,33 @@ EventImpl * MakeEvent (MEM mem_ptr, OBJ obj, T1 a1, T2 a2, T3 a3, T4 a4)
return ev;
}
template <typename MEM, typename OBJ,
template <typename MEM, typename OBJ,
typename T1, typename T2, typename T3, typename T4, typename T5>
EventImpl * MakeEvent (MEM mem_ptr, OBJ obj,
T1 a1, T2 a2, T3 a3, T4 a4, T5 a5)
EventImpl * MakeEvent (MEM mem_ptr, OBJ obj,
T1 a1, T2 a2, T3 a3, T4 a4, T5 a5)
{
// five argument version
class EventMemberImpl5 : public EventImpl {
public:
EventMemberImpl5 (OBJ obj, MEM function, T1 a1, T2 a2, T3 a3, T4 a4, T5 a5)
: m_obj (obj),
class EventMemberImpl5 : public EventImpl
{
public:
EventMemberImpl5 (OBJ obj, MEM function, T1 a1, T2 a2, T3 a3, T4 a4, T5 a5)
: m_obj (obj),
m_function (function),
m_a1 (a1),
m_a2 (a2),
m_a3 (a3),
m_a4 (a4),
m_a5 (a5)
{ }
protected:
virtual ~EventMemberImpl5 () {}
private:
virtual void Notify (void) {
(EventMemberImplObjTraits<OBJ>::GetReference (m_obj).*m_function) (m_a1, m_a2, m_a3, m_a4, m_a5);
{
}
protected:
virtual ~EventMemberImpl5 ()
{
}
private:
virtual void Notify (void)
{
(EventMemberImplObjTraits<OBJ>::GetReference (m_obj).*m_function)(m_a1, m_a2, m_a3, m_a4, m_a5);
}
OBJ m_obj;
MEM m_function;
@@ -241,22 +272,27 @@ EventImpl * MakeEvent (MEM mem_ptr, OBJ obj,
}
template <typename U1, typename T1>
EventImpl * MakeEvent (void (*f) (U1), T1 a1)
EventImpl * MakeEvent (void (*f)(U1), T1 a1)
{
// one arg version
class EventFunctionImpl1 : public EventImpl {
public:
class EventFunctionImpl1 : public EventImpl
{
public:
typedef void (*F)(U1);
EventFunctionImpl1 (F function, T1 a1)
EventFunctionImpl1 (F function, T1 a1)
: m_function (function),
m_a1 (a1)
{ }
protected:
virtual ~EventFunctionImpl1 () {}
private:
virtual void Notify (void) {
(*m_function) (m_a1);
{
}
protected:
virtual ~EventFunctionImpl1 ()
{
}
private:
virtual void Notify (void)
{
(*m_function)(m_a1);
}
F m_function;
typename TypeTraits<T1>::ReferencedType m_a1;
@@ -265,23 +301,28 @@ EventImpl * MakeEvent (void (*f) (U1), T1 a1)
}
template <typename U1, typename U2, typename T1, typename T2>
EventImpl * MakeEvent (void (*f) (U1,U2), T1 a1, T2 a2)
EventImpl * MakeEvent (void (*f)(U1,U2), T1 a1, T2 a2)
{
// two arg version
class EventFunctionImpl2 : public EventImpl {
public:
class EventFunctionImpl2 : public EventImpl
{
public:
typedef void (*F)(U1, U2);
EventFunctionImpl2 (F function, T1 a1, T2 a2)
EventFunctionImpl2 (F function, T1 a1, T2 a2)
: m_function (function),
m_a1 (a1),
m_a2 (a2)
{}
protected:
virtual ~EventFunctionImpl2 () {}
private:
virtual void Notify (void) {
(*m_function) (m_a1, m_a2);
{
}
protected:
virtual ~EventFunctionImpl2 ()
{
}
private:
virtual void Notify (void)
{
(*m_function)(m_a1, m_a2);
}
F m_function;
typename TypeTraits<T1>::ReferencedType m_a1;
@@ -292,24 +333,29 @@ EventImpl * MakeEvent (void (*f) (U1,U2), T1 a1, T2 a2)
template <typename U1, typename U2, typename U3,
typename T1, typename T2, typename T3>
EventImpl * MakeEvent (void (*f) (U1,U2,U3), T1 a1, T2 a2, T3 a3)
EventImpl * MakeEvent (void (*f)(U1,U2,U3), T1 a1, T2 a2, T3 a3)
{
// three arg version
class EventFunctionImpl3 : public EventImpl {
public:
class EventFunctionImpl3 : public EventImpl
{
public:
typedef void (*F)(U1, U2, U3);
EventFunctionImpl3 (F function, T1 a1, T2 a2, T3 a3)
EventFunctionImpl3 (F function, T1 a1, T2 a2, T3 a3)
: m_function (function),
m_a1 (a1),
m_a2 (a2),
m_a3 (a3)
{ }
protected:
virtual ~EventFunctionImpl3 () {}
private:
virtual void Notify (void) {
(*m_function) (m_a1, m_a2, m_a3);
{
}
protected:
virtual ~EventFunctionImpl3 ()
{
}
private:
virtual void Notify (void)
{
(*m_function)(m_a1, m_a2, m_a3);
}
F m_function;
typename TypeTraits<T1>::ReferencedType m_a1;
@@ -321,25 +367,30 @@ EventImpl * MakeEvent (void (*f) (U1,U2,U3), T1 a1, T2 a2, T3 a3)
template <typename U1, typename U2, typename U3, typename U4,
typename T1, typename T2, typename T3, typename T4>
EventImpl * MakeEvent (void (*f) (U1,U2,U3,U4), T1 a1, T2 a2, T3 a3, T4 a4)
EventImpl * MakeEvent (void (*f)(U1,U2,U3,U4), T1 a1, T2 a2, T3 a3, T4 a4)
{
// four arg version
class EventFunctionImpl4 : public EventImpl {
public:
class EventFunctionImpl4 : public EventImpl
{
public:
typedef void (*F)(U1, U2, U3, U4);
EventFunctionImpl4 (F function, T1 a1, T2 a2, T3 a3, T4 a4)
EventFunctionImpl4 (F function, T1 a1, T2 a2, T3 a3, T4 a4)
: m_function (function),
m_a1 (a1),
m_a2 (a2),
m_a3 (a3),
m_a4 (a4)
{ }
protected:
virtual ~EventFunctionImpl4 () {}
private:
virtual void Notify (void) {
(*m_function) (m_a1, m_a2, m_a3, m_a4);
{
}
protected:
virtual ~EventFunctionImpl4 ()
{
}
private:
virtual void Notify (void)
{
(*m_function)(m_a1, m_a2, m_a3, m_a4);
}
F m_function;
typename TypeTraits<T1>::ReferencedType m_a1;
@@ -352,26 +403,31 @@ EventImpl * MakeEvent (void (*f) (U1,U2,U3,U4), T1 a1, T2 a2, T3 a3, T4 a4)
template <typename U1, typename U2, typename U3, typename U4, typename U5,
typename T1, typename T2, typename T3, typename T4, typename T5>
EventImpl * MakeEvent (void (*f) (U1,U2,U3,U4,U5), T1 a1, T2 a2, T3 a3, T4 a4, T5 a5)
EventImpl * MakeEvent (void (*f)(U1,U2,U3,U4,U5), T1 a1, T2 a2, T3 a3, T4 a4, T5 a5)
{
// five arg version
class EventFunctionImpl5 : public EventImpl {
public:
class EventFunctionImpl5 : public EventImpl
{
public:
typedef void (*F)(U1,U2,U3,U4,U5);
EventFunctionImpl5 (F function, T1 a1, T2 a2, T3 a3, T4 a4, T5 a5)
EventFunctionImpl5 (F function, T1 a1, T2 a2, T3 a3, T4 a4, T5 a5)
: m_function (function),
m_a1 (a1),
m_a2 (a2),
m_a3 (a3),
m_a4 (a4),
m_a5 (a5)
{}
protected:
virtual ~EventFunctionImpl5 () {}
private:
virtual void Notify (void) {
(*m_function) (m_a1, m_a2, m_a3, m_a4, m_a5);
{
}
protected:
virtual ~EventFunctionImpl5 ()
{
}
private:
virtual void Notify (void)
{
(*m_function)(m_a1, m_a2, m_a3, m_a4, m_a5);
}
F m_function;
typename TypeTraits<T1>::ReferencedType m_a1;

View File

@@ -31,20 +31,22 @@ namespace ns3 {
NS_OBJECT_ENSURE_REGISTERED (MapScheduler);
TypeId
TypeId
MapScheduler::GetTypeId (void)
{
static TypeId tid = TypeId ("ns3::MapScheduler")
.SetParent<Scheduler> ()
.AddConstructor<MapScheduler> ()
;
;
return tid;
}
MapScheduler::MapScheduler ()
{}
{
}
MapScheduler::~MapScheduler ()
{}
{
}
void
MapScheduler::Insert (const Event &ev)
@@ -67,7 +69,7 @@ MapScheduler::PeekNext (void) const
NS_LOG_FUNCTION (this);
EventMapCI i = m_list.begin ();
NS_ASSERT (i != m_list.end ());
Event ev;
ev.impl = i->second;
ev.key = i->first;

View File

@@ -32,10 +32,10 @@ namespace ns3 {
* \ingroup scheduler
* \brief a std::map event scheduler
*
* This class implements the an event scheduler using an std::map
* This class implements the an event scheduler using an std::map
* data structure.
*/
class MapScheduler : public Scheduler
class MapScheduler : public Scheduler
{
public:
static TypeId GetTypeId (void);
@@ -49,7 +49,6 @@ public:
virtual Event RemoveNext (void);
virtual void Remove (const Event &ev);
private:
typedef std::map<Scheduler::EventKey, EventImpl*> EventMap;
typedef std::map<Scheduler::EventKey, EventImpl*>::iterator EventMapI;
typedef std::map<Scheduler::EventKey, EventImpl*>::const_iterator EventMapCI;

View File

@@ -34,462 +34,544 @@ NS_OBJECT_ENSURE_REGISTERED (Ns2CalendarScheduler);
#define CALENDAR_HASH(key) ((key.m_ts / width_) % nbuckets_)
TypeId
TypeId
Ns2CalendarScheduler::GetTypeId (void)
{
static TypeId tid = TypeId ("ns3::Ns2CalendarScheduler")
.SetParent<Scheduler> ()
.AddConstructor<Ns2CalendarScheduler> ()
;
return tid;
static TypeId tid = TypeId ("ns3::Ns2CalendarScheduler")
.SetParent<Scheduler> ()
.AddConstructor<Ns2CalendarScheduler> ()
;
return tid;
}
Ns2CalendarScheduler::Ns2CalendarScheduler ()
{
NS_LOG_FUNCTION (this);
NS_LOG_FUNCTION (this);
adjust_new_width_interval_ = 10;
min_bin_width_ = 1;
avg_gap_ = -2;
last_time_ = 0;
gap_num_ = 0;
head_search_ = 0;
insert_search_ = 0;
round_num_ = 0;
time_to_newwidth_ = adjust_new_width_interval_;
cal_clock_ = Scheduler::EventKey ();
reinit(4, 1, cal_clock_);
adjust_new_width_interval_ = 10;
min_bin_width_ = 1;
avg_gap_ = -2;
last_time_ = 0;
gap_num_ = 0;
head_search_ = 0;
insert_search_ = 0;
round_num_ = 0;
time_to_newwidth_ = adjust_new_width_interval_;
cal_clock_ = Scheduler::EventKey ();
reinit (4, 1, cal_clock_);
}
Ns2CalendarScheduler::~Ns2CalendarScheduler ()
{
NS_LOG_FUNCTION (this);
for (int i = 0; i < nbuckets_; i++) {
Bucket *bucket = &buckets_[i];
if (bucket->list_ == 0) {
continue;
}
if (bucket->list_->next_ == bucket->list_) {
delete bucket->list_;
continue;
}
BucketItem *next;
BucketItem *cur;
for (cur = bucket->list_;
cur->next_ != bucket->list_;
cur = next) {
next = cur->next_;
delete cur;
}
delete cur;
}
delete [] buckets_;
qsize_ = 0;
stat_qsize_ = 0;
NS_LOG_FUNCTION (this);
for (int i = 0; i < nbuckets_; i++)
{
Bucket *bucket = &buckets_[i];
if (bucket->list_ == 0)
{
continue;
}
if (bucket->list_->next_ == bucket->list_)
{
delete bucket->list_;
continue;
}
BucketItem *next;
BucketItem *cur;
for (cur = bucket->list_;
cur->next_ != bucket->list_;
cur = next)
{
next = cur->next_;
delete cur;
}
delete cur;
}
delete [] buckets_;
qsize_ = 0;
stat_qsize_ = 0;
}
void
Ns2CalendarScheduler::Insert (const Event &event)
{
NS_LOG_FUNCTION (this);
NS_LOG_FUNCTION (this);
Scheduler::EventKey newtime = event.key;
int i = CALENDAR_HASH(newtime);
Scheduler::EventKey newtime = event.key;
int i = CALENDAR_HASH (newtime);
Bucket* current=(&buckets_[i]);
BucketItem *head = current->list_;
BucketItem *after=0;
BucketItem *e = new BucketItem ();
e->event = event;
Bucket* current = (&buckets_[i]);
BucketItem *head = current->list_;
BucketItem *after = 0;
BucketItem *e = new BucketItem ();
e->event = event;
if (!head) {
current->list_ = e;
e->next_ = e->prev_ = e;
++stat_qsize_;
++(current->count_);
} else {
insert_search_++;
if (newtime < head->event.key) {
// e-> head -> ...
e->next_ = head;
e->prev_ = head->prev_;
e->prev_->next_ = e;
head->prev_ = e;
current->list_ = e;
++stat_qsize_;
++(current->count_);
} else {
for (after = head->prev_; newtime < after->event.key; after = after->prev_)
{ insert_search_++; };
//...-> after -> e -> ...
e->next_ = after->next_;
e->prev_ = after;
e->next_->prev_ = e;
after->next_ = e;
if (after->event.key < newtime) {
//unique timing
++stat_qsize_;
++(current->count_);
}
}
}
++qsize_;
//assert(e == buckets_[i].list_ || e->prev_->time_ <= e->time_);
//assert(e == buckets_[i].list_->prev_ || e->next_->time_ >= e->time_);
if (!head)
{
current->list_ = e;
e->next_ = e->prev_ = e;
++stat_qsize_;
++(current->count_);
}
else
{
insert_search_++;
if (newtime < head->event.key)
{
// e-> head -> ...
e->next_ = head;
e->prev_ = head->prev_;
e->prev_->next_ = e;
head->prev_ = e;
current->list_ = e;
++stat_qsize_;
++(current->count_);
}
else
{
for (after = head->prev_; newtime < after->event.key; after = after->prev_)
{
insert_search_++;
}
// ...-> after -> e -> ...
e->next_ = after->next_;
e->prev_ = after;
e->next_->prev_ = e;
after->next_ = e;
if (after->event.key < newtime)
{
// unique timing
++stat_qsize_;
++(current->count_);
}
}
}
++qsize_;
// assert(e == buckets_[i].list_ || e->prev_->time_ <= e->time_);
// assert(e == buckets_[i].list_->prev_ || e->next_->time_ >= e->time_);
if (stat_qsize_ > top_threshold_) {
resize(nbuckets_ << 1, cal_clock_);
return;
}
if (stat_qsize_ > top_threshold_)
{
resize (nbuckets_ << 1, cal_clock_);
return;
}
}
bool
bool
Ns2CalendarScheduler::IsEmpty (void) const
{
return qsize_ == 0;
return qsize_ == 0;
}
Scheduler::Event
Ns2CalendarScheduler::PeekNext (void) const
{
NS_LOG_FUNCTION (this);
NS_ASSERT (!IsEmpty ());
NS_LOG_FUNCTION (this);
NS_ASSERT (!IsEmpty ());
BucketItem *e = const_cast<Ns2CalendarScheduler *> (this)->head ();
NS_ASSERT (e != 0);
return e->event;
BucketItem *e = const_cast<Ns2CalendarScheduler *> (this)->head ();
NS_ASSERT (e != 0);
return e->event;
}
Scheduler::Event
Ns2CalendarScheduler::RemoveNext (void)
{
NS_LOG_FUNCTION (this);
NS_ASSERT (!IsEmpty ());
NS_LOG_FUNCTION (this);
NS_ASSERT (!IsEmpty ());
BucketItem *e = head ();
NS_ASSERT (e != 0);
BucketItem *e = head ();
NS_ASSERT (e != 0);
if (last_time_ == 0) last_time_ = e->event.key.m_ts;
else
{
gap_num_ ++;
if (gap_num_ >= qsize_ ) {
uint64_t tt_gap_ = e->event.key.m_ts - last_time_;
avg_gap_ = tt_gap_ / gap_num_;
gap_num_ = 0;
last_time_ = e->event.key.m_ts;
round_num_ ++;
if ((round_num_ > 20) &&
(( head_search_> (insert_search_<<1))
||( insert_search_> (head_search_<<1)) ))
{
resize(nbuckets_, cal_clock_);
round_num_ = 0;
} else {
if (round_num_ > 100) {
round_num_ = 0;
head_search_ = 0;
insert_search_ = 0;
}
}
}
}
if (last_time_ == 0)
{
last_time_ = e->event.key.m_ts;
}
else
{
gap_num_++;
if (gap_num_ >= qsize_ )
{
uint64_t tt_gap_ = e->event.key.m_ts - last_time_;
avg_gap_ = tt_gap_ / gap_num_;
gap_num_ = 0;
last_time_ = e->event.key.m_ts;
round_num_++;
if ((round_num_ > 20)
&& (( head_search_ > (insert_search_ << 1))
||( insert_search_ > (head_search_ << 1)) ))
{
resize (nbuckets_, cal_clock_);
round_num_ = 0;
}
else
{
if (round_num_ > 100)
{
round_num_ = 0;
head_search_ = 0;
insert_search_ = 0;
}
}
}
}
int l = lastbucket_;
int l = lastbucket_;
// update stats and unlink
if (e->next_ == e || e->next_->event.key != e->event.key) {
--stat_qsize_;
//assert(stat_qsize_ >= 0);
--buckets_[l].count_;
//assert(buckets_[l].count_ >= 0);
}
--qsize_;
// update stats and unlink
if (e->next_ == e || e->next_->event.key != e->event.key)
{
--stat_qsize_;
// assert(stat_qsize_ >= 0);
--buckets_[l].count_;
// assert(buckets_[l].count_ >= 0);
}
--qsize_;
if (e->next_ == e)
buckets_[l].list_ = 0;
else {
e->next_->prev_ = e->prev_;
e->prev_->next_ = e->next_;
buckets_[l].list_ = e->next_;
}
if (e->next_ == e)
{
buckets_[l].list_ = 0;
}
else
{
e->next_->prev_ = e->prev_;
e->prev_->next_ = e->next_;
buckets_[l].list_ = e->next_;
}
e->next_ = e->prev_ = NULL;
e->next_ = e->prev_ = NULL;
//if (buckets_[l].count_ == 0)
// assert(buckets_[l].list_ == 0);
if (stat_qsize_ < bot_threshold_) {
resize(nbuckets_ >> 1, cal_clock_);
}
// if (buckets_[l].count_ == 0)
// assert(buckets_[l].list_ == 0);
Scheduler::Event event = e->event;
delete e;
return event;
if (stat_qsize_ < bot_threshold_)
{
resize (nbuckets_ >> 1, cal_clock_);
}
Scheduler::Event event = e->event;
delete e;
return event;
}
void
Ns2CalendarScheduler::Remove (const Event &ev)
{
NS_ASSERT (!IsEmpty ());
NS_ASSERT (!IsEmpty ());
int i = CALENDAR_HASH(ev.key);
int i = CALENDAR_HASH (ev.key);
Bucket* current=(&buckets_[i]);
BucketItem *head = current->list_;
BucketItem *e=0;
Bucket* current = (&buckets_[i]);
BucketItem *head = current->list_;
BucketItem *e = 0;
if (!head) {
NS_LOG_DEBUG ("event not in scheduler");
return;
}
for (e = head->prev_; ev.key != e->event.key; e = e->prev_) {}
--stat_qsize_;
--buckets_[i].count_;
if (e->next_ == e) {
assert(buckets_[i].list_ == e);
buckets_[i].list_ = 0;
} else {
e->next_->prev_ = e->prev_;
e->prev_->next_ = e->next_;
if (buckets_[i].list_ == e)
buckets_[i].list_ = e->next_;
}
if (!head)
{
NS_LOG_DEBUG ("event not in scheduler");
return;
}
for (e = head->prev_; ev.key != e->event.key; e = e->prev_)
{
}
--stat_qsize_;
--buckets_[i].count_;
if (e->next_ == e)
{
assert (buckets_[i].list_ == e);
buckets_[i].list_ = 0;
}
else
{
e->next_->prev_ = e->prev_;
e->prev_->next_ = e->next_;
if (buckets_[i].list_ == e)
{
buckets_[i].list_ = e->next_;
}
}
if (buckets_[i].count_ == 0)
assert(buckets_[i].list_ == 0);
if (buckets_[i].count_ == 0)
{
assert (buckets_[i].list_ == 0);
}
e->next_ = e->prev_ = NULL;
e->next_ = e->prev_ = NULL;
delete e;
delete e;
--qsize_;
--qsize_;
return;
return;
}
Ns2CalendarScheduler::BucketItem *
Ns2CalendarScheduler::head (void)
{
NS_ASSERT (!IsEmpty ());
int l = -1, i = lastbucket_;
int lastbucket_dec = (lastbucket_) ? lastbucket_ - 1 : nbuckets_ - 1;
uint64_t diff;
BucketItem *e, *min_e = NULL;
#define CAL_DEQUEUE(x) \
do { \
head_search_++; \
if ((e = buckets_[i].list_) != NULL) { \
diff = e->event.key.m_ts - cal_clock_.m_ts; \
if (diff < diff##x##_) { \
l = i; \
goto found_l; \
} \
if (min_e == NULL || min_e->event.key > e->event.key) { \
min_e = e; \
l = i; \
} \
} \
if (++i == nbuckets_) i = 0; \
} while (0)
// CAL_DEQUEUE applied successively will find the event to
// dequeue (within one year) and keep track of the
// minimum-priority event seen so far; the argument controls
// the criteria used to decide whether the event should be
// considered `within one year'. Importantly, the number of
// buckets should not be less than 4.
CAL_DEQUEUE(0);
CAL_DEQUEUE(1);
for (; i != lastbucket_dec; ) {
CAL_DEQUEUE(2);
}
// one last bucket is left unchecked - take the minimum
// [could have done CAL_DEQUEUE(3) with diff3_ = bwidth*(nbuck*3/2-1)]
e = buckets_[i].list_;
if (min_e != NULL &&
(e == NULL || min_e->event.key < e->event.key))
e = min_e;
else {
//assert(e);
l = i;
}
found_l:
//assert(buckets_[l].count_ >= 0);
//assert(buckets_[l].list_ == e);
/* l is the index of the bucket to dequeue, e is the event */
/*
* still want to advance lastbucket_ and cal_clock_ to save
* time when deque() follows.
*/
assert (l != -1);
lastbucket_ = l;
cal_clock_ = e->event.key;
NS_ASSERT (!IsEmpty ());
return e;
int l = -1, i = lastbucket_;
int lastbucket_dec = (lastbucket_) ? lastbucket_ - 1 : nbuckets_ - 1;
uint64_t diff;
BucketItem *e, *min_e = NULL;
#define CAL_DEQUEUE(x) \
do { \
head_search_++; \
if ((e = buckets_[i].list_) != NULL) { \
diff = e->event.key.m_ts - cal_clock_.m_ts; \
if (diff < diff ## x ## _) { \
l = i; \
goto found_l; \
} \
if (min_e == NULL || min_e->event.key > e->event.key) { \
min_e = e; \
l = i; \
} \
} \
if (++i == nbuckets_) { i = 0; } \
} \
while (0)
// CAL_DEQUEUE applied successively will find the event to
// dequeue (within one year) and keep track of the
// minimum-priority event seen so far; the argument controls
// the criteria used to decide whether the event should be
// considered `within one year'. Importantly, the number of
// buckets should not be less than 4.
CAL_DEQUEUE (0);
CAL_DEQUEUE (1);
for (; i != lastbucket_dec; )
{
CAL_DEQUEUE (2);
}
// one last bucket is left unchecked - take the minimum
// [could have done CAL_DEQUEUE(3) with diff3_ = bwidth*(nbuck*3/2-1)]
e = buckets_[i].list_;
if (min_e != NULL
&& (e == NULL || min_e->event.key < e->event.key))
{
e = min_e;
}
else
{
// assert(e);
l = i;
}
found_l:
// assert(buckets_[l].count_ >= 0);
// assert(buckets_[l].list_ == e);
/* l is the index of the bucket to dequeue, e is the event */
/*
* still want to advance lastbucket_ and cal_clock_ to save
* time when deque() follows.
*/
assert (l != -1);
lastbucket_ = l;
cal_clock_ = e->event.key;
return e;
}
void
Ns2CalendarScheduler::reinit(int nbuck, uint64_t bwidth, Scheduler::EventKey start)
void
Ns2CalendarScheduler::reinit (int nbuck, uint64_t bwidth, Scheduler::EventKey start)
{
buckets_ = new Bucket[nbuck];
buckets_ = new Bucket[nbuck];
memset(buckets_, 0, sizeof(Bucket)*nbuck); //faster than ctor
width_ = bwidth;
nbuckets_ = nbuck;
qsize_ = 0;
stat_qsize_ = 0;
lastbucket_ = CALENDAR_HASH(start);
memset (buckets_, 0, sizeof(Bucket) * nbuck); // faster than ctor
diff0_ = bwidth*nbuck/2;
diff1_ = diff0_ + bwidth;
diff2_ = bwidth*nbuck;
//diff3_ = bwidth*(nbuck*3/2-1);
bot_threshold_ = (nbuck >> 1) - 2;
top_threshold_ = (nbuck << 1);
width_ = bwidth;
nbuckets_ = nbuck;
qsize_ = 0;
stat_qsize_ = 0;
lastbucket_ = CALENDAR_HASH (start);
diff0_ = bwidth * nbuck / 2;
diff1_ = diff0_ + bwidth;
diff2_ = bwidth * nbuck;
// diff3_ = bwidth*(nbuck*3/2-1);
bot_threshold_ = (nbuck >> 1) - 2;
top_threshold_ = (nbuck << 1);
}
void
Ns2CalendarScheduler::resize(int newsize, Scheduler::EventKey start)
void
Ns2CalendarScheduler::resize (int newsize, Scheduler::EventKey start)
{
uint64_t bwidth;
if (newsize == nbuckets_) {
/* we resize for bwidth*/
if (head_search_) bwidth = head_search_; else bwidth = 1;
if (insert_search_) bwidth = bwidth / insert_search_;
bwidth = static_cast<uint64_t> (sqrt (bwidth) * width_);
if (bwidth < min_bin_width_) {
if (time_to_newwidth_>0) {
time_to_newwidth_ --;
head_search_ = 0;
insert_search_ = 0;
round_num_ = 0;
return; //failed to adjust bwidth
} else {
// We have many (adjust_new_width_interval_) times failure in adjusting bwidth.
// should do a reshuffle with newwidth
bwidth = newwidth(newsize);
}
}
//snoopy queue calculation
} else {
/* we resize for size */
bwidth = newwidth(newsize);
if (newsize < 4)
newsize = 4;
}
uint64_t bwidth;
if (newsize == nbuckets_)
{
/* we resize for bwidth*/
if (head_search_)
{
bwidth = head_search_;
}
else
{
bwidth = 1;
}
if (insert_search_)
{
bwidth = bwidth / insert_search_;
}
bwidth = static_cast<uint64_t> (sqrt (bwidth) * width_);
if (bwidth < min_bin_width_)
{
if (time_to_newwidth_ > 0)
{
time_to_newwidth_--;
head_search_ = 0;
insert_search_ = 0;
round_num_ = 0;
return; // failed to adjust bwidth
}
else
{
// We have many (adjust_new_width_interval_) times failure in adjusting bwidth.
// should do a reshuffle with newwidth
bwidth = newwidth (newsize);
}
}
// snoopy queue calculation
}
else
{
/* we resize for size */
bwidth = newwidth (newsize);
if (newsize < 4)
{
newsize = 4;
}
}
Bucket *oldb = buckets_;
int oldn = nbuckets_;
Bucket *oldb = buckets_;
int oldn = nbuckets_;
reinit(newsize, bwidth, start);
reinit (newsize, bwidth, start);
// copy events to new buckets
int i;
// copy events to new buckets
int i;
for (i = 0; i < oldn; ++i) {
// we can do inserts faster, if we use insert2, but to
// preserve FIFO, we have to start from the end of
// each bucket and use insert2
if (oldb[i].list_) {
BucketItem *tail = oldb[i].list_->prev_;
BucketItem *e = tail;
do {
BucketItem* ep = e->prev_;
e->next_ = e->prev_ = 0;
insert2(e);
e = ep;
} while (e != tail);
}
}
head_search_ = 0;
insert_search_ = 0;
round_num_ = 0;
delete [] oldb;
for (i = 0; i < oldn; ++i)
{
// we can do inserts faster, if we use insert2, but to
// preserve FIFO, we have to start from the end of
// each bucket and use insert2
if (oldb[i].list_)
{
BucketItem *tail = oldb[i].list_->prev_;
BucketItem *e = tail;
do
{
BucketItem* ep = e->prev_;
e->next_ = e->prev_ = 0;
insert2 (e);
e = ep;
}
while (e != tail);
}
}
head_search_ = 0;
insert_search_ = 0;
round_num_ = 0;
delete [] oldb;
}
void
Ns2CalendarScheduler::insert2(Ns2CalendarScheduler::BucketItem* e)
void
Ns2CalendarScheduler::insert2 (Ns2CalendarScheduler::BucketItem* e)
{
// Same as insert, but for inserts e *before* any same-time-events, if
// there should be any. Since it is used only by CalendarScheduler::newwidth(),
// some important checks present in insert() need not be performed.
// Same as insert, but for inserts e *before* any same-time-events, if
// there should be any. Since it is used only by CalendarScheduler::newwidth(),
// some important checks present in insert() need not be performed.
int i = CALENDAR_HASH(e->event.key);
BucketItem *head = buckets_[i].list_;
BucketItem *before=0;
if (!head) {
buckets_[i].list_ = e;
e->next_ = e->prev_ = e;
++stat_qsize_;
++buckets_[i].count_;
} else {
bool newhead;
if (e->event.key > head->prev_->event.key) { //strict LIFO, so > and not >=
// insert at the tail
before = head;
newhead = false;
} else {
// insert event in time sorted order, LIFO for sim-time events
for (before = head; e->event.key > before->event.key; before = before->next_)
;
newhead = (before == head);
}
int i = CALENDAR_HASH (e->event.key);
BucketItem *head = buckets_[i].list_;
BucketItem *before = 0;
if (!head)
{
buckets_[i].list_ = e;
e->next_ = e->prev_ = e;
++stat_qsize_;
++buckets_[i].count_;
}
else
{
bool newhead;
if (e->event.key > head->prev_->event.key) // strict LIFO, so > and not >=
{ // insert at the tail
before = head;
newhead = false;
}
else
{
// insert event in time sorted order, LIFO for sim-time events
for (before = head; e->event.key > before->event.key; before = before->next_)
{
}
newhead = (before == head);
}
e->next_ = before;
e->prev_ = before->prev_;
before->prev_ = e;
e->prev_->next_ = e;
if (newhead) {
buckets_[i].list_ = e;
//assert(e->time_ <= e->next_->time_);
}
e->next_ = before;
e->prev_ = before->prev_;
before->prev_ = e;
e->prev_->next_ = e;
if (newhead)
{
buckets_[i].list_ = e;
// assert(e->time_ <= e->next_->time_);
}
if (e != e->next_ && e->next_->event.key != e->event.key) {
// unique timing
++stat_qsize_;
++buckets_[i].count_;
}
}
//assert(e == buckets_[i].list_ || e->prev_->time_ <= e->time_);
//assert(e == buckets_[i].list_->prev_ || e->next_->time_ >= e->time_);
if (e != e->next_ && e->next_->event.key != e->event.key)
{
// unique timing
++stat_qsize_;
++buckets_[i].count_;
}
}
// assert(e == buckets_[i].list_ || e->prev_->time_ <= e->time_);
// assert(e == buckets_[i].list_->prev_ || e->next_->time_ >= e->time_);
++qsize_;
// no need to check resizing
++qsize_;
// no need to check resizing
}
uint64_t
Ns2CalendarScheduler::newwidth(int newsize)
Ns2CalendarScheduler::newwidth (int newsize)
{
if (adjust_new_width_interval_) {
time_to_newwidth_ = adjust_new_width_interval_;
if (avg_gap_ > 0) return avg_gap_*4;
}
int i;
int max_bucket = 0; // index of the fullest bucket
for (i = 1; i < nbuckets_; ++i) {
if (buckets_[i].count_ > buckets_[max_bucket].count_)
max_bucket = i;
}
int nsamples = buckets_[max_bucket].count_;
if (adjust_new_width_interval_)
{
time_to_newwidth_ = adjust_new_width_interval_;
if (avg_gap_ > 0)
{
return avg_gap_ * 4;
}
}
int i;
int max_bucket = 0; // index of the fullest bucket
for (i = 1; i < nbuckets_; ++i)
{
if (buckets_[i].count_ > buckets_[max_bucket].count_)
{
max_bucket = i;
}
}
int nsamples = buckets_[max_bucket].count_;
if (nsamples <= 4) return width_;
uint64_t nw = (buckets_[max_bucket].list_->prev_->event.key.m_ts
- buckets_[max_bucket].list_->event.key.m_ts) * 4;
nw /= ((newsize < nsamples) ? newsize : nsamples); // min (newsize, nsamples)
if (nsamples <= 4)
{
return width_;
}
nw = std::max (nw, min_bin_width_);
return nw;
uint64_t nw = (buckets_[max_bucket].list_->prev_->event.key.m_ts
- buckets_[max_bucket].list_->event.key.m_ts) * 4;
nw /= ((newsize < nsamples) ? newsize : nsamples); // min (newsize, nsamples)
nw = std::max (nw, min_bin_width_);
return nw;
}
} // namespace ns3

View File

@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Authors:
* Authors:
* David Wetherall <djw@juniper.lcs.mit.edu>: originally, in ns-2, back in 1997
* David X. Wei: optimizations in ns-2.28
* Mathieu Lacage <mathieu.lacage@sophia.inria.fr>: port to ns-3
@@ -40,7 +40,7 @@ class EventImpl;
*
* This event scheduler is a copy/paste of the ns2.29 calendar scheduler.
*/
class Ns2CalendarScheduler : public Scheduler
class Ns2CalendarScheduler : public Scheduler
{
public:
static TypeId GetTypeId (void);
@@ -55,37 +55,39 @@ public:
virtual void Remove (const Event &ev);
private:
struct BucketItem {
struct BucketItem
{
ns3::Scheduler::Event event;
struct BucketItem *next_;
struct BucketItem *prev_;
};
struct Bucket {
struct Bucket
{
struct BucketItem *list_;
int count_;
};
void reinit(int nbuck, uint64_t bwidth, Scheduler::EventKey start);
void resize(int newsize, Scheduler::EventKey start);
uint64_t newwidth(int newsize);
void reinit (int nbuck, uint64_t bwidth, Scheduler::EventKey start);
void resize (int newsize, Scheduler::EventKey start);
uint64_t newwidth (int newsize);
void insert2 (Ns2CalendarScheduler::BucketItem *e);
Ns2CalendarScheduler::BucketItem *head (void);
Ns2CalendarScheduler::BucketItem * head (void);
uint64_t min_bin_width_; // minimum bin width for Calendar Queue
uint64_t min_bin_width_; // minimum bin width for Calendar Queue
unsigned int adjust_new_width_interval_; // The interval (in unit of resize time) for adjustment of bin width. A zero value disables automatic bin width adjustment
unsigned time_to_newwidth_; // how many time we failed to adjust the width based on snoopy-queue
unsigned time_to_newwidth_; // how many time we failed to adjust the width based on snoopy-queue
long unsigned head_search_;
long unsigned insert_search_;
int round_num_;
long int gap_num_; //the number of gap samples in this window (in process of calculation)
uint64_t last_time_; //the departure time of first event in this window
int64_t avg_gap_; //the average gap in last window (finished calculation)
long int gap_num_; // the number of gap samples in this window (in process of calculation)
uint64_t last_time_; // the departure time of first event in this window
int64_t avg_gap_; // the average gap in last window (finished calculation)
uint64_t width_;
uint64_t diff0_, diff1_, diff2_; /* wrap-around checks */
int stat_qsize_; /* # of distinct priorities in queue*/
int stat_qsize_; /* # of distinct priorities in queue*/
int nbuckets_;
int lastbucket_;
int top_threshold_;

View File

@@ -33,7 +33,8 @@ namespace ns3 {
namespace TimeStepPrecision {
enum precision_t {
enum precision_t
{
S = 0,
MS = 3,
US = 6,
@@ -44,7 +45,7 @@ enum precision_t {
/**
* \param precision the new precision to use
*
* This should be invoked before any Time object
* This should be invoked before any Time object
* is created. i.e., it should be invoked at the very start
* of every simulation. The unit specified by this method
* is used as the unit of the internal simulation time
@@ -67,8 +68,8 @@ precision_t Get (void);
* \ingroup time
* \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
* 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.
@@ -76,11 +77,11 @@ precision_t Get (void);
* 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
* ==, !=, <, >, <=, >=. 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::Scalar, ns3::Time, ns3::TimeSquare, and ns3::TimeInvert classes
* The ns3::Scalar, ns3::Time, ns3::TimeSquare, and ns3::TimeInvert classes
* are aliases for the TimeUnit<0>, TimeUnit<1>, TimeUnit<2> and TimeUnit<-1>
* types respectively.
*
@@ -96,7 +97,7 @@ precision_t Get (void);
* Scalar s = t4;
* \endcode
*
* If you try to assign the result of an expression which does not
* 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
@@ -143,11 +144,11 @@ public:
* This is really an internal method exported for the needs of
* the implementation. Please, Do not try to use this method, ever.
*
* \return the ns3::HighPrecision object which holds the value
* \return the ns3::HighPrecision object which holds the value
* stored in this Time<N> type.
*/
HighPrecision const &GetHighPrecision (void) const;
HighPrecision *PeekHighPrecision (void);
HighPrecision * PeekHighPrecision (void);
private:
HighPrecision m_data;
@@ -156,11 +157,13 @@ private:
template <int N>
TimeUnit<N>::TimeUnit ()
: m_data ()
{}
{
}
template <int N>
TimeUnit<N>::TimeUnit (TimeUnit const &o)
: m_data (o.m_data)
{}
{
}
template <int N>
TimeUnit<N>
TimeUnit<N>::operator = (TimeUnit const &o)
@@ -171,7 +174,8 @@ TimeUnit<N>::operator = (TimeUnit const &o)
template <int N>
TimeUnit<N>::TimeUnit (HighPrecision data)
: m_data (data)
{}
{
}
template <int N>
HighPrecision const &
@@ -192,62 +196,62 @@ TimeUnit<N>::IsZero (void) const
return m_data.Compare (HighPrecision::Zero ()) == 0;
}
template <int N>
bool
bool
TimeUnit<N>::IsNegative (void) const
{
return m_data.Compare (HighPrecision::Zero ()) <= 0;
}
template <int N>
bool
bool
TimeUnit<N>::IsPositive (void) const
{
return m_data.Compare (HighPrecision::Zero ()) >= 0;
}
template <int N>
bool
bool
TimeUnit<N>::IsStrictlyNegative (void) const
{
return m_data.Compare (HighPrecision::Zero ()) < 0;
}
template <int N>
bool
bool
TimeUnit<N>::IsStrictlyPositive (void) const
{
return m_data.Compare (HighPrecision::Zero ()) > 0;
}
template <int N>
bool
bool
operator == (TimeUnit<N> const &lhs, TimeUnit<N> const &rhs)
{
return lhs.GetHighPrecision ().Compare (rhs.GetHighPrecision ()) == 0;
}
template <int N>
bool
bool
operator != (TimeUnit<N> const &lhs, TimeUnit<N> const &rhs)
{
return lhs.GetHighPrecision ().Compare (rhs.GetHighPrecision ()) != 0;
}
template <int N>
bool
bool
operator <= (TimeUnit<N> const &lhs, TimeUnit<N> const &rhs)
{
return lhs.GetHighPrecision ().Compare (rhs.GetHighPrecision ()) <= 0;
}
template <int N>
bool
bool
operator >= (TimeUnit<N> const &lhs, TimeUnit<N> const &rhs)
{
return lhs.GetHighPrecision ().Compare (rhs.GetHighPrecision ()) >= 0;
}
template <int N>
bool
bool
operator < (TimeUnit<N> const &lhs, TimeUnit<N> const &rhs)
{
return lhs.GetHighPrecision ().Compare (rhs.GetHighPrecision ()) < 0;
}
template <int N>
bool
bool
operator > (TimeUnit<N> const &lhs, TimeUnit<N> const &rhs)
{
return lhs.GetHighPrecision ().Compare (rhs.GetHighPrecision ()) > 0;
@@ -267,31 +271,33 @@ TimeUnit<N> operator - (TimeUnit<N> const &lhs, TimeUnit<N> const &rhs)
return TimeUnit<N> (retval);
}
template <int N1, int N2>
TimeUnit<N1+N2> operator * (TimeUnit<N1> const &lhs, TimeUnit<N2> const &rhs)
TimeUnit<N1 + N2> operator * (TimeUnit<N1> const &lhs, TimeUnit<N2> const &rhs)
{
HighPrecision retval = lhs.GetHighPrecision ();
retval.Mul (rhs.GetHighPrecision ());
// std::cout << lhs.GetHighPrecision().GetInteger() << " * "
// << rhs.GetHighPrecision().GetInteger()
// std::cout << lhs.GetHighPrecision().GetInteger() << " * "
// << rhs.GetHighPrecision().GetInteger()
// << " = " << retval.GetInteger() << std::endl;
return TimeUnit<N1+N2> (retval);
return TimeUnit<N1 + N2> (retval);
}
template <int N1, int N2>
TimeUnit<N1-N2> operator / (TimeUnit<N1> const &lhs, TimeUnit<N2> const &rhs)
TimeUnit<N1 - N2> operator / (TimeUnit<N1> const &lhs, TimeUnit<N2> const &rhs)
{
NS_ASSERT (rhs.GetHighPrecision ().GetDouble () != 0);
HighPrecision retval = lhs.GetHighPrecision ();
retval.Div (rhs.GetHighPrecision ());
return TimeUnit<N1-N2> (retval);
return TimeUnit<N1 - N2> (retval);
}
template <int N>
TimeUnit<N> &operator += (TimeUnit<N> &lhs, TimeUnit<N> const &rhs) {
TimeUnit<N> &operator += (TimeUnit<N> &lhs, TimeUnit<N> const &rhs)
{
HighPrecision *lhsv = lhs.PeekHighPrecision ();
lhsv->Add (rhs.GetHighPrecision ());
return lhs;
}
template <int N>
TimeUnit<N> &operator -= (TimeUnit<N> &lhs, TimeUnit<N> const &rhs) {
TimeUnit<N> &operator -= (TimeUnit<N> &lhs, TimeUnit<N> const &rhs)
{
HighPrecision *lhsv = lhs.PeekHighPrecision ();
lhsv->Sub (rhs.GetHighPrecision ());
return lhs;
@@ -320,7 +326,7 @@ template <int N>
TimeUnit<N> Max (TimeUnit<N> const &ta, TimeUnit<N> const &tb)
{
HighPrecision a = ta.GetHighPrecision ();
HighPrecision b = tb.GetHighPrecision ();
HighPrecision b = tb.GetHighPrecision ();
return TimeUnit<N> (Max (a, b));
}
/**
@@ -334,7 +340,7 @@ template <int N>
TimeUnit<N> Min (TimeUnit<N> const &ta, TimeUnit<N> const &tb)
{
HighPrecision a = ta.GetHighPrecision ();
HighPrecision b = tb.GetHighPrecision ();
HighPrecision b = tb.GetHighPrecision ();
return TimeUnit<N> (Min (a, b));
}
@@ -349,7 +355,6 @@ class TimeUnit<1>
{
// -*- New methods -*-
public:
/**
* \brief String constructor
* Construct TimeUnit<1> object from common time expressions like "
@@ -366,7 +371,7 @@ public:
* occur.
* \param s The string to parse into a TimeUnit<1>
*/
TimeUnit<1>(const std::string& s);
TimeUnit<1> (const std::string & s);
/**
* \returns an approximation in seconds of the time stored in this
* instance.
@@ -376,7 +381,7 @@ public:
/**
* \returns an approximation in milliseconds of the time stored in this
* instance.
*/
*/
int64_t GetMilliSeconds (void) const;
/**
* \returns an approximation in microseconds of the time stored in this
@@ -407,39 +412,52 @@ public:
// -*- The rest is the the same as in the generic template class -*-
public:
TimeUnit ()
: m_data ()
{}
: m_data ()
{
}
TimeUnit (TimeUnit const &o)
: m_data (o.m_data) {}
TimeUnit operator = (TimeUnit const &o) {
: m_data (o.m_data)
{
}
TimeUnit operator = (TimeUnit const &o)
{
m_data = o.m_data;
return *this;
}
TimeUnit (HighPrecision data)
: m_data (data) {}
bool IsZero (void) const {
: m_data (data)
{
}
bool IsZero (void) const
{
return m_data.Compare (HighPrecision::Zero ()) == 0;
}
bool IsNegative (void) const {
bool IsNegative (void) const
{
return m_data.Compare (HighPrecision::Zero ()) <= 0;
}
bool IsPositive (void) const {
bool IsPositive (void) const
{
return m_data.Compare (HighPrecision::Zero ()) >= 0;
}
bool IsStrictlyNegative (void) const {
bool IsStrictlyNegative (void) const
{
return m_data.Compare (HighPrecision::Zero ()) < 0;
}
bool IsStrictlyPositive (void) const {
bool IsStrictlyPositive (void) const
{
return m_data.Compare (HighPrecision::Zero ()) > 0;
}
HighPrecision const &GetHighPrecision (void) const {
HighPrecision const &GetHighPrecision (void) const
{
return m_data;
}
HighPrecision *PeekHighPrecision (void) {
HighPrecision * PeekHighPrecision (void)
{
return &m_data;
}
static uint64_t UnitsToTimestep (uint64_t unitValue,
static uint64_t UnitsToTimestep (uint64_t unitValue,
uint64_t unitFactor);
private:
@@ -476,7 +494,7 @@ private:
* of the ns3::TimeUnit class template)
* To scale a Time instance, you can multiply it with an instance of
* the ns3::Scalar class.
* Time instances can also be manipulated through the following non-member
* Time instances can also be manipulated through the following non-member
* functions:
* - \ref ns3-Time-Abs ns3::Abs
* - \ref ns3-Time-Max ns3::Max
@@ -484,7 +502,7 @@ private:
*
* The Time class has the following additional methods not available in
* the generic TimeUnit template:
*
*
* \code
* double GetSeconds (void) const;
* \endcode
@@ -611,35 +629,48 @@ public:
// -*- The rest is the the same as in the generic template class -*-
public:
TimeUnit ()
: m_data ()
{};
: m_data ()
{
}
TimeUnit (TimeUnit const &o)
: m_data (o.m_data) {}
TimeUnit operator = (TimeUnit const &o) {
: m_data (o.m_data)
{
}
TimeUnit operator = (TimeUnit const &o)
{
m_data = o.m_data;
return *this;
}
TimeUnit (HighPrecision data)
: m_data (data) {}
bool IsZero (void) const {
: m_data (data)
{
}
bool IsZero (void) const
{
return m_data.Compare (HighPrecision::Zero ()) == 0;
}
bool IsNegative (void) const {
bool IsNegative (void) const
{
return m_data.Compare (HighPrecision::Zero ()) <= 0;
}
bool IsPositive (void) const {
bool IsPositive (void) const
{
return m_data.Compare (HighPrecision::Zero ()) >= 0;
}
bool IsStrictlyNegative (void) const {
bool IsStrictlyNegative (void) const
{
return m_data.Compare (HighPrecision::Zero ()) < 0;
}
bool IsStrictlyPositive (void) const {
bool IsStrictlyPositive (void) const
{
return m_data.Compare (HighPrecision::Zero ()) > 0;
}
HighPrecision const &GetHighPrecision (void) const {
HighPrecision const &GetHighPrecision (void) const
{
return m_data;
}
HighPrecision *PeekHighPrecision (void) {
HighPrecision * PeekHighPrecision (void)
{
return &m_data;
}
@@ -652,7 +683,7 @@ private:
*
* This class is used both to construct scalar values to multiply
* ns3::Time instances and to hold the return value of
* an expression which returns a scalar. For example, the
* an expression which returns a scalar. For example, the
* following code will output on your terminal 1.5:
* \code
* Scalar s0 = Scalar (1.5);

View File

@@ -23,15 +23,16 @@
namespace ns3 {
Scheduler::~Scheduler ()
{}
Scheduler::~Scheduler ()
{
}
TypeId
TypeId
Scheduler::GetTypeId (void)
{
static TypeId tid = TypeId ("ns3::Scheduler")
.SetParent<Object> ()
;
;
return tid;
}

View File

@@ -36,9 +36,9 @@ class EventImpl;
* \ingroup scheduler
* \brief Maintain the event list
*
* This base class specifies the interface used to maintain the
* event list. If you want to provide a new event list scheduler,
* you need to create a subclass of this base class and implement
* This base class specifies the interface used to maintain the
* event list. If you want to provide a new event list scheduler,
* you need to create a subclass of this base class and implement
* all the pure virtual methods defined here.
*
* The only tricky aspect of this API is the memory management of
@@ -52,15 +52,17 @@ class EventImpl;
*/
class Scheduler : public Object
{
public:
public:
static TypeId GetTypeId (void);
struct EventKey {
struct EventKey
{
uint64_t m_ts;
uint32_t m_uid;
uint32_t m_context;
};
struct Event {
struct Event
{
EventImpl *impl;
EventKey key;
};
@@ -106,8 +108,8 @@ inline bool operator < (const Scheduler::EventKey &a, const Scheduler::EventKey
{
return true;
}
else if (a.m_ts == b.m_ts &&
a.m_uid < b.m_uid)
else if (a.m_ts == b.m_ts
&& a.m_uid < b.m_uid)
{
return true;
}
@@ -126,8 +128,8 @@ inline bool operator > (const Scheduler::EventKey &a, const Scheduler::EventKey
{
return true;
}
else if (a.m_ts == b.m_ts &&
a.m_uid > b.m_uid)
else if (a.m_ts == b.m_ts
&& a.m_uid > b.m_uid)
{
return true;
}

View File

@@ -39,7 +39,7 @@ static const uint64_t PS_FACTOR = (uint64_t)1000000 * (uint64_t)1000000;
static const uint64_t FS_FACTOR = (uint64_t)1000000 * (uint64_t)1000000 * (uint64_t)1000;
static uint64_t g_tsPrecFactor = NS_FACTOR;
static GlobalValue g_precisionDefaultValue ("TimeStepPrecision",
static GlobalValue g_precisionDefaultValue ("TimeStepPrecision",
"The time unit of the internal 64 bit integer time.",
EnumValue (NS),
MakeEnumChecker (NS, "NS",
@@ -58,76 +58,76 @@ Get (void)
return (precision_t) v.Get ();
}
void
void
Set (precision_t precision)
{
g_precisionDefaultValue.SetValue (EnumValue (precision));
g_tsPrecFactor = (uint64_t)pow(10, precision);
g_tsPrecFactor = (uint64_t)pow (10, precision);
}
} // namespace TimeStepPrecision
TimeUnit<1>::TimeUnit(const std::string& s)
TimeUnit<1>::TimeUnit (const std::string& s)
{
std::string::size_type n = s.find_first_not_of("0123456789.");
std::string::size_type n = s.find_first_not_of ("0123456789.");
if (n != std::string::npos)
{ // Found non-numeric
std::istringstream iss;
iss.str (s.substr(0, n));
double r;
iss >> r;
std::string trailer = s.substr(n, std::string::npos);
if (trailer == std::string("s"))
{
m_data = HighPrecision (r * TimeStepPrecision::g_tsPrecFactor);
return;
{ // Found non-numeric
std::istringstream iss;
iss.str (s.substr (0, n));
double r;
iss >> r;
std::string trailer = s.substr (n, std::string::npos);
if (trailer == std::string ("s"))
{
m_data = HighPrecision (r * TimeStepPrecision::g_tsPrecFactor);
return;
}
if (trailer == std::string ("ms"))
{
m_data = HighPrecision ((int64_t)(r * (TimeStepPrecision::g_tsPrecFactor / pow (10,3))),
false);
return;
}
if (trailer == std::string ("us"))
{
m_data = HighPrecision ((int64_t)(r * (TimeStepPrecision::g_tsPrecFactor / pow (10,6))),
false);
return;
}
if (trailer == std::string ("ns"))
{
m_data = HighPrecision ((int64_t)(r * (TimeStepPrecision::g_tsPrecFactor / pow (10,9))),
false);
return;
}
if (trailer == std::string ("ps"))
{
m_data = HighPrecision ((int64_t)(r * (TimeStepPrecision::g_tsPrecFactor / pow (10,12))),
false);
return;
}
if (trailer == std::string ("fs"))
{
m_data = HighPrecision ((int64_t)(r * (TimeStepPrecision::g_tsPrecFactor / pow (10,15))),
false);
return;
}
NS_FATAL_ERROR ("Can't Parse Time " << s);
}
if (trailer == std::string("ms"))
{
m_data = HighPrecision ((int64_t)(r * (TimeStepPrecision::g_tsPrecFactor/pow(10,3))),
false);
return;
}
if (trailer == std::string("us"))
{
m_data = HighPrecision ((int64_t)(r * (TimeStepPrecision::g_tsPrecFactor/pow(10,6))),
false);
return;
}
if (trailer == std::string("ns"))
{
m_data = HighPrecision ((int64_t)(r * (TimeStepPrecision::g_tsPrecFactor/pow(10,9))),
false);
return;
}
if (trailer == std::string("ps"))
{
m_data = HighPrecision ((int64_t)(r * (TimeStepPrecision::g_tsPrecFactor/pow(10,12))),
false);
return;
}
if (trailer == std::string("fs"))
{
m_data = HighPrecision ((int64_t)(r * (TimeStepPrecision::g_tsPrecFactor/pow(10,15))),
false);
return;
}
NS_FATAL_ERROR("Can't Parse Time "<<s);
}
//else
//they didn't provide units, assume seconds
// else
// they didn't provide units, assume seconds
std::istringstream iss;
iss. str (s);
iss.str (s);
double v;
iss >> v;
m_data = HighPrecision (v * TimeStepPrecision::g_tsPrecFactor);
}
double
double
TimeUnit<1>::GetSeconds (void) const
{
double timeValue = GetHighPrecision ().GetDouble ();
return timeValue/TimeStepPrecision::g_tsPrecFactor;
return timeValue / TimeStepPrecision::g_tsPrecFactor;
}
int64_t
@@ -149,43 +149,43 @@ TimeUnit<1>::ConvertToUnits (int64_t timeValue, uint64_t unitFactor) const
}
int64_t
int64_t
TimeUnit<1>::GetMilliSeconds (void) const
{
int64_t ts = GetTimeStep();
int64_t ms = ConvertToUnits(ts, TimeStepPrecision::MS_FACTOR);
int64_t ts = GetTimeStep ();
int64_t ms = ConvertToUnits (ts, TimeStepPrecision::MS_FACTOR);
return ms;
}
int64_t
int64_t
TimeUnit<1>::GetMicroSeconds (void) const
{
int64_t ts = GetTimeStep();
int64_t us = ConvertToUnits(ts, TimeStepPrecision::US_FACTOR);
int64_t ts = GetTimeStep ();
int64_t us = ConvertToUnits (ts, TimeStepPrecision::US_FACTOR);
return us;
}
int64_t
int64_t
TimeUnit<1>::GetNanoSeconds (void) const
{
int64_t ts = GetTimeStep();
int64_t ns = ConvertToUnits(ts, TimeStepPrecision::NS_FACTOR);
int64_t ts = GetTimeStep ();
int64_t ns = ConvertToUnits (ts, TimeStepPrecision::NS_FACTOR);
return ns;
}
int64_t
int64_t
TimeUnit<1>::GetPicoSeconds (void) const
{
int64_t ts = GetTimeStep();
int64_t ps = ConvertToUnits(ts, TimeStepPrecision::PS_FACTOR);
int64_t ts = GetTimeStep ();
int64_t ps = ConvertToUnits (ts, TimeStepPrecision::PS_FACTOR);
return ps;
}
int64_t
int64_t
TimeUnit<1>::GetFemtoSeconds (void) const
{
int64_t ts = GetTimeStep();
int64_t fs = ConvertToUnits(ts, TimeStepPrecision::FS_FACTOR);
int64_t ts = GetTimeStep ();
int64_t fs = ConvertToUnits (ts, TimeStepPrecision::FS_FACTOR);
return fs;
}
@@ -201,30 +201,31 @@ TimeUnit<1>::GetTimeStep (void) const
}
std::ostream&
std::ostream&
operator<< (std::ostream& os, const Time & time)
{
std::string unit;
switch (TimeStepPrecision::Get ()) {
case TimeStepPrecision::S:
unit = "s";
break;
case TimeStepPrecision::MS:
unit = "ms";
break;
case TimeStepPrecision::US:
unit = "us";
break;
case TimeStepPrecision::NS:
unit = "ns";
break;
case TimeStepPrecision::PS:
unit = "ps";
break;
case TimeStepPrecision::FS:
unit = "fs";
break;
}
switch (TimeStepPrecision::Get ())
{
case TimeStepPrecision::S:
unit = "s";
break;
case TimeStepPrecision::MS:
unit = "ms";
break;
case TimeStepPrecision::US:
unit = "us";
break;
case TimeStepPrecision::NS:
unit = "ns";
break;
case TimeStepPrecision::PS:
unit = "ps";
break;
case TimeStepPrecision::FS:
unit = "fs";
break;
}
os << time.GetTimeStep () << unit;
return os;
}
@@ -232,17 +233,17 @@ std::istream& operator>> (std::istream& is, Time & time)
{
std::string value;
is >> value;
std::string::size_type n = value.find_first_not_of("0123456789.");
std::string::size_type n = value.find_first_not_of ("0123456789.");
if (n == std::string::npos)
{
is.setstate (std::ios_base::failbit);
return is;
}
std::string trailer = value.substr(n, value.size ()-n);
std::string trailer = value.substr (n, value.size () - n);
std::istringstream iss;
iss.str (value.substr(0, n));
iss.str (value.substr (0, n));
if (trailer == std::string("s"))
if (trailer == std::string ("s"))
{
double v;
iss >> v;
@@ -255,23 +256,23 @@ std::istream& operator>> (std::istream& is, Time & time)
{
is.setstate (std::ios_base::failbit);
}
else if (trailer == std::string("ms"))
else if (trailer == std::string ("ms"))
{
time = MilliSeconds (integer);
}
else if (trailer == std::string("us"))
else if (trailer == std::string ("us"))
{
time = MicroSeconds (integer);
}
else if (trailer == std::string("ns"))
else if (trailer == std::string ("ns"))
{
time = NanoSeconds (integer);
}
else if (trailer == std::string("ps"))
else if (trailer == std::string ("ps"))
{
time = PicoSeconds (integer);
}
else if (trailer == std::string("fs"))
else if (trailer == std::string ("fs"))
{
time = FemtoSeconds (integer);
}
@@ -290,7 +291,7 @@ Time Seconds (double seconds)
}
uint64_t
TimeUnit<1>::UnitsToTimestep (uint64_t unitValue,
TimeUnit<1>::UnitsToTimestep (uint64_t unitValue,
uint64_t unitFactor)
{
uint64_t precFactor;
@@ -313,30 +314,30 @@ ATTRIBUTE_CHECKER_IMPLEMENT (Time);
Time MilliSeconds (uint64_t ms)
{
uint64_t ts = TimeUnit<1>::UnitsToTimestep(ms, TimeStepPrecision::MS_FACTOR);
return TimeStep(ts);
uint64_t ts = TimeUnit<1>::UnitsToTimestep (ms, TimeStepPrecision::MS_FACTOR);
return TimeStep (ts);
}
Time MicroSeconds (uint64_t us)
{
uint64_t ts = TimeUnit<1>::UnitsToTimestep(us, TimeStepPrecision::US_FACTOR);
return TimeStep(ts);
uint64_t ts = TimeUnit<1>::UnitsToTimestep (us, TimeStepPrecision::US_FACTOR);
return TimeStep (ts);
}
Time NanoSeconds (uint64_t ns)
{
uint64_t ts = TimeUnit<1>::UnitsToTimestep(ns, TimeStepPrecision::NS_FACTOR);
return TimeStep(ts);
uint64_t ts = TimeUnit<1>::UnitsToTimestep (ns, TimeStepPrecision::NS_FACTOR);
return TimeStep (ts);
}
Time PicoSeconds (uint64_t ps)
{
uint64_t ts = TimeUnit<1>::UnitsToTimestep(ps, TimeStepPrecision::PS_FACTOR);
return TimeStep(ts);
uint64_t ts = TimeUnit<1>::UnitsToTimestep (ps, TimeStepPrecision::PS_FACTOR);
return TimeStep (ts);
}
Time FemtoSeconds (uint64_t fs)
{
uint64_t ts = TimeUnit<1>::UnitsToTimestep(fs, TimeStepPrecision::FS_FACTOR);
return TimeStep(ts);
uint64_t ts = TimeUnit<1>::UnitsToTimestep (fs, TimeStepPrecision::FS_FACTOR);
return TimeStep (ts);
}
@@ -351,7 +352,8 @@ Time TimeStep (uint64_t ts)
TimeUnit<0>::TimeUnit (double scalar)
: m_data (HighPrecision (scalar))
{}
{
}
double
TimeUnit<0>::GetDouble (void) const
@@ -365,86 +367,87 @@ TimeUnit<0>::GetDouble (void) const
namespace ns3 {
#define PRECISION(mult) (pow(10,-((double)(ns3::TimeStepPrecision::Get ())))*mult)
#define PRECISION(mult) (pow (10,-((double)(ns3::TimeStepPrecision::Get ()))) * mult)
#define ASSERT_MSG_EQ(a,b,mult,msg) \
NS_TEST_ASSERT_MSG_EQ(((a)<((b)-PRECISION(mult)) || (a)>((b)+PRECISION(mult))),false, \
msg << " Values are not equal within requested precision range: " << \
(a) << "!=" << (b) << " ~ " << PRECISION(mult))
NS_TEST_ASSERT_MSG_EQ (((a) < ((b) - PRECISION (mult)) || (a) > ((b) + PRECISION (mult))),false, \
msg << " Values are not equal within requested precision range: " << \
(a) << "!=" << (b) << " ~ " << PRECISION (mult))
#define ASSERT_MSG_EQ_INT(a,b,mult,msg) \
ASSERT_MSG_EQ(((int64_t)(a)),((int64_t)(b)),mult,msg)
ASSERT_MSG_EQ (((int64_t)(a)),((int64_t)(b)),mult,msg)
#define ASSERT_EQ(a,b) \
ASSERT_MSG_EQ(a,b,1,"")
ASSERT_MSG_EQ (a,b,1,"")
class OldTimeTestCase : public TestCase
{
public:
OldTimeTestCase();
OldTimeTestCase ();
virtual bool DoRun (void);
};
OldTimeTestCase::OldTimeTestCase()
: TestCase("Sanity check of common time operations")
{}
bool
OldTimeTestCase::OldTimeTestCase ()
: TestCase ("Sanity check of common time operations")
{
}
bool
OldTimeTestCase::DoRun (void)
{
NS_TEST_ASSERT_MSG_EQ(TimeStepPrecision::Get(),
TimeStepPrecision::NS,
"Invalid precision mode");
{
NS_TEST_ASSERT_MSG_EQ (TimeStepPrecision::Get (),
TimeStepPrecision::NS,
"Invalid precision mode");
Time t0 = Seconds (10.0);
ASSERT_EQ(t0.GetSeconds(), 10.0);
ASSERT_EQ (t0.GetSeconds (), 10.0);
Time t1 = Seconds (11.0);
ASSERT_EQ(t1.GetSeconds(), 11.0);
ASSERT_EQ (t1.GetSeconds (), 11.0);
t0 = Seconds (1.5);
ASSERT_EQ(t0.GetSeconds(), 1.5);
ASSERT_EQ (t0.GetSeconds (), 1.5);
t0 = Seconds (-1.5);
ASSERT_EQ(t0.GetSeconds(), -1.5);
ASSERT_EQ (t0.GetSeconds (), -1.5);
t0 = MilliSeconds ((uint64_t)10.0);
ASSERT_EQ(t0.GetSeconds(), 0.01);
ASSERT_EQ (t0.GetSeconds (), 0.01);
t1 = MilliSeconds ((uint64_t)11.0);
ASSERT_EQ(t1.GetSeconds(), 0.011);
ASSERT_EQ (t1.GetSeconds (), 0.011);
Time t2, t3;
t2 = t1 - t0;
NS_TEST_ASSERT_MSG_EQ(t2.IsStrictlyPositive (),true, "Variable should be positive");
ASSERT_EQ(t2.GetSeconds(), t1.GetSeconds()-t0.GetSeconds());
NS_TEST_ASSERT_MSG_EQ (t2.IsStrictlyPositive (),true, "Variable should be positive");
ASSERT_EQ (t2.GetSeconds (), t1.GetSeconds () - t0.GetSeconds ());
t2 = t1 - t1;
NS_TEST_ASSERT_MSG_EQ(t2.IsZero (),true, "Variable should be zero");
ASSERT_EQ(t2.GetSeconds(), t1.GetSeconds()-t1.GetSeconds());
NS_TEST_ASSERT_MSG_EQ (t2.IsZero (),true, "Variable should be zero");
ASSERT_EQ (t2.GetSeconds (), t1.GetSeconds () - t1.GetSeconds ());
t2 = t0 - t1;
NS_TEST_ASSERT_MSG_EQ(t2.IsStrictlyNegative (),true, "Variable should be negative");
ASSERT_EQ(t2.GetSeconds(), t0.GetSeconds()-t1.GetSeconds());
NS_TEST_ASSERT_MSG_EQ (t2.IsStrictlyNegative (),true, "Variable should be negative");
ASSERT_EQ (t2.GetSeconds (), t0.GetSeconds () - t1.GetSeconds ());
Time tmp = MilliSeconds (0);
NS_TEST_ASSERT_MSG_EQ((MilliSeconds (0) == NanoSeconds(0)), true, "Zero is not Zero ?");
NS_TEST_ASSERT_MSG_EQ((MilliSeconds (0) > NanoSeconds(0)), false, "Zero is bigger than Zero ?");
NS_TEST_ASSERT_MSG_EQ((MilliSeconds (0) < NanoSeconds(0)), false, "Zero is smaller than Zero ?");
NS_TEST_ASSERT_MSG_EQ ((MilliSeconds (0) == NanoSeconds (0)), true, "Zero is not Zero ?");
NS_TEST_ASSERT_MSG_EQ ((MilliSeconds (0) > NanoSeconds (0)), false, "Zero is bigger than Zero ?");
NS_TEST_ASSERT_MSG_EQ ((MilliSeconds (0) < NanoSeconds (0)), false, "Zero is smaller than Zero ?");
Time t4 = Seconds (10.0) * Scalar (1.5);
ASSERT_EQ(t4.GetSeconds(), 15.0);
ASSERT_EQ (t4.GetSeconds (), 15.0);
Time t5 = NanoSeconds (10) * Scalar (1.5);
ASSERT_EQ(t5.GetNanoSeconds(), 15.0);
ASSERT_EQ (t5.GetNanoSeconds (), 15.0);
Time t6 = Seconds (10.0) * Scalar (15) / Scalar (10);
ASSERT_EQ(t6.GetSeconds (), 15.0);
ASSERT_EQ (t6.GetSeconds (), 15.0);
Time t7 = NanoSeconds (10) * Scalar (15) / Scalar (10);
ASSERT_EQ(t7.GetNanoSeconds (), 15.0);
ASSERT_EQ (t7.GetNanoSeconds (), 15.0);
ASSERT_EQ((t1 + t2).GetSeconds (), t1.GetSeconds()+t2.GetSeconds());
ASSERT_EQ ((t1 + t2).GetSeconds (), t1.GetSeconds () + t2.GetSeconds ());
ASSERT_EQ((t1 / t2).GetDouble (), t1.GetSeconds()/t2.GetSeconds());
ASSERT_EQ ((t1 / t2).GetDouble (), t1.GetSeconds () / t2.GetSeconds ());
return false;
}
@@ -452,54 +455,55 @@ OldTimeTestCase::DoRun (void)
class OperationsTimeTestCase : public TestCase
{
public:
OperationsTimeTestCase();
virtual bool DoRun(void);
OperationsTimeTestCase ();
virtual bool DoRun (void);
};
OperationsTimeTestCase::OperationsTimeTestCase()
OperationsTimeTestCase::OperationsTimeTestCase ()
: TestCase ("Check the +, -, * and / operators for the TimeUnit<1>")
{}
{
}
bool
OperationsTimeTestCase::DoRun(void)
OperationsTimeTestCase::DoRun (void)
{
// What happens if you set these values ?
// t0 = Seconds ((uint64_t)10.0);
// t1 = Seconds ((uint64_t)11.0);
Time t0 = MilliSeconds(10);
Time t1 = MilliSeconds(11);
Time t0 = MilliSeconds (10);
Time t1 = MilliSeconds (11);
ASSERT_EQ((t0-t1).GetSeconds(),
(t0.GetSeconds()-t1.GetSeconds()));
ASSERT_EQ(((t0-t1) * t0 / t0).GetSeconds(),
((t0.GetSeconds()-t1.GetSeconds()) * t0.GetSeconds () / t0.GetSeconds ()));
ASSERT_EQ(((t0-t1) * t0 / t1).GetSeconds(),
((t0.GetSeconds()-t1.GetSeconds()) * t0.GetSeconds () / t1.GetSeconds ()));
ASSERT_EQ((t0 * (t0-t1) / t1).GetSeconds(),
(t0.GetSeconds () * (t0.GetSeconds()-t1.GetSeconds()) / t1.GetSeconds ()));
ASSERT_EQ((t0 * t1 / (t0-t1)).GetSeconds(),
(t0.GetSeconds () * t1.GetSeconds() / (t0.GetSeconds()-t1.GetSeconds())));
ASSERT_EQ((t0 * (t1 / (t0-t1))).GetSeconds(),
(t0.GetSeconds () * (t1.GetSeconds() / (t0.GetSeconds()-t1.GetSeconds()))));
ASSERT_EQ(((t0 * t1) / (t0-t1)).GetSeconds(),
((t0.GetSeconds () * t1.GetSeconds()) / (t0.GetSeconds()-t1.GetSeconds())));
ASSERT_EQ((t0 / t1 * (t0-t1)).GetSeconds(),
(t0.GetSeconds () / t1.GetSeconds() * (t0.GetSeconds()-t1.GetSeconds())));
ASSERT_EQ(((t0 / t1) * (t0-t1)).GetSeconds(),
(t0.GetSeconds () / t1.GetSeconds()) * (t0.GetSeconds()-t1.GetSeconds()));
ASSERT_EQ((t0 * Scalar(10.0)).GetSeconds (), (t0.GetSeconds () * 10.0));
ASSERT_EQ((Scalar(10.0) * t0).GetSeconds (), (10.0 * t0.GetSeconds ()));
ASSERT_EQ ((t0 - t1).GetSeconds (),
(t0.GetSeconds () - t1.GetSeconds ()));
ASSERT_EQ (((t0 - t1) * t0 / t0).GetSeconds (),
((t0.GetSeconds () - t1.GetSeconds ()) * t0.GetSeconds () / t0.GetSeconds ()));
ASSERT_EQ (((t0 - t1) * t0 / t1).GetSeconds (),
((t0.GetSeconds () - t1.GetSeconds ()) * t0.GetSeconds () / t1.GetSeconds ()));
ASSERT_EQ ((t0 * (t0 - t1) / t1).GetSeconds (),
(t0.GetSeconds () * (t0.GetSeconds () - t1.GetSeconds ()) / t1.GetSeconds ()));
ASSERT_EQ ((t0 * t1 / (t0 - t1)).GetSeconds (),
(t0.GetSeconds () * t1.GetSeconds () / (t0.GetSeconds () - t1.GetSeconds ())));
ASSERT_EQ ((t0 * (t1 / (t0 - t1))).GetSeconds (),
(t0.GetSeconds () * (t1.GetSeconds () / (t0.GetSeconds () - t1.GetSeconds ()))));
ASSERT_EQ (((t0 * t1) / (t0 - t1)).GetSeconds (),
((t0.GetSeconds () * t1.GetSeconds ()) / (t0.GetSeconds () - t1.GetSeconds ())));
ASSERT_EQ ((t0 / t1 * (t0 - t1)).GetSeconds (),
(t0.GetSeconds () / t1.GetSeconds () * (t0.GetSeconds () - t1.GetSeconds ())));
ASSERT_EQ (((t0 / t1) * (t0 - t1)).GetSeconds (),
(t0.GetSeconds () / t1.GetSeconds ()) * (t0.GetSeconds () - t1.GetSeconds ()));
ASSERT_EQ ((t0 * Scalar (10.0)).GetSeconds (), (t0.GetSeconds () * 10.0));
ASSERT_EQ ((Scalar (10.0) * t0).GetSeconds (), (10.0 * t0.GetSeconds ()));
// Note: we need to multiply by 1e9 because GetSeconds is multiplying
ASSERT_EQ(((t0/(t1*(t0-t1))).GetHighPrecision().GetDouble() * 1e9),
(t0.GetSeconds()/(t1.GetSeconds()*(t0.GetSeconds()-t1.GetSeconds()))));
ASSERT_EQ (((t0 / (t1 * (t0 - t1))).GetHighPrecision ().GetDouble () * 1e9),
(t0.GetSeconds () / (t1.GetSeconds () * (t0.GetSeconds () - t1.GetSeconds ()))));
ASSERT_EQ((t0/t1).GetDouble(),(t0.GetSeconds()/t1.GetSeconds()));
ASSERT_EQ ((t0 / t1).GetDouble (),(t0.GetSeconds () / t1.GetSeconds ()));
ASSERT_EQ((t0 * t1 / ((t0-t1) * t0)).GetDouble (),
(t0.GetSeconds () * t1.GetSeconds () / ((t0.GetSeconds () - t1.GetSeconds()) * t0.GetSeconds ())));
ASSERT_EQ ((t0 * t1 / ((t0 - t1) * t0)).GetDouble (),
(t0.GetSeconds () * t1.GetSeconds () / ((t0.GetSeconds () - t1.GetSeconds ()) * t0.GetSeconds ())));
return false;
}
@@ -511,8 +515,9 @@ public:
};
TimeStepTestCase::TimeStepTestCase ()
: TestCase("Check boundaries of TimeStep")
{}
: TestCase ("Check boundaries of TimeStep")
{
}
bool
TimeStepTestCase::DoRun (void)
{
@@ -537,30 +542,31 @@ public:
GlobalPrecisionTestCase::GlobalPrecisionTestCase ()
: TestCase ("Check that global value actually changes the underlying precision")
{}
{
}
#define CHECK_PRECISION(prec) \
Config::SetGlobal ("TimeStepPrecision", StringValue (#prec)); \
NS_TEST_ASSERT_MSG_EQ(TimeStepPrecision::Get(), TimeStepPrecision::prec, "Could not set precision " << #prec)
bool
Config::SetGlobal ("TimeStepPrecision", StringValue (# prec)); \
NS_TEST_ASSERT_MSG_EQ (TimeStepPrecision::Get (), TimeStepPrecision::prec, "Could not set precision " << # prec)
bool
GlobalPrecisionTestCase::DoRun (void)
{
CHECK_PRECISION(S);
CHECK_PRECISION(MS);
CHECK_PRECISION(US);
CHECK_PRECISION(NS);
CHECK_PRECISION(PS);
CHECK_PRECISION(FS);
CHECK_PRECISION (S);
CHECK_PRECISION (MS);
CHECK_PRECISION (US);
CHECK_PRECISION (NS);
CHECK_PRECISION (PS);
CHECK_PRECISION (FS);
return false;
}
void
void
GlobalPrecisionTestCase::DoTeardown (void)
{
TimeStepPrecision::Set (TimeStepPrecision::NS);
}
#if 0
// disable this test because it triggers crazy
// disable this test because it triggers crazy
// compiler behavior (ICE+unbounded memory usage)
class ConversionTestCase : public TestCase
{
@@ -572,7 +578,8 @@ public:
ConversionTestCase::ConversionTestCase ()
: TestCase ("Check crazy time conversions")
{}
{
}
void ConversionTestCase::DoTeardown (void)
{
@@ -581,103 +588,103 @@ void ConversionTestCase::DoTeardown (void)
#define CHECK_CONVERSIONS(tmp) \
do { \
double val = tmp; \
Time t_sec = Seconds(val); \
ASSERT_MSG_EQ(t_sec.GetSeconds(), val*1e0, 1e0, "conv sec s"); \
ASSERT_MSG_EQ_INT(t_sec.GetMilliSeconds(), val*1e3, 1e3, "conv sec ms"); \
ASSERT_MSG_EQ_INT(t_sec.GetMicroSeconds(), val*1e6, 1e6, "conv sec us"); \
ASSERT_MSG_EQ_INT(t_sec.GetNanoSeconds(), val*1e9, 1e9, "conv sec ns"); \
ASSERT_MSG_EQ_INT(t_sec.GetPicoSeconds(), val*1e12, 1e12, "conv sec ps"); \
ASSERT_MSG_EQ_INT(t_sec.GetFemtoSeconds(), val*1e15, 1e15, "conv sec fs"); \
uint64_t int_val = (uint64_t)val; \
Time t_ms = MilliSeconds(int_val); \
ASSERT_MSG_EQ(t_ms.GetSeconds(), val*1e-3, 1e0, "conv ms s"); \
ASSERT_MSG_EQ_INT(t_ms.GetMilliSeconds(), val*1e0, 1e3, "conv ms ms"); \
ASSERT_MSG_EQ_INT(t_ms.GetMicroSeconds(), val*1e3, 1e6, "conv ms us"); \
ASSERT_MSG_EQ_INT(t_ms.GetNanoSeconds(), val*1e6, 1e9, "conv ms ns"); \
ASSERT_MSG_EQ_INT(t_ms.GetPicoSeconds(), val*1e9, 1e12, "conv ms fs"); \
ASSERT_MSG_EQ_INT(t_ms.GetFemtoSeconds(), val*1e12, 1e15, "conv ms ps"); \
Time t_us = MicroSeconds(int_val); \
ASSERT_MSG_EQ(t_us.GetSeconds(), val*1e-6, 1e0, "conv us s"); \
ASSERT_MSG_EQ_INT(t_us.GetMilliSeconds(), val*1e-3, 1e3, "conv us ms"); \
ASSERT_MSG_EQ_INT(t_us.GetMicroSeconds(), val*1e0, 1e6, "conv us us"); \
ASSERT_MSG_EQ_INT(t_us.GetNanoSeconds(), val*1e3, 1e9, "conv us ns"); \
ASSERT_MSG_EQ_INT(t_us.GetPicoSeconds(), val*1e6, 1e12, "conv us ps"); \
ASSERT_MSG_EQ_INT(t_us.GetFemtoSeconds(), val*1e9, 1e15, "conv us fs"); \
Time t_ns = NanoSeconds(int_val); \
ASSERT_MSG_EQ(t_ns.GetSeconds(), val*1e-9, 1e0, "conv ns s"); \
ASSERT_MSG_EQ_INT(t_ns.GetMilliSeconds(), val*1e-6, 1e3, "conv ns ms"); \
ASSERT_MSG_EQ_INT(t_ns.GetMicroSeconds(), val*1e-3, 1e6, "conv ns us"); \
ASSERT_MSG_EQ_INT(t_ns.GetNanoSeconds(), val*1e0, 1e9, "conv ns ns"); \
ASSERT_MSG_EQ_INT(t_ns.GetPicoSeconds(), val*1e3, 1e12, "conv ns ps"); \
ASSERT_MSG_EQ_INT(t_ns.GetFemtoSeconds(), val*1e6, 1e15, "conv ns fs"); \
Time t_ps = PicoSeconds(int_val); \
ASSERT_MSG_EQ(t_ps.GetSeconds(), val*1e-12, 1e0, "conv ps s"); \
ASSERT_MSG_EQ_INT(t_ps.GetMilliSeconds(), val*1e-9, 1e3, "conv ps ms"); \
ASSERT_MSG_EQ_INT(t_ps.GetMicroSeconds(), val*1e-6, 1e6, "conv ps us"); \
ASSERT_MSG_EQ_INT(t_ps.GetNanoSeconds(), val*1e-3, 1e9, "conv ps ns"); \
ASSERT_MSG_EQ_INT(t_ps.GetPicoSeconds(), val*1e0, 1e12, "conv ps ps"); \
ASSERT_MSG_EQ_INT(t_ps.GetFemtoSeconds(), val*1e3, 1e15, "conv ps fs"); \
Time t_fs = FemtoSeconds(int_val); \
ASSERT_MSG_EQ(t_fs.GetSeconds(), val*1e-15, 1e0, "conv fs sec"); \
ASSERT_MSG_EQ_INT(t_fs.GetMilliSeconds(), val*1e-12, 1e3, "conv fs ms"); \
ASSERT_MSG_EQ_INT(t_fs.GetMicroSeconds(), val*1e-9, 1e6, "conv fs us"); \
ASSERT_MSG_EQ_INT(t_fs.GetNanoSeconds(), val*1e-6, 1e9, "conv fs ns"); \
ASSERT_MSG_EQ_INT(t_fs.GetPicoSeconds(), val*1e-3, 1e12, "conv fs ps"); \
ASSERT_MSG_EQ_INT(t_fs.GetFemtoSeconds(), val*1e0, 1e15, "conv fs fs"); \
} while (false)
double val = tmp; \
Time t_sec = Seconds (val); \
ASSERT_MSG_EQ (t_sec.GetSeconds (), val * 1e0, 1e0, "conv sec s"); \
ASSERT_MSG_EQ_INT (t_sec.GetMilliSeconds (), val * 1e3, 1e3, "conv sec ms"); \
ASSERT_MSG_EQ_INT (t_sec.GetMicroSeconds (), val * 1e6, 1e6, "conv sec us"); \
ASSERT_MSG_EQ_INT (t_sec.GetNanoSeconds (), val * 1e9, 1e9, "conv sec ns"); \
ASSERT_MSG_EQ_INT (t_sec.GetPicoSeconds (), val * 1e12, 1e12, "conv sec ps"); \
ASSERT_MSG_EQ_INT (t_sec.GetFemtoSeconds (), val * 1e15, 1e15, "conv sec fs"); \
uint64_t int_val = (uint64_t)val; \
Time t_ms = MilliSeconds (int_val); \
ASSERT_MSG_EQ (t_ms.GetSeconds (), val * 1e-3, 1e0, "conv ms s"); \
ASSERT_MSG_EQ_INT (t_ms.GetMilliSeconds (), val * 1e0, 1e3, "conv ms ms"); \
ASSERT_MSG_EQ_INT (t_ms.GetMicroSeconds (), val * 1e3, 1e6, "conv ms us"); \
ASSERT_MSG_EQ_INT (t_ms.GetNanoSeconds (), val * 1e6, 1e9, "conv ms ns"); \
ASSERT_MSG_EQ_INT (t_ms.GetPicoSeconds (), val * 1e9, 1e12, "conv ms fs"); \
ASSERT_MSG_EQ_INT (t_ms.GetFemtoSeconds (), val * 1e12, 1e15, "conv ms ps"); \
Time t_us = MicroSeconds (int_val); \
ASSERT_MSG_EQ (t_us.GetSeconds (), val * 1e-6, 1e0, "conv us s"); \
ASSERT_MSG_EQ_INT (t_us.GetMilliSeconds (), val * 1e-3, 1e3, "conv us ms"); \
ASSERT_MSG_EQ_INT (t_us.GetMicroSeconds (), val * 1e0, 1e6, "conv us us"); \
ASSERT_MSG_EQ_INT (t_us.GetNanoSeconds (), val * 1e3, 1e9, "conv us ns"); \
ASSERT_MSG_EQ_INT (t_us.GetPicoSeconds (), val * 1e6, 1e12, "conv us ps"); \
ASSERT_MSG_EQ_INT (t_us.GetFemtoSeconds (), val * 1e9, 1e15, "conv us fs"); \
Time t_ns = NanoSeconds (int_val); \
ASSERT_MSG_EQ (t_ns.GetSeconds (), val * 1e-9, 1e0, "conv ns s"); \
ASSERT_MSG_EQ_INT (t_ns.GetMilliSeconds (), val * 1e-6, 1e3, "conv ns ms"); \
ASSERT_MSG_EQ_INT (t_ns.GetMicroSeconds (), val * 1e-3, 1e6, "conv ns us"); \
ASSERT_MSG_EQ_INT (t_ns.GetNanoSeconds (), val * 1e0, 1e9, "conv ns ns"); \
ASSERT_MSG_EQ_INT (t_ns.GetPicoSeconds (), val * 1e3, 1e12, "conv ns ps"); \
ASSERT_MSG_EQ_INT (t_ns.GetFemtoSeconds (), val * 1e6, 1e15, "conv ns fs"); \
Time t_ps = PicoSeconds (int_val); \
ASSERT_MSG_EQ (t_ps.GetSeconds (), val * 1e-12, 1e0, "conv ps s"); \
ASSERT_MSG_EQ_INT (t_ps.GetMilliSeconds (), val * 1e-9, 1e3, "conv ps ms"); \
ASSERT_MSG_EQ_INT (t_ps.GetMicroSeconds (), val * 1e-6, 1e6, "conv ps us"); \
ASSERT_MSG_EQ_INT (t_ps.GetNanoSeconds (), val * 1e-3, 1e9, "conv ps ns"); \
ASSERT_MSG_EQ_INT (t_ps.GetPicoSeconds (), val * 1e0, 1e12, "conv ps ps"); \
ASSERT_MSG_EQ_INT (t_ps.GetFemtoSeconds (), val * 1e3, 1e15, "conv ps fs"); \
Time t_fs = FemtoSeconds (int_val); \
ASSERT_MSG_EQ (t_fs.GetSeconds (), val * 1e-15, 1e0, "conv fs sec"); \
ASSERT_MSG_EQ_INT (t_fs.GetMilliSeconds (), val * 1e-12, 1e3, "conv fs ms"); \
ASSERT_MSG_EQ_INT (t_fs.GetMicroSeconds (), val * 1e-9, 1e6, "conv fs us"); \
ASSERT_MSG_EQ_INT (t_fs.GetNanoSeconds (), val * 1e-6, 1e9, "conv fs ns"); \
ASSERT_MSG_EQ_INT (t_fs.GetPicoSeconds (), val * 1e-3, 1e12, "conv fs ps"); \
ASSERT_MSG_EQ_INT (t_fs.GetFemtoSeconds (), val * 1e0, 1e15, "conv fs fs"); \
} while (false)
bool
ConversionTestCase::DoRun (void)
{
CHECK_CONVERSIONS(5);
CHECK_CONVERSIONS(0);
CHECK_CONVERSIONS(783);
CHECK_CONVERSIONS(1132);
CHECK_CONVERSIONS (5);
CHECK_CONVERSIONS (0);
CHECK_CONVERSIONS (783);
CHECK_CONVERSIONS (1132);
// triggers overflow
// XXX
// CHECK_CONVERSIONS(3341039);
TimeStepPrecision::Set (TimeStepPrecision::US);
CHECK_CONVERSIONS(7);
CHECK_CONVERSIONS(546);
CHECK_CONVERSIONS(6231);
CHECK_CONVERSIONS (7);
CHECK_CONVERSIONS (546);
CHECK_CONVERSIONS (6231);
// triggers overflow
// XXX
// CHECK_CONVERSIONS(1234639);
TimeStepPrecision::Set (TimeStepPrecision::MS);
CHECK_CONVERSIONS(3);
CHECK_CONVERSIONS(134);
CHECK_CONVERSIONS(2341);
CHECK_CONVERSIONS (3);
CHECK_CONVERSIONS (134);
CHECK_CONVERSIONS (2341);
// triggers overflow
// XXX
// CHECK_CONVERSIONS(8956239);
TimeStepPrecision::Set (TimeStepPrecision::NS);
CHECK_CONVERSIONS(4);
CHECK_CONVERSIONS(342);
CHECK_CONVERSIONS(1327);
CHECK_CONVERSIONS (4);
CHECK_CONVERSIONS (342);
CHECK_CONVERSIONS (1327);
// triggers overflow
// XXX
// CHECK_CONVERSIONS(5439627);
TimeStepPrecision::Set (TimeStepPrecision::PS);
CHECK_CONVERSIONS(4);
CHECK_CONVERSIONS(342);
CHECK_CONVERSIONS(1327);
CHECK_CONVERSIONS (4);
CHECK_CONVERSIONS (342);
CHECK_CONVERSIONS (1327);
// triggers overflow
// XXX
// CHECK_CONVERSIONS(5439627);
TimeStepPrecision::Set (TimeStepPrecision::NS);
CHECK_CONVERSIONS(12);
CHECK_CONVERSIONS (12);
TimeStepPrecision::Set (TimeStepPrecision::S);
CHECK_CONVERSIONS(7);
CHECK_CONVERSIONS (7);
TimeStepPrecision::Set (TimeStepPrecision::FS);
CHECK_CONVERSIONS(5);
CHECK_CONVERSIONS (5);
return false;
}
@@ -692,7 +699,8 @@ public:
Bug863TestCase::Bug863TestCase ()
: TestCase ("Bug 863")
{}
{
}
bool Bug863TestCase::DoRun (void)
{
@@ -704,15 +712,15 @@ bool Bug863TestCase::DoRun (void)
static class TimeTestSuite : public TestSuite
{
public:
TimeTestSuite()
: TestSuite("time", UNIT)
TimeTestSuite ()
: TestSuite ("time", UNIT)
{
AddTestCase(new OldTimeTestCase());
AddTestCase(new OperationsTimeTestCase());
AddTestCase(new TimeStepTestCase());
AddTestCase(new GlobalPrecisionTestCase());
AddTestCase (new OldTimeTestCase ());
AddTestCase (new OperationsTimeTestCase ());
AddTestCase (new TimeStepTestCase ());
AddTestCase (new GlobalPrecisionTestCase ());
AddTestCase (new Bug863TestCase ());
//AddTestCase(new ConversionTestCase());
// AddTestCase(new ConversionTestCase());
}
} g_timeTestSuite;

View File

@@ -29,8 +29,10 @@ namespace ns3 {
class TimerImpl
{
public:
virtual ~TimerImpl () {}
public:
virtual ~TimerImpl ()
{
}
template <typename T1>
void SetArgs (T1 a1);
@@ -38,13 +40,13 @@ public:
void SetArgs (T1 a1, T2 a2);
template <typename T1, typename T2, typename T3>
void SetArgs (T1 a1, T2 a2, T3 a3);
template <typename T1, typename T2, typename T3,
template <typename T1, typename T2, typename T3,
typename T4>
void SetArgs (T1 a1, T2 a2, T3 a3, T4 a4);
template <typename T1, typename T2, typename T3,
template <typename T1, typename T2, typename T3,
typename T4, typename T5>
void SetArgs (T1 a1, T2 a2, T3 a3, T4 a4, T5 a5);
template <typename T1, typename T2, typename T3,
template <typename T1, typename T2, typename T3,
typename T4, typename T5, typename T6>
void SetArgs (T1 a1, T2 a2, T3 a3, T4 a4, T5 a5, T6 a6);
@@ -107,12 +109,16 @@ MakeTimerImpl (IntToType<0>, FN fn)
{
struct FnTimerImplZero : public TimerImpl
{
FnTimerImplZero (FN fn)
: m_fn (fn) {}
virtual EventId Schedule (const Time &delay) {
FnTimerImplZero (FN fn)
: m_fn (fn)
{
}
virtual EventId Schedule (const Time &delay)
{
return Simulator::Schedule (delay, m_fn);
}
virtual void Invoke (void) {
virtual void Invoke (void)
{
m_fn ();
}
FN m_fn;
@@ -130,15 +136,20 @@ MakeTimerImpl (IntToType<1>, FN fn)
struct FnTimerImplOne : public TimerImplOne<T1Parameter>
{
FnTimerImplOne (FN fn)
: m_fn (fn) {}
virtual void SetArguments (T1Parameter a1) {
FnTimerImplOne (FN fn)
: m_fn (fn)
{
}
virtual void SetArguments (T1Parameter a1)
{
m_a1 = a1;
}
virtual EventId Schedule (const Time &delay) {
virtual EventId Schedule (const Time &delay)
{
return Simulator::Schedule (delay, m_fn, m_a1);
}
virtual void Invoke (void) {
virtual void Invoke (void)
{
m_fn (m_a1);
}
FN m_fn;
@@ -160,16 +171,21 @@ MakeTimerImpl (IntToType<2>, FN fn)
struct FnTimerImplTwo : public TimerImplTwo<T1Parameter,T2Parameter>
{
FnTimerImplTwo (FN fn)
: m_fn (fn) {}
virtual void SetArguments (T1Parameter a1, T2Parameter a2) {
FnTimerImplTwo (FN fn)
: m_fn (fn)
{
}
virtual void SetArguments (T1Parameter a1, T2Parameter a2)
{
m_a1 = a1;
m_a2 = a2;
}
virtual EventId Schedule (const Time &delay) {
virtual EventId Schedule (const Time &delay)
{
return Simulator::Schedule (delay, m_fn, m_a1, m_a2);
}
virtual void Invoke (void) {
virtual void Invoke (void)
{
m_fn (m_a1, m_a2);
}
FN m_fn;
@@ -195,17 +211,22 @@ MakeTimerImpl (IntToType<3>, FN fn)
struct FnTimerImplThree : public TimerImplThree<T1Parameter,T2Parameter,T3Parameter>
{
FnTimerImplThree (FN fn)
: m_fn (fn) {}
virtual void SetArguments (T1Parameter a1, T2Parameter a2, T3Parameter a3) {
FnTimerImplThree (FN fn)
: m_fn (fn)
{
}
virtual void SetArguments (T1Parameter a1, T2Parameter a2, T3Parameter a3)
{
m_a1 = a1;
m_a2 = a2;
m_a3 = a3;
}
virtual EventId Schedule (const Time &delay) {
virtual EventId Schedule (const Time &delay)
{
return Simulator::Schedule (delay, m_fn, m_a1, m_a2, m_a3);
}
virtual void Invoke (void) {
virtual void Invoke (void)
{
m_fn (m_a1, m_a2, m_a3);
}
FN m_fn;
@@ -235,18 +256,23 @@ MakeTimerImpl (IntToType<4>, FN fn)
struct FnTimerImplFour : public TimerImplFour<T1Parameter,T2Parameter,T3Parameter,T4Parameter>
{
FnTimerImplFour (FN fn)
: m_fn (fn) {}
virtual void SetArguments (T1Parameter a1, T2Parameter a2, T3Parameter a3, T4Parameter a4) {
FnTimerImplFour (FN fn)
: m_fn (fn)
{
}
virtual void SetArguments (T1Parameter a1, T2Parameter a2, T3Parameter a3, T4Parameter a4)
{
m_a1 = a1;
m_a2 = a2;
m_a3 = a3;
m_a4 = a4;
}
virtual EventId Schedule (const Time &delay) {
virtual EventId Schedule (const Time &delay)
{
return Simulator::Schedule (delay, m_fn, m_a1, m_a2, m_a3, m_a4);
}
virtual void Invoke (void) {
virtual void Invoke (void)
{
m_fn (m_a1, m_a2, m_a3, m_a4);
}
FN m_fn;
@@ -280,19 +306,24 @@ MakeTimerImpl (IntToType<5>, FN fn)
struct FnTimerImplFive : public TimerImplFive<T1Parameter,T2Parameter,T3Parameter,T4Parameter,T5Parameter>
{
FnTimerImplFive (FN fn)
: m_fn (fn) {}
virtual void SetArguments (T1Parameter a1, T2Parameter a2, T3Parameter a3, T4Parameter a4, T5Parameter a5) {
FnTimerImplFive (FN fn)
: m_fn (fn)
{
}
virtual void SetArguments (T1Parameter a1, T2Parameter a2, T3Parameter a3, T4Parameter a4, T5Parameter a5)
{
m_a1 = a1;
m_a2 = a2;
m_a3 = a3;
m_a4 = a4;
m_a5 = a5;
}
virtual EventId Schedule (const Time &delay) {
virtual EventId Schedule (const Time &delay)
{
return Simulator::Schedule (delay, m_fn, m_a1, m_a2, m_a3, m_a4, m_a5);
}
virtual void Invoke (void) {
virtual void Invoke (void)
{
m_fn (m_a1, m_a2, m_a3, m_a4, m_a5);
}
FN m_fn;
@@ -330,9 +361,12 @@ MakeTimerImpl (IntToType<6>, FN fn)
struct FnTimerImplSix : public TimerImplSix<T1Parameter,T2Parameter,T3Parameter,T4Parameter,T5Parameter,T6Parameter>
{
FnTimerImplSix (FN fn)
: m_fn (fn) {}
virtual void SetArguments (T1Parameter a1, T2Parameter a2, T3Parameter a3, T4Parameter a4, T5Parameter a5, T6Parameter a6) {
FnTimerImplSix (FN fn)
: m_fn (fn)
{
}
virtual void SetArguments (T1Parameter a1, T2Parameter a2, T3Parameter a3, T4Parameter a4, T5Parameter a5, T6Parameter a6)
{
m_a1 = a1;
m_a2 = a2;
m_a3 = a3;
@@ -340,10 +374,12 @@ MakeTimerImpl (IntToType<6>, FN fn)
m_a5 = a5;
m_a6 = a6;
}
virtual EventId Schedule (const Time &delay) {
virtual EventId Schedule (const Time &delay)
{
return Simulator::Schedule (delay, m_fn, m_a1, m_a2, m_a3, m_a4, m_a5, m_a6);
}
virtual void Invoke (void) {
virtual void Invoke (void)
{
m_fn (m_a1, m_a2, m_a3, m_a4, m_a5, m_a6);
}
FN m_fn;
@@ -365,7 +401,8 @@ struct TimerImplMemberTraits;
template <typename T>
struct TimerImplMemberTraits<T *>
{
static T &GetReference (T *p) {
static T &GetReference (T *p)
{
return *p;
}
};
@@ -375,7 +412,7 @@ TimerImpl *
MakeTimerImpl (MEM_PTR memPtr, OBJ_PTR objPtr)
{
NS_ASSERT (TypeTraits<MEM_PTR>::IsPointerToMember);
return MakeTimerImpl (IntToType<TypeTraits<MEM_PTR>::PointerToMemberTraits::nArgs> () , memPtr, objPtr);
return MakeTimerImpl (IntToType<TypeTraits<MEM_PTR>::PointerToMemberTraits::nArgs> (), memPtr, objPtr);
}
template <typename MEM_PTR, typename OBJ_PTR>
@@ -384,13 +421,18 @@ MakeTimerImpl (IntToType<0>, MEM_PTR memPtr, OBJ_PTR objPtr)
{
struct MemFnTimerImplZero : public TimerImpl
{
MemFnTimerImplZero (MEM_PTR memPtr, OBJ_PTR objPtr)
: m_memPtr (memPtr), m_objPtr (objPtr) {}
virtual EventId Schedule (const Time &delay) {
MemFnTimerImplZero (MEM_PTR memPtr, OBJ_PTR objPtr)
: m_memPtr (memPtr),
m_objPtr (objPtr)
{
}
virtual EventId Schedule (const Time &delay)
{
return Simulator::Schedule (delay, m_memPtr, m_objPtr);
}
virtual void Invoke (void) {
(TimerImplMemberTraits<OBJ_PTR>::GetReference (m_objPtr).*m_memPtr) ();
virtual void Invoke (void)
{
(TimerImplMemberTraits<OBJ_PTR>::GetReference (m_objPtr).*m_memPtr)();
}
MEM_PTR m_memPtr;
OBJ_PTR m_objPtr;
@@ -405,19 +447,25 @@ MakeTimerImpl (IntToType<1>, MEM_PTR memPtr, OBJ_PTR objPtr)
typedef typename TypeTraits<MEM_PTR>::PointerToMemberTraits::Arg1Type T1;
typedef typename TimerTraits<T1>::ParameterType T1Parameter;
typedef typename TimerTraits<T1>::StoredType T1Stored;
struct MemFnTimerImplOne : public TimerImplOne<T1Parameter>
{
MemFnTimerImplOne (MEM_PTR memPtr, OBJ_PTR objPtr)
: m_memPtr (memPtr), m_objPtr (objPtr) {}
virtual void SetArguments (T1Parameter a1) {
MemFnTimerImplOne (MEM_PTR memPtr, OBJ_PTR objPtr)
: m_memPtr (memPtr),
m_objPtr (objPtr)
{
}
virtual void SetArguments (T1Parameter a1)
{
m_a1 = a1;
}
virtual EventId Schedule (const Time &delay) {
virtual EventId Schedule (const Time &delay)
{
return Simulator::Schedule (delay, m_memPtr, m_objPtr, m_a1);
}
virtual void Invoke (void) {
(TimerImplMemberTraits<OBJ_PTR>::GetReference (m_objPtr).*m_memPtr) (m_a1);
virtual void Invoke (void)
{
(TimerImplMemberTraits<OBJ_PTR>::GetReference (m_objPtr).*m_memPtr)(m_a1);
}
MEM_PTR m_memPtr;
OBJ_PTR m_objPtr;
@@ -436,20 +484,26 @@ MakeTimerImpl (IntToType<2>, MEM_PTR memPtr, OBJ_PTR objPtr)
typedef typename TypeTraits<MEM_PTR>::PointerToMemberTraits::Arg2Type T2;
typedef typename TimerTraits<T2>::ParameterType T2Parameter;
typedef typename TimerTraits<T2>::StoredType T2Stored;
struct MemFnTimerImplTwo : public TimerImplTwo<T1Parameter,T2Parameter>
{
MemFnTimerImplTwo (MEM_PTR memPtr, OBJ_PTR objPtr)
: m_memPtr (memPtr), m_objPtr (objPtr) {}
virtual void SetArguments (T1Parameter a1, T2Parameter a2) {
MemFnTimerImplTwo (MEM_PTR memPtr, OBJ_PTR objPtr)
: m_memPtr (memPtr),
m_objPtr (objPtr)
{
}
virtual void SetArguments (T1Parameter a1, T2Parameter a2)
{
m_a1 = a1;
m_a2 = a2;
}
virtual EventId Schedule (const Time &delay) {
virtual EventId Schedule (const Time &delay)
{
return Simulator::Schedule (delay, m_memPtr, m_objPtr, m_a1, m_a2);
}
virtual void Invoke (void) {
(TimerImplMemberTraits<OBJ_PTR>::GetReference (m_objPtr).*m_memPtr) (m_a1, m_a2);
virtual void Invoke (void)
{
(TimerImplMemberTraits<OBJ_PTR>::GetReference (m_objPtr).*m_memPtr)(m_a1, m_a2);
}
MEM_PTR m_memPtr;
OBJ_PTR m_objPtr;
@@ -472,21 +526,27 @@ MakeTimerImpl (IntToType<3>, MEM_PTR memPtr, OBJ_PTR objPtr)
typedef typename TypeTraits<MEM_PTR>::PointerToMemberTraits::Arg3Type T3;
typedef typename TimerTraits<T3>::ParameterType T3Parameter;
typedef typename TimerTraits<T3>::StoredType T3Stored;
struct MemFnTimerImplThree : public TimerImplThree<T1Parameter,T2Parameter,T3Parameter>
{
MemFnTimerImplThree (MEM_PTR memPtr, OBJ_PTR objPtr)
: m_memPtr (memPtr), m_objPtr (objPtr) {}
virtual void SetArguments (T1Parameter a1, T2Parameter a2, T3Parameter a3) {
MemFnTimerImplThree (MEM_PTR memPtr, OBJ_PTR objPtr)
: m_memPtr (memPtr),
m_objPtr (objPtr)
{
}
virtual void SetArguments (T1Parameter a1, T2Parameter a2, T3Parameter a3)
{
m_a1 = a1;
m_a2 = a2;
m_a3 = a3;
}
virtual EventId Schedule (const Time &delay) {
virtual EventId Schedule (const Time &delay)
{
return Simulator::Schedule (delay, m_memPtr, m_objPtr, m_a1, m_a2, m_a3);
}
virtual void Invoke (void) {
(TimerImplMemberTraits<OBJ_PTR>::GetReference (m_objPtr).*m_memPtr) (m_a1, m_a2, m_a3);
virtual void Invoke (void)
{
(TimerImplMemberTraits<OBJ_PTR>::GetReference (m_objPtr).*m_memPtr)(m_a1, m_a2, m_a3);
}
MEM_PTR m_memPtr;
OBJ_PTR m_objPtr;
@@ -513,22 +573,28 @@ MakeTimerImpl (IntToType<4>, MEM_PTR memPtr, OBJ_PTR objPtr)
typedef typename TypeTraits<MEM_PTR>::PointerToMemberTraits::Arg4Type T4;
typedef typename TimerTraits<T4>::ParameterType T4Parameter;
typedef typename TimerTraits<T4>::StoredType T4Stored;
struct MemFnTimerImplFour : public TimerImplFour<T1Parameter,T2Parameter,T3Parameter,T4Parameter>
{
MemFnTimerImplFour (MEM_PTR memPtr, OBJ_PTR objPtr)
: m_memPtr (memPtr), m_objPtr (objPtr) {}
virtual void SetArguments (T1Parameter a1, T2Parameter a2, T3Parameter a3, T4Parameter a4) {
MemFnTimerImplFour (MEM_PTR memPtr, OBJ_PTR objPtr)
: m_memPtr (memPtr),
m_objPtr (objPtr)
{
}
virtual void SetArguments (T1Parameter a1, T2Parameter a2, T3Parameter a3, T4Parameter a4)
{
m_a1 = a1;
m_a2 = a2;
m_a3 = a3;
m_a4 = a4;
}
virtual EventId Schedule (const Time &delay) {
virtual EventId Schedule (const Time &delay)
{
return Simulator::Schedule (delay, m_memPtr, m_objPtr, m_a1, m_a2, m_a3, m_a4);
}
virtual void Invoke (void) {
(TimerImplMemberTraits<OBJ_PTR>::GetReference (m_objPtr).*m_memPtr) (m_a1, m_a2, m_a3, m_a4);
virtual void Invoke (void)
{
(TimerImplMemberTraits<OBJ_PTR>::GetReference (m_objPtr).*m_memPtr)(m_a1, m_a2, m_a3, m_a4);
}
MEM_PTR m_memPtr;
OBJ_PTR m_objPtr;
@@ -559,23 +625,29 @@ MakeTimerImpl (IntToType<5>, MEM_PTR memPtr, OBJ_PTR objPtr)
typedef typename TypeTraits<MEM_PTR>::PointerToMemberTraits::Arg5Type T5;
typedef typename TimerTraits<T5>::ParameterType T5Parameter;
typedef typename TimerTraits<T5>::StoredType T5Stored;
struct MemFnTimerImplFive : public TimerImplFive<T1Parameter,T2Parameter,T3Parameter,T4Parameter,T5Parameter>
{
MemFnTimerImplFive (MEM_PTR memPtr, OBJ_PTR objPtr)
: m_memPtr (memPtr), m_objPtr (objPtr) {}
virtual void SetArguments (T1Parameter a1, T2Parameter a2, T3Parameter a3, T4Parameter a4,T5Parameter a5) {
MemFnTimerImplFive (MEM_PTR memPtr, OBJ_PTR objPtr)
: m_memPtr (memPtr),
m_objPtr (objPtr)
{
}
virtual void SetArguments (T1Parameter a1, T2Parameter a2, T3Parameter a3, T4Parameter a4,T5Parameter a5)
{
m_a1 = a1;
m_a2 = a2;
m_a3 = a3;
m_a4 = a4;
m_a5 = a5;
}
virtual EventId Schedule (const Time &delay) {
virtual EventId Schedule (const Time &delay)
{
return Simulator::Schedule (delay, m_memPtr, m_objPtr, m_a1, m_a2, m_a3, m_a4, m_a5);
}
virtual void Invoke (void) {
(TimerImplMemberTraits<OBJ_PTR>::GetReference (m_objPtr).*m_memPtr) (m_a1, m_a2, m_a3, m_a4, m_a5);
virtual void Invoke (void)
{
(TimerImplMemberTraits<OBJ_PTR>::GetReference (m_objPtr).*m_memPtr)(m_a1, m_a2, m_a3, m_a4, m_a5);
}
MEM_PTR m_memPtr;
OBJ_PTR m_objPtr;
@@ -610,12 +682,16 @@ MakeTimerImpl (IntToType<6>, MEM_PTR memPtr, OBJ_PTR objPtr)
typedef typename TypeTraits<MEM_PTR>::PointerToMemberTraits::Arg6Type T6;
typedef typename TimerTraits<T6>::ParameterType T6Parameter;
typedef typename TimerTraits<T6>::StoredType T6Stored;
struct MemFnTimerImplSix : public TimerImplSix<T1Parameter,T2Parameter,T3Parameter,T4Parameter,T5Parameter,T6Parameter>
{
MemFnTimerImplSix (MEM_PTR memPtr, OBJ_PTR objPtr)
: m_memPtr (memPtr), m_objPtr (objPtr) {}
virtual void SetArguments (T1Parameter a1, T2Parameter a2, T3Parameter a3, T4Parameter a4,T5Parameter a5,T6Parameter a6) {
MemFnTimerImplSix (MEM_PTR memPtr, OBJ_PTR objPtr)
: m_memPtr (memPtr),
m_objPtr (objPtr)
{
}
virtual void SetArguments (T1Parameter a1, T2Parameter a2, T3Parameter a3, T4Parameter a4,T5Parameter a5,T6Parameter a6)
{
m_a1 = a1;
m_a2 = a2;
m_a3 = a3;
@@ -623,11 +699,13 @@ MakeTimerImpl (IntToType<6>, MEM_PTR memPtr, OBJ_PTR objPtr)
m_a5 = a5;
m_a6 = a6;
}
virtual EventId Schedule (const Time &delay) {
virtual EventId Schedule (const Time &delay)
{
return Simulator::Schedule (delay, m_memPtr, m_objPtr, m_a1, m_a2, m_a3, m_a4, m_a5, m_a6);
}
virtual void Invoke (void) {
(TimerImplMemberTraits<OBJ_PTR>::GetReference (m_objPtr).*m_memPtr) (m_a1, m_a2, m_a3, m_a4, m_a5, m_a6);
virtual void Invoke (void)
{
(TimerImplMemberTraits<OBJ_PTR>::GetReference (m_objPtr).*m_memPtr)(m_a1, m_a2, m_a3, m_a4, m_a5, m_a6);
}
MEM_PTR m_memPtr;
OBJ_PTR m_objPtr;
@@ -676,7 +754,7 @@ TimerImpl::SetArgs (T1 a1, T2 a2)
}
template <typename T1, typename T2, typename T3>
void
void
TimerImpl::SetArgs (T1 a1, T2 a2, T3 a3)
{
typedef struct TimerImplThree<
@@ -694,7 +772,7 @@ TimerImpl::SetArgs (T1 a1, T2 a2, T3 a3)
}
template <typename T1, typename T2, typename T3, typename T4>
void
void
TimerImpl::SetArgs (T1 a1, T2 a2, T3 a3, T4 a4)
{
typedef struct TimerImplFour<
@@ -713,7 +791,7 @@ TimerImpl::SetArgs (T1 a1, T2 a2, T3 a3, T4 a4)
}
template <typename T1, typename T2, typename T3, typename T4, typename T5>
void
void
TimerImpl::SetArgs (T1 a1, T2 a2, T3 a3, T4 a4, T5 a5)
{
typedef struct TimerImplFive<
@@ -733,7 +811,7 @@ TimerImpl::SetArgs (T1 a1, T2 a2, T3 a3, T4 a4, T5 a5)
}
template <typename T1, typename T2, typename T3, typename T4, typename T5, typename T6>
void
void
TimerImpl::SetArgs (T1 a1, T2 a2, T3 a3, T4 a4, T5 a5, T6 a6)
{
typedef struct TimerImplSix<

View File

@@ -28,23 +28,25 @@ Timer::Timer ()
m_delay (FemtoSeconds (0)),
m_event (),
m_impl (0)
{}
{
}
Timer::Timer (enum DestroyPolicy destroyPolicy)
: m_flags (destroyPolicy),
m_delay (FemtoSeconds (0)),
m_event (),
m_impl (0)
{}
{
}
Timer::~Timer ()
{
if (m_flags & CHECK_ON_DESTROY)
{
if (m_event.IsRunning ())
{
NS_FATAL_ERROR ("Event is still running while destroying.");
}
{
NS_FATAL_ERROR ("Event is still running while destroying.");
}
}
else if (m_flags & CANCEL_ON_DESTROY)
{
@@ -57,12 +59,12 @@ Timer::~Timer ()
delete m_impl;
}
void
void
Timer::SetDelay (const Time &time)
{
m_delay = time;
}
Time
Time
Timer::GetDelay (void) const
{
return m_delay;
@@ -70,39 +72,40 @@ Timer::GetDelay (void) const
Time
Timer::GetDelayLeft (void) const
{
switch (GetState ()) {
case Timer::RUNNING:
return Simulator::GetDelayLeft (m_event);
break;
case Timer::EXPIRED:
return TimeStep (0);
break;
case Timer::SUSPENDED:
return m_delayLeft;
break;
default:
NS_ASSERT (false);
return TimeStep (0);
break;
}
switch (GetState ())
{
case Timer::RUNNING:
return Simulator::GetDelayLeft (m_event);
break;
case Timer::EXPIRED:
return TimeStep (0);
break;
case Timer::SUSPENDED:
return m_delayLeft;
break;
default:
NS_ASSERT (false);
return TimeStep (0);
break;
}
}
void
void
Timer::Cancel (void)
{
Simulator::Cancel (m_event);
}
void
void
Timer::Remove (void)
{
Simulator::Remove (m_event);
}
bool
bool
Timer::IsExpired (void) const
{
return !IsSuspended () && m_event.IsExpired ();
}
bool
bool
Timer::IsRunning (void) const
{
return !IsSuspended () && m_event.IsRunning ();
@@ -112,7 +115,7 @@ Timer::IsSuspended (void) const
{
return (m_flags & TIMER_SUSPENDED) == TIMER_SUSPENDED;
}
enum Timer::State
enum Timer::State
Timer::GetState (void) const
{
if (IsRunning ())
@@ -123,20 +126,20 @@ Timer::GetState (void) const
{
return Timer::EXPIRED;
}
else
else
{
NS_ASSERT (IsSuspended ());
return Timer::SUSPENDED;
}
}
void
void
Timer::Schedule (void)
{
Schedule (m_delay);
}
void
void
Timer::Schedule (Time delay)
{
NS_ASSERT (m_impl != 0);
@@ -173,25 +176,35 @@ Timer::Resume (void)
namespace {
void bari (int)
{}
{
}
void bar2i (int, int)
{}
{
}
void bar3i (int, int, int)
{}
{
}
void bar4i (int, int, int, int)
{}
{
}
void bar5i (int, int, int, int, int)
{}
{
}
void bar6i (int, int, int, int, int, int)
{}
{
}
void barcir (const int &)
{}
{
}
void barir (int &)
{}
{
}
void barip (int *)
{}
{
}
void barcip (const int *)
{}
{
}
} // anonymous namespace
namespace ns3 {
@@ -205,8 +218,9 @@ public:
TimerStateTestCase::TimerStateTestCase ()
: TestCase ("Check correct state transitions")
{}
bool
{
}
bool
TimerStateTestCase::DoRun (void)
{
Timer timer = Timer (Timer::CANCEL_ON_DESTROY);
@@ -247,21 +261,42 @@ public:
TimerTemplateTestCase ();
virtual bool DoRun (void);
virtual void DoTeardown (void);
void bazi (int) {}
void baz2i (int, int) {}
void baz3i (int, int, int) {}
void baz4i (int, int, int, int) {}
void baz5i (int, int, int, int, int) {}
void baz6i (int, int, int, int, int, int) {}
void bazcir (const int&) {}
void bazir (int&) {}
void bazip (int *) {}
void bazcip (const int *) {}
void bazi (int)
{
}
void baz2i (int, int)
{
}
void baz3i (int, int, int)
{
}
void baz4i (int, int, int, int)
{
}
void baz5i (int, int, int, int, int)
{
}
void baz6i (int, int, int, int, int, int)
{
}
void bazcir (const int&)
{
}
void bazir (int&)
{
}
void bazip (int *)
{
}
void bazcip (const int *)
{
}
};
TimerTemplateTestCase::TimerTemplateTestCase ()
: TestCase ("Check that template magic is working")
{}
{
}
bool
TimerTemplateTestCase::DoRun (void)
@@ -289,7 +324,7 @@ TimerTemplateTestCase::DoRun (void)
timer.SetArguments (c);
// the following call cannot possibly work and is flagged by
// a runtime error.
//timer.SetArguments (0.0);
// timer.SetArguments (0.0);
timer.SetDelay (Seconds (1.0));
timer.Schedule ();
@@ -309,8 +344,8 @@ TimerTemplateTestCase::DoRun (void)
timer.SetFunction (&bar5i);
timer.SetArguments (1, 1, 1, 1, 1);
// unsupported in simulator class
//timer.SetFunction (&bar6i);
//timer.SetArguments (1, 1, 1, 1, 1, 1);
// timer.SetFunction (&bar6i);
// timer.SetArguments (1, 1, 1, 1, 1, 1);
timer.SetFunction (&TimerTemplateTestCase::baz2i, this);
timer.SetArguments (1, 1);
@@ -321,8 +356,8 @@ TimerTemplateTestCase::DoRun (void)
timer.SetFunction (&TimerTemplateTestCase::baz5i, this);
timer.SetArguments (1, 1, 1, 1, 1);
// unsupported in simulator class
//timer.SetFunction (&TimerTemplateTestCase::baz6i, this);
//timer.SetArguments (1, 1, 1, 1, 1, 1);
// timer.SetFunction (&TimerTemplateTestCase::baz6i, this);
// timer.SetArguments (1, 1, 1, 1, 1, 1);
Simulator::Run ();
Simulator::Destroy ();

View File

@@ -42,31 +42,33 @@ class TimerImpl;
* management policies. These policies are specified at construction time
* and cannot be changed after.
*/
class Timer
class Timer
{
public:
/**
* The policy to use to manager the internal timer when and
* instance of the Timer class is destroyed.
*/
enum DestroyPolicy {
enum DestroyPolicy
{
/**
* This policy cancels the event from the destructor of the Timer
* to verify that the event has already expired.
*/
CANCEL_ON_DESTROY = (1<<3),
CANCEL_ON_DESTROY = (1 << 3),
/**
* This policy removes the event from the simulation event list
* when the destructor of the Timer is invoked.
*/
REMOVE_ON_DESTROY = (1<<4),
REMOVE_ON_DESTROY = (1 << 4),
/**
* This policy enforces a check from the destructor of the Timer
* to verify that the timer has already expired.
*/
CHECK_ON_DESTROY = (1<<5)
CHECK_ON_DESTROY = (1 << 5)
};
enum State {
enum State
{
RUNNING,
EXPIRED,
SUSPENDED,
@@ -180,7 +182,7 @@ public:
*/
void Cancel (void);
/**
* Remove from the simulation event-list the currently-running event
* Remove from the simulation event-list the currently-running event
* if there is one. Do nothing otherwise.
*/
void Remove (void);
@@ -202,14 +204,14 @@ public:
*/
enum Timer::State GetState (void) const;
/**
* Schedule a new event using the currently-configured delay, function,
* Schedule a new event using the currently-configured delay, function,
* and arguments.
*/
void Schedule (void);
/**
* \param delay the delay to use
*
* Schedule a new event using the specified delay (ignore the delay set by
* Schedule a new event using the specified delay (ignore the delay set by
* Timer::SetDelay), function, and arguments.
*/
void Schedule (Time delay);
@@ -228,9 +230,9 @@ public:
void Resume (void);
private:
enum {
TIMER_SUSPENDED = (1<<7)
enum
{
TIMER_SUSPENDED = (1 << 7)
};
int m_flags;
@@ -248,14 +250,14 @@ namespace ns3 {
template <typename FN>
void
void
Timer::SetFunction (FN fn)
{
delete m_impl;
m_impl = MakeTimerImpl (fn);
}
template <typename MEM_PTR, typename OBJ_PTR>
void
void
Timer::SetFunction (MEM_PTR memPtr, OBJ_PTR objPtr)
{
delete m_impl;
@@ -263,7 +265,7 @@ Timer::SetFunction (MEM_PTR memPtr, OBJ_PTR objPtr)
}
template <typename T1>
void
void
Timer::SetArguments (T1 a1)
{
if (m_impl == 0)
@@ -274,7 +276,7 @@ Timer::SetArguments (T1 a1)
m_impl->SetArgs (a1);
}
template <typename T1, typename T2>
void
void
Timer::SetArguments (T1 a1, T2 a2)
{
if (m_impl == 0)
@@ -286,7 +288,7 @@ Timer::SetArguments (T1 a1, T2 a2)
}
template <typename T1, typename T2, typename T3>
void
void
Timer::SetArguments (T1 a1, T2 a2, T3 a3)
{
if (m_impl == 0)
@@ -298,7 +300,7 @@ Timer::SetArguments (T1 a1, T2 a2, T3 a3)
}
template <typename T1, typename T2, typename T3, typename T4>
void
void
Timer::SetArguments (T1 a1, T2 a2, T3 a3, T4 a4)
{
if (m_impl == 0)
@@ -310,7 +312,7 @@ Timer::SetArguments (T1 a1, T2 a2, T3 a3, T4 a4)
}
template <typename T1, typename T2, typename T3, typename T4, typename T5>
void
void
Timer::SetArguments (T1 a1, T2 a2, T3 a3, T4 a4, T5 a5)
{
if (m_impl == 0)
@@ -322,7 +324,7 @@ Timer::SetArguments (T1 a1, T2 a2, T3 a3, T4 a4, T5 a5)
}
template <typename T1, typename T2, typename T3, typename T4, typename T5, typename T6>
void
void
Timer::SetArguments (T1 a1, T2 a2, T3 a3, T4 a4, T5 a5, T6 a6)
{
if (m_impl == 0)