coding style
This commit is contained in:
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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 ();
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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_;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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<
|
||||
|
||||
@@ -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 ();
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user