Browse Source

change indent to be 4 spaces

ndnSIM-v1
Mathieu Lacage 19 years ago
parent
commit
f935fe02bd
  1. 78
      samples/main-callback.cc
  2. 80
      samples/main-packet.cc
  3. 30
      samples/main-simulator.cc
  4. 50
      samples/main-trace.cc
  5. 878
      src/common/buffer.cc
  6. 956
      src/common/buffer.h
  7. 78
      src/common/callback-tracer.h
  8. 20
      src/common/chunk-constant-data.cc
  9. 18
      src/common/chunk-constant-data.h
  10. 22
      src/common/chunk.cc
  11. 80
      src/common/chunk.h
  12. 62
      src/common/data-writer.cc
  13. 12
      src/common/data-writer.h
  14. 34
      src/common/f-variable-tracer.h
  15. 80
      src/common/packet.cc
  16. 60
      src/common/packet.h
  17. 54
      src/common/pcap-writer.cc
  18. 48
      src/common/pcap-writer.h
  19. 210
      src/common/si-variable-tracer.h
  20. 46
      src/common/stream-tracer-test.cc
  21. 60
      src/common/stream-tracer.h
  22. 356
      src/common/tags.cc
  23. 234
      src/common/tags.h
  24. 164
      src/common/trace-container.cc
  25. 326
      src/common/trace-container.h
  26. 222
      src/common/ui-variable-tracer.h
  27. 388
      src/common/variable-tracer-test.cc
  28. 208
      src/core/callback-test.cc
  29. 312
      src/core/callback.h
  30. 114
      src/core/reference-list-test.cc
  31. 146
      src/core/reference-list.h
  32. 12
      src/core/system-file.h
  33. 12
      src/core/system-wall-clock-ms.h
  34. 66
      src/core/test.cc
  35. 42
      src/core/test.h
  36. 62
      src/core/unix-system-file.cc
  37. 34
      src/core/unix-system-wall-clock-ms.cc
  38. 20
      src/core/win32-system-file.cc
  39. 18
      src/core/win32-system-wall-clock-ms.cc
  40. 24
      src/simulator/event-id.cc
  41. 30
      src/simulator/event-id.h
  42. 18
      src/simulator/event-impl.cc
  43. 22
      src/simulator/event-impl.h
  44. 4
      src/simulator/scheduler-factory.cc
  45. 16
      src/simulator/scheduler-factory.h
  46. 154
      src/simulator/scheduler-heap.cc
  47. 54
      src/simulator/scheduler-heap.h
  48. 76
      src/simulator/scheduler-list.cc
  49. 32
      src/simulator/scheduler-list.h
  50. 56
      src/simulator/scheduler-map.cc
  51. 40
      src/simulator/scheduler-map.h
  52. 40
      src/simulator/scheduler.cc
  53. 124
      src/simulator/scheduler.h
  54. 374
      src/simulator/simulator.cc
  55. 868
      src/simulator/simulator.h
  56. 80
      src/simulator/time.cc
  57. 38
      src/simulator/time.h
  58. 134
      utils/bench-packets.cc
  59. 166
      utils/bench-simulator.cc
  60. 400
      utils/replay-simulation.cc
  61. 8
      utils/run-tests.cc

78
samples/main-callback.cc

@ -1,4 +1,4 @@
/* -*- Mode:C++; c-basic-offset:8; tab-width:8; indent-tabs-mode:t -*- */
/* -*- Mode:C++; c-basic-offset:4; tab-width:4; indent-tabs-mode:f -*- */
#include "ns3/callback.h"
#include <cassert>
#include <iostream>
@ -8,51 +8,51 @@ using namespace ns3;
static double
cbOne (double a, double b)
{
std::cout << "invoke cbOne a=" << a << ", b=" << b << std::endl;
return a;
std::cout << "invoke cbOne a=" << a << ", b=" << b << std::endl;
return a;
}
class MyCb {
public:
int cbTwo (double a) {
std::cout << "invoke cbTwo a=" << a << std::endl;
return -5;
}
int cbTwo (double a) {
std::cout << "invoke cbTwo a=" << a << std::endl;
return -5;
}
};
int main (int argc, char *argv[])
{
// return type: double
// first arg type: double
// second arg type: double
Callback<double, double, double> one;
// build callback instance which points to cbOne function
one = makeCallback (&cbOne);
// this is not a null callback
assert (!one.isNull ());
// invoke cbOne function through callback instance
double retOne;
retOne = one (10.0, 20.0);
// return type: int
// first arg type: double
Callback<int, double> two;
MyCb cb;
// build callback instance which points to MyCb::cbTwo
two = makeCallback (&MyCb::cbTwo, &cb);
// this is not a null callback
assert (!two.isNull ());
// invoke MyCb::cbTwo through callback instance
int retTwo;
retTwo = two (10.0);
two = makeNullCallback<int, double> ();
// invoking a null callback is just like
// invoking a null function pointer:
// it will crash.
//int retTwoNull = two (20.0);
assert (two.isNull ());
return 0;
// return type: double
// first arg type: double
// second arg type: double
Callback<double, double, double> one;
// build callback instance which points to cbOne function
one = makeCallback (&cbOne);
// this is not a null callback
assert (!one.isNull ());
// invoke cbOne function through callback instance
double retOne;
retOne = one (10.0, 20.0);
// return type: int
// first arg type: double
Callback<int, double> two;
MyCb cb;
// build callback instance which points to MyCb::cbTwo
two = makeCallback (&MyCb::cbTwo, &cb);
// this is not a null callback
assert (!two.isNull ());
// invoke MyCb::cbTwo through callback instance
int retTwo;
retTwo = two (10.0);
two = makeNullCallback<int, double> ();
// invoking a null callback is just like
// invoking a null function pointer:
// it will crash.
//int retTwoNull = two (20.0);
assert (two.isNull ());
return 0;
}

80
samples/main-packet.cc

@ -1,4 +1,4 @@
/* -*- Mode:C++; c-basic-offset:8; tab-width:8; indent-tabs-mode:t -*- */
/* -*- Mode:C++; c-basic-offset:4; tab-width:4; indent-tabs-mode:f -*- */
#include "ns3/packet.h"
#include "ns3/chunk.h"
#include <iostream>
@ -9,18 +9,18 @@ using namespace ns3;
*/
class MyChunk : public Chunk {
public:
MyChunk ();
virtual ~MyChunk ();
MyChunk ();
virtual ~MyChunk ();
void setData (uint16_t data);
uint16_t getData (void) const;
void setData (uint16_t data);
uint16_t getData (void) const;
private:
virtual void print (std::ostream *os) const;
virtual void addTo (Buffer *buffer) const;
virtual void peekFrom (Buffer const *buffer);
virtual void removeFrom (Buffer *buffer);
virtual void print (std::ostream *os) const;
virtual void addTo (Buffer *buffer) const;
virtual void peekFrom (Buffer const *buffer);
virtual void removeFrom (Buffer *buffer);
uint16_t m_data;
uint16_t m_data;
};
MyChunk::MyChunk ()
@ -30,71 +30,71 @@ MyChunk::~MyChunk ()
void
MyChunk::print (std::ostream *os) const
{
*os << "MyChunk data=" << m_data << std::endl;
*os << "MyChunk data=" << m_data << std::endl;
}
void
MyChunk::addTo (Buffer *buffer) const
{
// reserve 2 bytes at head of buffer
buffer->addAtStart (2);
Buffer::Iterator i = buffer->begin ();
// serialize in head of buffer
i.writeHtonU16 (m_data);
// reserve 2 bytes at head of buffer
buffer->addAtStart (2);
Buffer::Iterator i = buffer->begin ();
// serialize in head of buffer
i.writeHtonU16 (m_data);
}
void
MyChunk::peekFrom (Buffer const *buffer)
{
Buffer::Iterator i = buffer->begin ();
// deserialize from head of buffer
m_data = i.readNtohU16 ();
Buffer::Iterator i = buffer->begin ();
// deserialize from head of buffer
m_data = i.readNtohU16 ();
}
void
MyChunk::removeFrom (Buffer *buffer)
{
// remove deserialized data
buffer->removeAtStart (2);
// remove deserialized data
buffer->removeAtStart (2);
}
void
MyChunk::setData (uint16_t data)
{
m_data = data;
m_data = data;
}
uint16_t
MyChunk::getData (void) const
{
return m_data;
return m_data;
}
/* A sample Tag implementation
*/
struct MyTag {
uint16_t m_streamId;
uint16_t m_streamId;
};
static void
receive (Packet p)
{
MyChunk my;
p.peek (&my);
p.remove (&my);
std::cout << "received data=" << my.getData () << std::endl;
struct MyTag myTag;
p.peekTag (&myTag);
MyChunk my;
p.peek (&my);
p.remove (&my);
std::cout << "received data=" << my.getData () << std::endl;
struct MyTag myTag;
p.peekTag (&myTag);
}
int main (int argc, char *argv[])
{
Packet p;
MyChunk my;
my.setData (2);
std::cout << "send data=2" << std::endl;
p.add (&my);
struct MyTag myTag;
myTag.m_streamId = 5;
p.addTag (&myTag);
receive (p);
return 0;
Packet p;
MyChunk my;
my.setData (2);
std::cout << "send data=2" << std::endl;
p.add (&my);
struct MyTag myTag;
myTag.m_streamId = 5;
p.addTag (&myTag);
receive (p);
return 0;
}

30
samples/main-simulator.cc

@ -1,4 +1,4 @@
/* -*- Mode:C++; c-basic-offset:8; tab-width:8; indent-tabs-mode:t -*- */
/* -*- Mode:C++; c-basic-offset:4; tab-width:4; indent-tabs-mode:f -*- */
#include "ns3/simulator.h"
#include "ns3/time.h"
#include <iostream>
@ -7,41 +7,41 @@ using namespace ns3;
class MyModel {
public:
void start (void);
void start (void);
private:
void dealWithEvent (double eventValue);
void dealWithEvent (double eventValue);
};
void
MyModel::start (void)
{
Simulator::schedule (Time::relS (10.0),
&MyModel::dealWithEvent,
this, Simulator::now ().s ());
Simulator::schedule (Time::relS (10.0),
&MyModel::dealWithEvent,
this, Simulator::now ().s ());
}
void
MyModel::dealWithEvent (double value)
{
std::cout << "Member method received event at " << Simulator::now ().s () <<
"s started at " << value << "s" << std::endl;
std::cout << "Member method received event at " << Simulator::now ().s () <<
"s started at " << value << "s" << std::endl;
}
static void
random_function (MyModel *model)
{
std::cout << "random function received event at " <<
Simulator::now ().s () << "s" << std::endl;
model->start ();
std::cout << "random function received event at " <<
Simulator::now ().s () << "s" << std::endl;
model->start ();
}
int main (int argc, char *argv[])
{
MyModel model;
MyModel model;
Simulator::schedule (Time::absS (10.0), &random_function, &model);
Simulator::schedule (Time::absS (10.0), &random_function, &model);
Simulator::run ();
Simulator::run ();
Simulator::destroy ();
Simulator::destroy ();
}

50
samples/main-trace.cc

@ -1,4 +1,4 @@
/* -*- Mode:C++; c-basic-offset:8; tab-width:8; indent-tabs-mode:t -*- */
/* -*- Mode:C++; c-basic-offset:4; tab-width:4; indent-tabs-mode:f -*- */
#include "ns3/trace-container.h"
#include "ns3/ui-variable-tracer.h"
#include "ns3/callback-tracer.h"
@ -17,22 +17,22 @@ CallbackTracer<double, int> d;
void
registerAllTraceSources (TraceContainer *container)
{
container->registerCallback ("source-a", &a);
container->registerUiVariable ("source-b", &b);
container->registerStream ("source-c", &c);
container->registerCallback ("source-d", &d);
container->registerCallback ("source-a", &a);
container->registerUiVariable ("source-b", &b);
container->registerStream ("source-c", &c);
container->registerCallback ("source-d", &d);
}
void
generateTraceEvents (void)
{
// log en empty packet
a (Packet ());
b = 10;
b += 100;
b += 50;
b = (unsigned short) -20;
c << "this is a simple test b=" << b << std::endl;
d (3.1415, 3);
// log en empty packet
a (Packet ());
b = 10;
b += 100;
b += 50;
b = (unsigned short) -20;
c << "this is a simple test b=" << b << std::endl;
d (3.1415, 3);
}
void
@ -46,16 +46,16 @@ callbackEvent (double a, int b)
int main (int argc, char *argv[])
{
TraceContainer traces;
registerAllTraceSources (&traces);
PcapWriter pcap;
pcap.open ("trace-test.log");
pcap.writeHeaderEthernet ();
traces.setCallback ("source-a",
makeCallback (&PcapWriter::writePacket, &pcap));
traces.setUiVariableCallback ("source-b", makeCallback (&variableEvent));
traces.setStream ("source-c", &std::cout);
traces.setCallback ("source-d", makeCallback (&callbackEvent));
generateTraceEvents ();
return 0;
TraceContainer traces;
registerAllTraceSources (&traces);
PcapWriter pcap;
pcap.open ("trace-test.log");
pcap.writeHeaderEthernet ();
traces.setCallback ("source-a",
makeCallback (&PcapWriter::writePacket, &pcap));
traces.setUiVariableCallback ("source-b", makeCallback (&variableEvent));
traces.setStream ("source-c", &std::cout);
traces.setCallback ("source-d", makeCallback (&callbackEvent));
generateTraceEvents ();
return 0;
}

878
src/common/buffer.cc

@ -1,4 +1,4 @@
/* -*- Mode:C++; c-basic-offset:8; tab-width:8; indent-tabs-mode:t -*- */
/* -*- Mode:C++; c-basic-offset:4; tab-width:4; indent-tabs-mode:f -*- */
/*
* Copyright (c) 2005,2006 INRIA
* All rights reserved.
@ -34,78 +34,78 @@ uint32_t Buffer::m_maxTotalAddEnd = 0;
struct Buffer::BufferData *
Buffer::allocate (uint32_t reqSize, uint32_t reqStart)
{
if (reqSize == 0) {
reqSize = 1;
}
assert (reqSize >= 1);
uint32_t size = reqSize - 1 + sizeof (struct Buffer::BufferData);
uint8_t *b = new uint8_t [size];
struct BufferData *data = reinterpret_cast<struct Buffer::BufferData*>(b);
data->m_size = reqSize;
data->m_initialStart = reqStart;
data->m_dirtyStart = reqStart;
data->m_dirtySize = 0;
data->m_count = 1;
return data;
if (reqSize == 0) {
reqSize = 1;
}
assert (reqSize >= 1);
uint32_t size = reqSize - 1 + sizeof (struct Buffer::BufferData);
uint8_t *b = new uint8_t [size];
struct BufferData *data = reinterpret_cast<struct Buffer::BufferData*>(b);
data->m_size = reqSize;
data->m_initialStart = reqStart;
data->m_dirtyStart = reqStart;
data->m_dirtySize = 0;
data->m_count = 1;
return data;
}
void
Buffer::deallocate (struct Buffer::BufferData *data)
{
uint8_t *buf = reinterpret_cast<uint8_t *> (data);
delete [] buf;
uint8_t *buf = reinterpret_cast<uint8_t *> (data);
delete [] buf;
}
#ifdef USE_FREE_LIST
void
Buffer::recycle (struct Buffer::BufferData *data)
{
assert (data->m_count == 0);
/* get rid of it if it is too small for later reuse. */
if (data->m_size < (Buffer::m_maxTotalAddStart + Buffer::m_maxTotalAddEnd)) {
Buffer::deallocate (data);
return;
}
/* feed into free list */
if (Buffer::m_freeList.size () > 1000) {
Buffer::deallocate (data);
} else {
Buffer::m_freeList.push_back (data);
}
assert (data->m_count == 0);
/* get rid of it if it is too small for later reuse. */
if (data->m_size < (Buffer::m_maxTotalAddStart + Buffer::m_maxTotalAddEnd)) {
Buffer::deallocate (data);
return;
}
/* feed into free list */
if (Buffer::m_freeList.size () > 1000) {
Buffer::deallocate (data);
} else {
Buffer::m_freeList.push_back (data);
}
}
Buffer::BufferData *
Buffer::create (void)
{
/* try to find a buffer correctly sized. */
while (!Buffer::m_freeList.empty ()) {
struct Buffer::BufferData *data = Buffer::m_freeList.back ();
Buffer::m_freeList.pop_back ();
if (data->m_size >= (m_maxTotalAddStart + m_maxTotalAddEnd)) {
data->m_initialStart = m_maxTotalAddStart;
data->m_dirtyStart = m_maxTotalAddStart;
data->m_dirtySize = 0;
data->m_count = 1;
return data;
}
Buffer::deallocate (data);
}
struct Buffer::BufferData *data = Buffer::allocate (m_maxTotalAddStart+m_maxTotalAddEnd,
m_maxTotalAddStart);
assert (data->m_count == 1);
return data;
/* try to find a buffer correctly sized. */
while (!Buffer::m_freeList.empty ()) {
struct Buffer::BufferData *data = Buffer::m_freeList.back ();
Buffer::m_freeList.pop_back ();
if (data->m_size >= (m_maxTotalAddStart + m_maxTotalAddEnd)) {
data->m_initialStart = m_maxTotalAddStart;
data->m_dirtyStart = m_maxTotalAddStart;
data->m_dirtySize = 0;
data->m_count = 1;
return data;
}
Buffer::deallocate (data);
}
struct Buffer::BufferData *data = Buffer::allocate (m_maxTotalAddStart+m_maxTotalAddEnd,
m_maxTotalAddStart);
assert (data->m_count == 1);
return data;
}
#else
void
Buffer::recycle (struct Buffer::BufferData *data)
{
Buffer::deallocate (data);
Buffer::deallocate (data);
}
Buffer::BufferData *
Buffer::create (void)
{
return Buffer::allocate (m_maxTotalAddStart+m_maxTotalAddEnd,
m_maxTotalAddStart);
return Buffer::allocate (m_maxTotalAddStart+m_maxTotalAddEnd,
m_maxTotalAddStart);
}
#endif
@ -120,253 +120,253 @@ namespace ns3 {
void
Buffer::addAtStart (uint32_t start)
{
assert (m_start <= m_data->m_initialStart);
bool isDirty = m_data->m_count > 1 && m_start > m_data->m_dirtyStart;
if (m_start >= start && !isDirty) {
/* enough space in the buffer and not dirty. */
m_start -= start;
m_size += start;
} else if (m_size + start <= m_data->m_size && !isDirty) {
/* enough space but need to move data around to fit new data */
memmove (m_data->m_data + start, getStart (), m_size);
assert (start > m_start);
m_data->m_initialStart += start;
m_start = 0;
m_size += start;
} else if (m_start < start) {
/* not enough space in buffer */
uint32_t newSize = m_size + start;
struct Buffer::BufferData *newData = Buffer::allocate (newSize, 0);
memcpy (newData->m_data + start, getStart (), m_size);
newData->m_initialStart = m_data->m_initialStart + start;
m_data->m_count--;
if (m_data->m_count == 0) {
Buffer::deallocate (m_data);
}
m_data = newData;
m_start = 0;
m_size = newSize;
} else {
/* enough space in the buffer but it is dirty ! */
assert (isDirty);
struct Buffer::BufferData *newData = Buffer::create ();
memcpy (newData->m_data + m_start, getStart (), m_size);
newData->m_initialStart = m_data->m_initialStart;
m_data->m_count--;
if (m_data->m_count == 0) {
recycle (m_data);
}
m_data = newData;
m_start -= start;
m_size += start;
}
// update dirty area
m_data->m_dirtyStart = m_start;
m_data->m_dirtySize = m_size;
// update m_maxTotalAddStart
uint32_t addedAtStart;
if (m_data->m_initialStart > m_start) {
addedAtStart = m_data->m_initialStart - m_start;
} else {
addedAtStart = 0;
}
if (addedAtStart > m_maxTotalAddStart) {
m_maxTotalAddStart = addedAtStart;
}
TRACE ("start add="<<start<<", start="<<m_start<<", size="<<m_size<<", zero="<<m_zeroAreaSize<<
", real size="<<m_data->m_size<<", ini start="<<m_data->m_initialStart<<
", dirty start="<<m_data->m_dirtyStart<<", dirty size="<<m_data->m_dirtySize);
assert (m_start <= m_data->m_initialStart);
bool isDirty = m_data->m_count > 1 && m_start > m_data->m_dirtyStart;
if (m_start >= start && !isDirty) {
/* enough space in the buffer and not dirty. */
m_start -= start;
m_size += start;
} else if (m_size + start <= m_data->m_size && !isDirty) {
/* enough space but need to move data around to fit new data */
memmove (m_data->m_data + start, getStart (), m_size);
assert (start > m_start);
m_data->m_initialStart += start;
m_start = 0;
m_size += start;
} else if (m_start < start) {
/* not enough space in buffer */
uint32_t newSize = m_size + start;
struct Buffer::BufferData *newData = Buffer::allocate (newSize, 0);
memcpy (newData->m_data + start, getStart (), m_size);
newData->m_initialStart = m_data->m_initialStart + start;
m_data->m_count--;
if (m_data->m_count == 0) {
Buffer::deallocate (m_data);
}
m_data = newData;
m_start = 0;
m_size = newSize;
} else {
/* enough space in the buffer but it is dirty ! */
assert (isDirty);
struct Buffer::BufferData *newData = Buffer::create ();
memcpy (newData->m_data + m_start, getStart (), m_size);
newData->m_initialStart = m_data->m_initialStart;
m_data->m_count--;
if (m_data->m_count == 0) {
recycle (m_data);
}
m_data = newData;
m_start -= start;
m_size += start;
}
// update dirty area
m_data->m_dirtyStart = m_start;
m_data->m_dirtySize = m_size;
// update m_maxTotalAddStart
uint32_t addedAtStart;
if (m_data->m_initialStart > m_start) {
addedAtStart = m_data->m_initialStart - m_start;
} else {
addedAtStart = 0;
}
if (addedAtStart > m_maxTotalAddStart) {
m_maxTotalAddStart = addedAtStart;
}
TRACE ("start add="<<start<<", start="<<m_start<<", size="<<m_size<<", zero="<<m_zeroAreaSize<<
", real size="<<m_data->m_size<<", ini start="<<m_data->m_initialStart<<
", dirty start="<<m_data->m_dirtyStart<<", dirty size="<<m_data->m_dirtySize);
}
void
Buffer::addAtEnd (uint32_t end)
{
assert (m_start <= m_data->m_initialStart);
bool isDirty = m_data->m_count > 1 &&
m_start + m_size < m_data->m_dirtyStart + m_data->m_dirtySize;
if (m_start + m_size + end <= m_data->m_size && !isDirty) {
/* enough space in buffer and not dirty */
m_size += end;
} else if (m_size + end <= m_data->m_size && !isDirty) {
/* enough space but need to move data around to fit the extra data */
uint32_t newStart = m_data->m_size - (m_size + end);
memmove (m_data->m_data + newStart, getStart (), m_size);
assert (newStart < m_start);
m_data->m_initialStart -= m_start - newStart;
m_start = newStart;
m_size += end;
} else if (m_start + m_size + end > m_data->m_size) {
/* not enough space in buffer */
uint32_t newSize = m_size + end;
struct Buffer::BufferData *newData = Buffer::allocate (newSize, 0);
memcpy (newData->m_data, getStart (), m_size);
newData->m_initialStart = m_data->m_initialStart;
m_data->m_count--;
if (m_data->m_count == 0) {
Buffer::deallocate (m_data);
}
m_data = newData;
m_size = newSize;
m_start = 0;
} else {
/* enough space in the buffer but it is dirty ! */
assert (isDirty);
struct Buffer::BufferData *newData = Buffer::create ();
memcpy (newData->m_data + m_start, getStart (), m_size);
newData->m_initialStart = m_data->m_initialStart;
m_data->m_count--;
if (m_data->m_count == 0) {
recycle (m_data);
}
m_data = newData;
m_size += end;
}
// update dirty area
m_data->m_dirtyStart = m_start;
m_data->m_dirtySize = m_size;
// update m_maxTotalAddEnd
uint32_t endLoc = m_start + m_size;
uint32_t addedAtEnd;
if (m_data->m_initialStart < endLoc) {
addedAtEnd = endLoc - m_data->m_initialStart;
} else {
addedAtEnd = 0;
}
if (addedAtEnd > m_maxTotalAddEnd) {
m_maxTotalAddEnd = addedAtEnd;
}
TRACE ("end add="<<end<<", start="<<m_start<<", size="<<m_size<<", zero="<<m_zeroAreaSize<<
", real size="<<m_data->m_size<<", ini start="<<m_data->m_initialStart<<
", dirty start="<<m_data->m_dirtyStart<<", dirty size="<<m_data->m_dirtySize);
assert (m_start <= m_data->m_initialStart);
bool isDirty = m_data->m_count > 1 &&
m_start + m_size < m_data->m_dirtyStart + m_data->m_dirtySize;
if (m_start + m_size + end <= m_data->m_size && !isDirty) {
/* enough space in buffer and not dirty */
m_size += end;
} else if (m_size + end <= m_data->m_size && !isDirty) {
/* enough space but need to move data around to fit the extra data */
uint32_t newStart = m_data->m_size - (m_size + end);
memmove (m_data->m_data + newStart, getStart (), m_size);
assert (newStart < m_start);
m_data->m_initialStart -= m_start - newStart;
m_start = newStart;
m_size += end;
} else if (m_start + m_size + end > m_data->m_size) {
/* not enough space in buffer */
uint32_t newSize = m_size + end;
struct Buffer::BufferData *newData = Buffer::allocate (newSize, 0);
memcpy (newData->m_data, getStart (), m_size);
newData->m_initialStart = m_data->m_initialStart;
m_data->m_count--;
if (m_data->m_count == 0) {
Buffer::deallocate (m_data);
}
m_data = newData;
m_size = newSize;
m_start = 0;
} else {
/* enough space in the buffer but it is dirty ! */
assert (isDirty);
struct Buffer::BufferData *newData = Buffer::create ();
memcpy (newData->m_data + m_start, getStart (), m_size);
newData->m_initialStart = m_data->m_initialStart;
m_data->m_count--;
if (m_data->m_count == 0) {
recycle (m_data);
}
m_data = newData;
m_size += end;
}
// update dirty area
m_data->m_dirtyStart = m_start;
m_data->m_dirtySize = m_size;
// update m_maxTotalAddEnd
uint32_t endLoc = m_start + m_size;
uint32_t addedAtEnd;
if (m_data->m_initialStart < endLoc) {
addedAtEnd = endLoc - m_data->m_initialStart;
} else {
addedAtEnd = 0;
}
if (addedAtEnd > m_maxTotalAddEnd) {
m_maxTotalAddEnd = addedAtEnd;
}
TRACE ("end add="<<end<<", start="<<m_start<<", size="<<m_size<<", zero="<<m_zeroAreaSize<<
", real size="<<m_data->m_size<<", ini start="<<m_data->m_initialStart<<
", dirty start="<<m_data->m_dirtyStart<<", dirty size="<<m_data->m_dirtySize);
}
void
Buffer::removeAtStart (uint32_t start)
{
if (m_zeroAreaSize == 0) {
if (m_size <= start) {
m_start += m_size;
m_size = 0;
} else {
m_start += start;
m_size -= start;
}
} else {
assert (m_data->m_initialStart >= m_start);
uint32_t zeroStart = m_data->m_initialStart - m_start;
uint32_t zeroEnd = zeroStart + m_zeroAreaSize;
uint32_t dataEnd = m_size + m_zeroAreaSize;
if (start <= zeroStart) {
/* only remove start of buffer */
m_start += start;
m_size -= start;
} else if (start <= zeroEnd) {
/* remove start of buffer _and_ start of zero area */
m_start += zeroStart;
uint32_t zeroDelta = start - zeroStart;
m_zeroAreaSize -= zeroDelta;
assert (zeroDelta <= start);
m_size -= zeroStart;
} else if (start <= dataEnd) {
/* remove start of buffer, complete zero area, and part
* of end of buffer */
m_start += start - m_zeroAreaSize;
m_size -= start - m_zeroAreaSize;
m_zeroAreaSize = 0;
} else {
/* remove all buffer */
m_start += m_size;
m_size = 0;
m_zeroAreaSize = 0;
}
}
TRACE ("start remove="<<start<<", start="<<m_start<<", size="<<m_size<<", zero="<<m_zeroAreaSize<<
", real size="<<m_data->m_size<<", ini start="<<m_data->m_initialStart<<
", dirty start="<<m_data->m_dirtyStart<<", dirty size="<<m_data->m_dirtySize);
if (m_zeroAreaSize == 0) {
if (m_size <= start) {
m_start += m_size;
m_size = 0;
} else {
m_start += start;
m_size -= start;
}
} else {
assert (m_data->m_initialStart >= m_start);
uint32_t zeroStart = m_data->m_initialStart - m_start;
uint32_t zeroEnd = zeroStart + m_zeroAreaSize;
uint32_t dataEnd = m_size + m_zeroAreaSize;
if (start <= zeroStart) {
/* only remove start of buffer */
m_start += start;
m_size -= start;
} else if (start <= zeroEnd) {
/* remove start of buffer _and_ start of zero area */
m_start += zeroStart;
uint32_t zeroDelta = start - zeroStart;
m_zeroAreaSize -= zeroDelta;
assert (zeroDelta <= start);
m_size -= zeroStart;
} else if (start <= dataEnd) {
/* remove start of buffer, complete zero area, and part
* of end of buffer */
m_start += start - m_zeroAreaSize;
m_size -= start - m_zeroAreaSize;
m_zeroAreaSize = 0;
} else {
/* remove all buffer */
m_start += m_size;
m_size = 0;
m_zeroAreaSize = 0;
}
}
TRACE ("start remove="<<start<<", start="<<m_start<<", size="<<m_size<<", zero="<<m_zeroAreaSize<<
", real size="<<m_data->m_size<<", ini start="<<m_data->m_initialStart<<
", dirty start="<<m_data->m_dirtyStart<<", dirty size="<<m_data->m_dirtySize);
}
void
Buffer::removeAtEnd (uint32_t end)
{
if (m_zeroAreaSize == 0) {
if (m_size <= end) {
m_size = 0;
} else {
m_size -= end;
}
} else {
assert (m_data->m_initialStart >= m_start);
uint32_t zeroStart = m_data->m_initialStart - m_start;
uint32_t zeroEnd = zeroStart + m_zeroAreaSize;
uint32_t dataEnd = m_size + m_zeroAreaSize;
assert (zeroStart <= m_size);
assert (zeroEnd <= m_size + m_zeroAreaSize);
if (dataEnd <= end) {
/* remove all buffer */
m_zeroAreaSize = 0;
m_start += m_size;
m_size = 0;
} else if (dataEnd - zeroStart <= end) {
/* remove end of buffer, zero area, part of start of buffer */
assert (end >= m_zeroAreaSize);
m_size -= end - m_zeroAreaSize;
m_zeroAreaSize = 0;
} else if (dataEnd - zeroEnd <= end) {
/* remove end of buffer, part of zero area */
uint32_t zeroDelta = end - (dataEnd - zeroEnd);
m_zeroAreaSize -= zeroDelta;
m_size -= end - zeroDelta;
} else {
/* remove part of end of buffer */
m_size -= end;
}
}
TRACE ("end remove="<<end<<", start="<<m_start<<", size="<<m_size<<", zero="<<m_zeroAreaSize<<
", real size="<<m_data->m_size<<", ini start="<<m_data->m_initialStart<<
", dirty start="<<m_data->m_dirtyStart<<", dirty size="<<m_data->m_dirtySize);
if (m_zeroAreaSize == 0) {
if (m_size <= end) {
m_size = 0;
} else {
m_size -= end;
}
} else {
assert (m_data->m_initialStart >= m_start);
uint32_t zeroStart = m_data->m_initialStart - m_start;
uint32_t zeroEnd = zeroStart + m_zeroAreaSize;
uint32_t dataEnd = m_size + m_zeroAreaSize;
assert (zeroStart <= m_size);
assert (zeroEnd <= m_size + m_zeroAreaSize);
if (dataEnd <= end) {
/* remove all buffer */
m_zeroAreaSize = 0;
m_start += m_size;
m_size = 0;
} else if (dataEnd - zeroStart <= end) {
/* remove end of buffer, zero area, part of start of buffer */
assert (end >= m_zeroAreaSize);
m_size -= end - m_zeroAreaSize;
m_zeroAreaSize = 0;
} else if (dataEnd - zeroEnd <= end) {
/* remove end of buffer, part of zero area */
uint32_t zeroDelta = end - (dataEnd - zeroEnd);
m_zeroAreaSize -= zeroDelta;
m_size -= end - zeroDelta;
} else {
/* remove part of end of buffer */
m_size -= end;
}
}
TRACE ("end remove="<<end<<", start="<<m_start<<", size="<<m_size<<", zero="<<m_zeroAreaSize<<
", real size="<<m_data->m_size<<", ini start="<<m_data->m_initialStart<<
", dirty start="<<m_data->m_dirtyStart<<", dirty size="<<m_data->m_dirtySize);
}
Buffer
Buffer::createFragment (uint32_t start, uint32_t length) const
{
uint32_t zeroStart = m_data->m_initialStart - m_start;
uint32_t zeroEnd = zeroStart + m_zeroAreaSize;
if (m_zeroAreaSize != 0 &&
start + length > zeroStart &&
start <= zeroEnd) {
transform_intoRealBuffer ();
}
Buffer tmp = *this;
tmp.removeAtStart (start);
tmp.removeAtEnd (getSize () - (start + length));
return tmp;
uint32_t zeroStart = m_data->m_initialStart - m_start;
uint32_t zeroEnd = zeroStart + m_zeroAreaSize;
if (m_zeroAreaSize != 0 &&
start + length > zeroStart &&
start <= zeroEnd) {
transform_intoRealBuffer ();
}
Buffer tmp = *this;
tmp.removeAtStart (start);
tmp.removeAtEnd (getSize () - (start + length));
return tmp;
}
void
Buffer::transform_intoRealBuffer (void) const
{
if (m_zeroAreaSize != 0) {
assert (m_data->m_initialStart >= m_start);
assert (m_size >= (m_data->m_initialStart - m_start));
Buffer tmp;
tmp.addAtStart (m_zeroAreaSize);
tmp.begin ().writeU8 (0, m_zeroAreaSize);
uint32_t dataStart = m_data->m_initialStart - m_start;
tmp.addAtStart (dataStart);
tmp.begin ().write (m_data->m_data+m_start, dataStart);
uint32_t dataEnd = m_size - (m_data->m_initialStart - m_start);
tmp.addAtEnd (dataEnd);
Buffer::Iterator i = tmp.end ();
i.prev (dataEnd);
i.write (m_data->m_data+m_data->m_initialStart,dataEnd);
*const_cast<Buffer *> (this) = tmp;
}
if (m_zeroAreaSize != 0) {
assert (m_data->m_initialStart >= m_start);
assert (m_size >= (m_data->m_initialStart - m_start));
Buffer tmp;
tmp.addAtStart (m_zeroAreaSize);
tmp.begin ().writeU8 (0, m_zeroAreaSize);
uint32_t dataStart = m_data->m_initialStart - m_start;
tmp.addAtStart (dataStart);
tmp.begin ().write (m_data->m_data+m_start, dataStart);
uint32_t dataEnd = m_size - (m_data->m_initialStart - m_start);
tmp.addAtEnd (dataEnd);
Buffer::Iterator i = tmp.end ();
i.prev (dataEnd);
i.write (m_data->m_data+m_data->m_initialStart,dataEnd);
*const_cast<Buffer *> (this) = tmp;
}
}
uint8_t *
Buffer::peekData (void) const
{
transform_intoRealBuffer ();
return m_data->m_data + m_start;
transform_intoRealBuffer ();
return m_data->m_data + m_start;
}
@ -392,37 +392,37 @@ public:
BufferTest::BufferTest ()
: Test ("Buffer") {}
: Test ("Buffer") {}
bool
BufferTest::ensureWrittenBytes (Buffer b, uint32_t n, uint8_t array[])
{
bool success = true;
uint8_t *expected = array;
uint8_t *got;
got = b.peekData ();
for (uint32_t j = 0; j < n; j++) {
if (got[j] != expected[j]) {
success = false;
}
}
if (!success) {
failure () << "Buffer -- ";
failure () << "expected: n=";
failure () << n << ", ";
failure ().setf (std::ios::hex, std::ios::basefield);
for (uint32_t j = 0; j < n; j++) {
failure () << (uint16_t)expected[j] << " ";
}
failure ().setf (std::ios::dec, std::ios::basefield);
failure () << "got: ";
failure ().setf (std::ios::hex, std::ios::basefield);
for (uint32_t j = 0; j < n; j++) {
failure () << (uint16_t)got[j] << " ";
}
failure () << std::endl;
}
return success;
bool success = true;
uint8_t *expected = array;
uint8_t *got;
got = b.peekData ();
for (uint32_t j = 0; j < n; j++) {
if (got[j] != expected[j]) {
success = false;
}
}
if (!success) {
failure () << "Buffer -- ";
failure () << "expected: n=";
failure () << n << ", ";
failure ().setf (std::ios::hex, std::ios::basefield);
for (uint32_t j = 0; j < n; j++) {
failure () << (uint16_t)expected[j] << " ";
}
failure ().setf (std::ios::dec, std::ios::basefield);
failure () << "got: ";
failure ().setf (std::ios::hex, std::ios::basefield);
for (uint32_t j = 0; j < n; j++) {
failure () << (uint16_t)got[j] << " ";
}
failure () << std::endl;
}
return success;
}
/* Note: works only when variadic macros are
@ -431,157 +431,157 @@ BufferTest::ensureWrittenBytes (Buffer b, uint32_t n, uint8_t array[])
*/
#define ENSURE_WRITTEN_BYTES(buffer, n, ...) \
{ \
uint8_t bytes[] = {__VA_ARGS__}; \
if (!ensureWrittenBytes (buffer, n , bytes)) { \
ok = false; \
} \
uint8_t bytes[] = {__VA_ARGS__}; \
if (!ensureWrittenBytes (buffer, n , bytes)) { \
ok = false; \
} \
}
bool
BufferTest::runTests (void)
{
bool ok = true;
Buffer buffer;
Buffer::Iterator i;
buffer.addAtStart (6);
i = buffer.begin ();
i.writeU8 (0x66);
ENSURE_WRITTEN_BYTES (buffer, 1, 0x66);
i = buffer.begin ();
i.writeU8 (0x67);
ENSURE_WRITTEN_BYTES (buffer, 1, 0x67);
i.writeHtonU16 (0x6568);
i = buffer.begin ();
ENSURE_WRITTEN_BYTES (buffer, 3, 0x67, 0x65, 0x68);
i.writeHtonU16 (0x6369);
ENSURE_WRITTEN_BYTES (buffer, 3, 0x63, 0x69, 0x68);
i.writeHtonU32 (0xdeadbeaf);
ENSURE_WRITTEN_BYTES (buffer, 6, 0x63, 0x69, 0xde, 0xad, 0xbe, 0xaf);
buffer.addAtStart (2);
i = buffer.begin ();
i.writeU16 (0);
ENSURE_WRITTEN_BYTES (buffer, 8, 0, 0, 0x63, 0x69, 0xde, 0xad, 0xbe, 0xaf);
buffer.addAtEnd (2);
i = buffer.begin ();
i.next (8);
i.writeU16 (0);
ENSURE_WRITTEN_BYTES (buffer, 10, 0, 0, 0x63, 0x69, 0xde, 0xad, 0xbe, 0xaf, 0, 0);
buffer.removeAtStart (3);
i = buffer.begin ();
ENSURE_WRITTEN_BYTES (buffer, 7, 0x69, 0xde, 0xad, 0xbe, 0xaf, 0, 0);
buffer.removeAtEnd (4);
i = buffer.begin ();
ENSURE_WRITTEN_BYTES (buffer, 3, 0x69, 0xde, 0xad);
buffer.addAtStart (1);
i = buffer.begin ();
i.writeU8 (0xff);
ENSURE_WRITTEN_BYTES (buffer, 4, 0xff, 0x69, 0xde, 0xad);
buffer.addAtEnd (1);
i = buffer.begin ();
i.next (4);
i.writeU8 (0xff);
i.prev (2);
uint16_t saved = i.readU16 ();
i.prev (2);
i.writeHtonU16 (0xff00);
i.prev (2);
if (i.readNtohU16 () != 0xff00) {
ok = false;
}
i.prev (2);
i.writeU16 (saved);
ENSURE_WRITTEN_BYTES (buffer, 5, 0xff, 0x69, 0xde, 0xad, 0xff);
Buffer o = buffer;
ENSURE_WRITTEN_BYTES (o, 5, 0xff, 0x69, 0xde, 0xad, 0xff);
o.addAtStart (1);
i = o.begin ();
i.writeU8 (0xfe);
ENSURE_WRITTEN_BYTES (o, 6, 0xfe, 0xff, 0x69, 0xde, 0xad, 0xff);
buffer.addAtStart (2);
i = buffer.begin ();
i.writeU8 (0xfd);
i.writeU8 (0xfd);
ENSURE_WRITTEN_BYTES (o, 6, 0xfe, 0xff, 0x69, 0xde, 0xad, 0xff);
ENSURE_WRITTEN_BYTES (buffer, 7, 0xfd, 0xfd, 0xff, 0x69, 0xde, 0xad, 0xff);
// test self-assignment
{
Buffer a = o;
a = a;
}
// test remove start.
buffer = Buffer (5);
ENSURE_WRITTEN_BYTES (buffer, 5, 0, 0, 0, 0, 0);
buffer.removeAtStart (1);
ENSURE_WRITTEN_BYTES (buffer, 4, 0, 0, 0, 0);
buffer.addAtStart (1);
buffer.begin ().writeU8 (0xff);
ENSURE_WRITTEN_BYTES (buffer, 5, 0xff, 0, 0, 0, 0);
buffer.removeAtStart(3);
ENSURE_WRITTEN_BYTES (buffer, 2, 0, 0);
buffer.addAtStart (4);
buffer.begin ().writeHtonU32 (0xdeadbeaf);
ENSURE_WRITTEN_BYTES (buffer, 6, 0xde, 0xad, 0xbe, 0xaf, 0, 0);
buffer.removeAtStart (2);
ENSURE_WRITTEN_BYTES (buffer, 4, 0xbe, 0xaf, 0, 0);
buffer.addAtEnd (4);
i = buffer.begin ();
i.next (4);
i.writeHtonU32 (0xdeadbeaf);
ENSURE_WRITTEN_BYTES (buffer, 8, 0xbe, 0xaf, 0, 0, 0xde, 0xad, 0xbe, 0xaf);
buffer.removeAtStart (5);
ENSURE_WRITTEN_BYTES (buffer, 3, 0xad, 0xbe, 0xaf);
// test remove end
buffer = Buffer (5);
ENSURE_WRITTEN_BYTES (buffer, 5, 0, 0, 0, 0, 0);
buffer.removeAtEnd (1);
ENSURE_WRITTEN_BYTES (buffer, 4, 0, 0, 0, 0);
buffer.addAtEnd (2);
i = buffer.begin ();
i.next (4);
i.writeU8 (0xab);
i.writeU8 (0xac);
ENSURE_WRITTEN_BYTES (buffer, 6, 0, 0, 0, 0, 0xab, 0xac);
buffer.removeAtEnd (1);
ENSURE_WRITTEN_BYTES (buffer, 5, 0, 0, 0, 0, 0xab);
buffer.removeAtEnd (3);
ENSURE_WRITTEN_BYTES (buffer, 2, 0, 0);
buffer.addAtEnd (6);
i = buffer.begin ();
i.next (2);
i.writeU8 (0xac);
i.writeU8 (0xad);
i.writeU8 (0xae);
i.writeU8 (0xaf);
i.writeU8 (0xba);
i.writeU8 (0xbb);
ENSURE_WRITTEN_BYTES (buffer, 8, 0, 0, 0xac, 0xad, 0xae, 0xaf, 0xba, 0xbb);
buffer.addAtStart (3);
i = buffer.begin ();
i.writeU8 (0x30);
i.writeU8 (0x31);
i.writeU8 (0x32);
ENSURE_WRITTEN_BYTES (buffer, 11, 0x30, 0x31, 0x32, 0, 0, 0xac, 0xad, 0xae, 0xaf, 0xba, 0xbb);
buffer.removeAtEnd (9);
ENSURE_WRITTEN_BYTES (buffer, 2, 0x30, 0x31);
buffer = Buffer (3);
buffer.addAtEnd (2);
i = buffer.begin ();
i.next (3);
i.writeHtonU16 (0xabcd);
buffer.addAtStart (1);
buffer.begin ().writeU8 (0x21);
ENSURE_WRITTEN_BYTES (buffer, 6, 0x21, 0, 0, 0, 0xab, 0xcd);
buffer.removeAtEnd (8);
if (buffer.getSize () != 0) {
ok = false;
}
return ok;
bool ok = true;
Buffer buffer;
Buffer::Iterator i;
buffer.addAtStart (6);
i = buffer.begin ();
i.writeU8 (0x66);
ENSURE_WRITTEN_BYTES (buffer, 1, 0x66);
i = buffer.begin ();
i.writeU8 (0x67);
ENSURE_WRITTEN_BYTES (buffer, 1, 0x67);
i.writeHtonU16 (0x6568);
i = buffer.begin ();
ENSURE_WRITTEN_BYTES (buffer, 3, 0x67, 0x65, 0x68);
i.writeHtonU16 (0x6369);
ENSURE_WRITTEN_BYTES (buffer, 3, 0x63, 0x69, 0x68);
i.writeHtonU32 (0xdeadbeaf);
ENSURE_WRITTEN_BYTES (buffer, 6, 0x63, 0x69, 0xde, 0xad, 0xbe, 0xaf);
buffer.addAtStart (2);
i = buffer.begin ();
i.writeU16 (0);
ENSURE_WRITTEN_BYTES (buffer, 8, 0, 0, 0x63, 0x69, 0xde, 0xad, 0xbe, 0xaf);
buffer.addAtEnd (2);
i = buffer.begin ();
i.next (8);
i.writeU16 (0);
ENSURE_WRITTEN_BYTES (buffer, 10, 0, 0, 0x63, 0x69, 0xde, 0xad, 0xbe, 0xaf, 0, 0);
buffer.removeAtStart (3);
i = buffer.begin ();
ENSURE_WRITTEN_BYTES (buffer, 7, 0x69, 0xde, 0xad, 0xbe, 0xaf, 0, 0);
buffer.removeAtEnd (4);
i = buffer.begin ();
ENSURE_WRITTEN_BYTES (buffer, 3, 0x69, 0xde, 0xad);
buffer.addAtStart (1);
i = buffer.begin ();
i.writeU8 (0xff);
ENSURE_WRITTEN_BYTES (buffer, 4, 0xff, 0x69, 0xde, 0xad);
buffer.addAtEnd (1);
i = buffer.begin ();
i.next (4);
i.writeU8 (0xff);
i.prev (2);
uint16_t saved = i.readU16 ();
i.prev (2);
i.writeHtonU16 (0xff00);
i.prev (2);
if (i.readNtohU16 () != 0xff00) {
ok = false;
}
i.prev (2);
i.writeU16 (saved);
ENSURE_WRITTEN_BYTES (buffer, 5, 0xff, 0x69, 0xde, 0xad, 0xff);
Buffer o = buffer;
ENSURE_WRITTEN_BYTES (o, 5, 0xff, 0x69, 0xde, 0xad, 0xff);
o.addAtStart (1);
i = o.begin ();
i.writeU8 (0xfe);
ENSURE_WRITTEN_BYTES (o, 6, 0xfe, 0xff, 0x69, 0xde, 0xad, 0xff);
buffer.addAtStart (2);
i = buffer.begin ();
i.writeU8 (0xfd);
i.writeU8 (0xfd);
ENSURE_WRITTEN_BYTES (o, 6, 0xfe, 0xff, 0x69, 0xde, 0xad, 0xff);
ENSURE_WRITTEN_BYTES (buffer, 7, 0xfd, 0xfd, 0xff, 0x69, 0xde, 0xad, 0xff);
// test self-assignment
{
Buffer a = o;
a = a;
}
// test remove start.
buffer = Buffer (5);
ENSURE_WRITTEN_BYTES (buffer, 5, 0, 0, 0, 0, 0);
buffer.removeAtStart (1);
ENSURE_WRITTEN_BYTES (buffer, 4, 0, 0, 0, 0);
buffer.addAtStart (1);
buffer.begin ().writeU8 (0xff);
ENSURE_WRITTEN_BYTES (buffer, 5, 0xff, 0, 0, 0, 0);
buffer.removeAtStart(3);
ENSURE_WRITTEN_BYTES (buffer, 2, 0, 0);
buffer.addAtStart (4);
buffer.begin ().writeHtonU32 (0xdeadbeaf);
ENSURE_WRITTEN_BYTES (buffer, 6, 0xde, 0xad, 0xbe, 0xaf, 0, 0);
buffer.removeAtStart (2);
ENSURE_WRITTEN_BYTES (buffer, 4, 0xbe, 0xaf, 0, 0);
buffer.addAtEnd (4);
i = buffer.begin ();
i.next (4);
i.writeHtonU32 (0xdeadbeaf);
ENSURE_WRITTEN_BYTES (buffer, 8, 0xbe, 0xaf, 0, 0, 0xde, 0xad, 0xbe, 0xaf);
buffer.removeAtStart (5);
ENSURE_WRITTEN_BYTES (buffer, 3, 0xad, 0xbe, 0xaf);
// test remove end
buffer = Buffer (5);
ENSURE_WRITTEN_BYTES (buffer, 5, 0, 0, 0, 0, 0);
buffer.removeAtEnd (1);
ENSURE_WRITTEN_BYTES (buffer, 4, 0, 0, 0, 0);
buffer.addAtEnd (2);
i = buffer.begin ();
i.next (4);
i.writeU8 (0xab);
i.writeU8 (0xac);
ENSURE_WRITTEN_BYTES (buffer, 6, 0, 0, 0, 0, 0xab, 0xac);
buffer.removeAtEnd (1);
ENSURE_WRITTEN_BYTES (buffer, 5, 0, 0, 0, 0, 0xab);
buffer.removeAtEnd (3);
ENSURE_WRITTEN_BYTES (buffer, 2, 0, 0);
buffer.addAtEnd (6);
i = buffer.begin ();
i.next (2);
i.writeU8 (0xac);
i.writeU8 (0xad);
i.writeU8 (0xae);
i.writeU8 (0xaf);
i.writeU8 (0xba);
i.writeU8 (0xbb);
ENSURE_WRITTEN_BYTES (buffer, 8, 0, 0, 0xac, 0xad, 0xae, 0xaf, 0xba, 0xbb);
buffer.addAtStart (3);
i = buffer.begin ();
i.writeU8 (0x30);
i.writeU8 (0x31);
i.writeU8 (0x32);
ENSURE_WRITTEN_BYTES (buffer, 11, 0x30, 0x31, 0x32, 0, 0, 0xac, 0xad, 0xae, 0xaf, 0xba, 0xbb);
buffer.removeAtEnd (9);
ENSURE_WRITTEN_BYTES (buffer, 2, 0x30, 0x31);
buffer = Buffer (3);
buffer.addAtEnd (2);
i = buffer.begin ();
i.next (3);
i.writeHtonU16 (0xabcd);
buffer.addAtStart (1);
buffer.begin ().writeU8 (0x21);
ENSURE_WRITTEN_BYTES (buffer, 6, 0x21, 0, 0, 0, 0xab, 0xcd);
buffer.removeAtEnd (8);
if (buffer.getSize () != 0) {
ok = false;
}
return ok;
}

956
src/common/buffer.h

File diff suppressed because it is too large Load Diff

78
src/common/callback-tracer.h

@ -1,4 +1,4 @@
/* -*- Mode:C++; c-basic-offset:8; tab-width:8; indent-tabs-mode:t -*- */
/* -*- Mode:C++; c-basic-offset:4; tab-width:4; indent-tabs-mode:f -*- */
/*
* Copyright (c) 2005,2006 INRIA
* All rights reserved.
@ -35,48 +35,48 @@ class CallbackTracerBase {};
* are forwarded to the internal matching ns3::Callback.
*/
template<typename T1 = empty, typename T2 = empty,
typename T3 = empty, typename T4 = empty,
typename T5 = empty>
typename T3 = empty, typename T4 = empty,
typename T5 = empty>
class CallbackTracer : public CallbackTracerBase{
public:
CallbackTracer ()
: m_callback () {}
void setCallback (Callback<void,T1,T2,T3,T4,T5> callback) {
m_callback = callback;
}
void operator() (void) {
if (!m_callback.isNull ()) {
m_callback ();
}
}
void operator() (T1 a1) {
if (!m_callback.isNull ()) {
m_callback (a1);
}
}
void operator() (T1 a1, T2 a2) {
if (!m_callback.isNull ()) {
m_callback (a1,a2);
}
}
void operator() (T1 a1, T2 a2, T3 a3) {
if (!m_callback.isNull ()) {
m_callback (a1,a2,a3);
}
}
void operator() (T1 a1, T2 a2, T3 a3, T4 a4) {
if (!m_callback.isNull ()) {
m_callback (a1,a2,a3,a4);
}
}
void operator() (T1 a1, T2 a2, T3 a3, T4 a4,T5 a5) {
if (!m_callback.isNull ()) {
m_callback (a1,a2,a3,a4,a5);
}
}
CallbackTracer ()
: m_callback () {}
void setCallback (Callback<void,T1,T2,T3,T4,T5> callback) {
m_callback = callback;
}
void operator() (void) {
if (!m_callback.isNull ()) {
m_callback ();
}
}
void operator() (T1 a1) {
if (!m_callback.isNull ()) {
m_callback (a1);
}
}
void operator() (T1 a1, T2 a2) {
if (!m_callback.isNull ()) {
m_callback (a1,a2);
}
}
void operator() (T1 a1, T2 a2, T3 a3) {
if (!m_callback.isNull ()) {
m_callback (a1,a2,a3);
}
}
void operator() (T1 a1, T2 a2, T3 a3, T4 a4) {
if (!m_callback.isNull ()) {
m_callback (a1,a2,a3,a4);
}
}
void operator() (T1 a1, T2 a2, T3 a3, T4 a4,T5 a5) {
if (!m_callback.isNull ()) {
m_callback (a1,a2,a3,a4,a5);
}
}
private:
Callback<void,T1,T2,T3,T4,T5> m_callback;
Callback<void,T1,T2,T3,T4,T5> m_callback;
};
}; // namespace ns3

20
src/common/chunk-constant-data.cc

@ -1,4 +1,4 @@
/* -*- Mode:C++; c-basic-offset:8; tab-width:8; indent-tabs-mode:t -*- */
/* -*- Mode:C++; c-basic-offset:4; tab-width:4; indent-tabs-mode:f -*- */
/*
* Copyright (c) 2005 INRIA
* All rights reserved.
@ -24,7 +24,7 @@
namespace ns3 {
ChunkConstantData::ChunkConstantData (uint32_t len, uint8_t data)
: m_len (len), m_data (data)
: m_len (len), m_data (data)
{}
ChunkConstantData::~ChunkConstantData ()
@ -34,29 +34,29 @@ ChunkConstantData::~ChunkConstantData ()
void
ChunkConstantData::print (std::ostream *os) const
{
*os << "(constant data)"
<< " len=" << m_len
<< ", data=" << m_data;
*os << "(constant data)"
<< " len=" << m_len
<< ", data=" << m_data;
}
void
ChunkConstantData::addTo (Buffer *buffer) const
{
buffer->addAtStart (m_len);
buffer->addAtStart (m_len);
#ifndef NDEBUG
buffer->begin ().writeU8 (m_data, m_len);
buffer->begin ().writeU8 (m_data, m_len);
#endif
}
void
ChunkConstantData::peekFrom (Buffer const *buffer)
{
m_len = buffer->getSize ();
m_data = buffer->begin ().readU8 ();
m_len = buffer->getSize ();
m_data = buffer->begin ().readU8 ();
}
void
ChunkConstantData::removeFrom (Buffer *buffer)
{
buffer->removeAtStart (m_len);
buffer->removeAtStart (m_len);
}

18
src/common/chunk-constant-data.h

@ -1,4 +1,4 @@
/* -*- Mode:C++; c-basic-offset:8; tab-width:8; indent-tabs-mode:t -*- */
/* -*- Mode:C++; c-basic-offset:4; tab-width:4; indent-tabs-mode:f -*- */
/*
* Copyright (c) 2005 INRIA
* All rights reserved.
@ -30,16 +30,16 @@ namespace ns3 {
class ChunkConstantData : public Chunk {
public:
ChunkConstantData (uint32_t len, uint8_t data);
~ChunkConstantData ();
ChunkConstantData (uint32_t len, uint8_t data);
~ChunkConstantData ();
private:
virtual void print (std::ostream *os) const;
virtual void addTo (Buffer *buffer) const;
virtual void peekFrom (Buffer const *buffer);
virtual void removeFrom (Buffer *buffer);
uint32_t m_len;
uint8_t m_data;
virtual void print (std::ostream *os) const;
virtual void addTo (Buffer *buffer) const;
virtual void peekFrom (Buffer const *buffer);
virtual void removeFrom (Buffer *buffer);
uint32_t m_len;
uint8_t m_data;
};
}; // namespace ns3

22
src/common/chunk.cc

@ -1,4 +1,4 @@
/* -*- Mode:C++; c-basic-offset:8; tab-width:8; indent-tabs-mode:t -*- */
/* -*- Mode:C++; c-basic-offset:4; tab-width:4; indent-tabs-mode:f -*- */
/*
* Copyright (c) 2005 INRIA
* All rights reserved.
@ -25,30 +25,30 @@
namespace ns3 {
Chunk::Chunk ()
: m_mustPeekBeforeRemove (false) {}
: m_mustPeekBeforeRemove (false) {}
void
Chunk::print (std::ostream &os) const
{
print (&os);
print (&os);
}
void
Chunk::add (Buffer *buffer) const
{
addTo (buffer);
addTo (buffer);
}
void
Chunk::peek (Buffer const *buffer)
{
peekFrom (buffer);
m_mustPeekBeforeRemove = true;
peekFrom (buffer);
m_mustPeekBeforeRemove = true;
}
void
Chunk::remove (Buffer *buffer)
{
assert (m_mustPeekBeforeRemove);
removeFrom (buffer);
m_mustPeekBeforeRemove = false;
assert (m_mustPeekBeforeRemove);
removeFrom (buffer);
m_mustPeekBeforeRemove = false;
}
@ -58,8 +58,8 @@ Chunk::~Chunk ()
std::ostream& operator<< (std::ostream& os, Chunk const& chunk)
{
chunk.print (os);
return os;
chunk.print (os);
return os;
}
}; // namespace ns3

80
src/common/chunk.h

@ -1,4 +1,4 @@
/* -*- Mode:C++; c-basic-offset:8; tab-width:8; indent-tabs-mode:t -*- */
/* -*- Mode:C++; c-basic-offset:4; tab-width:4; indent-tabs-mode:f -*- */
/*
* Copyright (c) 2005 INRIA
* All rights reserved.
@ -37,49 +37,49 @@ namespace ns3 {
*/
class Chunk {
public:
Chunk ();
/**
* Derived classes must provided an explicit virtual destructor
*/
virtual ~Chunk () = 0;
Chunk ();
/**
* Derived classes must provided an explicit virtual destructor
*/
virtual ~Chunk () = 0;
void print (std::ostream &os) const;
void print (std::ostream &os) const;
void add (Buffer *buffer) const;
void peek (Buffer const *buffer);
void remove (Buffer *buffer);
void add (Buffer *buffer) const;
void peek (Buffer const *buffer);
void remove (Buffer *buffer);
private:
bool m_mustPeekBeforeRemove;
/**
* \param os the std output stream in which this
* protocol header must print itself.
*/
virtual void print (std::ostream *os) const = 0;
bool m_mustPeekBeforeRemove;
/**
* \param os the std output stream in which this
* protocol header must print itself.
*/
virtual void print (std::ostream *os) const = 0;
/**
* \param buffer the buffer in which the protocol header
* must serialize itself.
*
* This method must:
* - reserve room for its serialized representation in the input buffer
* - serialize itself in this reserved room
*/
virtual void addTo (Buffer *buffer) const = 0;
/**
* \param buffer the buffer from which the protocol header must
* deserialize itself.
*
*/
virtual void peekFrom (Buffer const *buffer) = 0;
/**
* \param buffer the buffer from which the protocol header
* must remove itself.
*
* This method must remove its serialized representation
* from the input buffer. This method does not need to deserialize
* the data itself.
*/
virtual void removeFrom (Buffer *buffer) = 0;
/**
* \param buffer the buffer in which the protocol header
* must serialize itself.
*
* This method must:
* - reserve room for its serialized representation in the input buffer
* - serialize itself in this reserved room
*/
virtual void addTo (Buffer *buffer) const = 0;
/**
* \param buffer the buffer from which the protocol header must
* deserialize itself.
*
*/
virtual void peekFrom (Buffer const *buffer) = 0;
/**
* \param buffer the buffer from which the protocol header
* must remove itself.
*
* This method must remove its serialized representation
* from the input buffer. This method does not need to deserialize
* the data itself.
*/
virtual void removeFrom (Buffer *buffer) = 0;
};
std::ostream& operator<< (std::ostream& os, Chunk const& chunk);

62
src/common/data-writer.cc

@ -1,4 +1,4 @@
/* -*- Mode:C++; c-basic-offset:8; tab-width:8; indent-tabs-mode:t -*- */
/* -*- Mode:C++; c-basic-offset:4; tab-width:4; indent-tabs-mode:f -*- */
/*
* Copyright (c) 2005 INRIA
* All rights reserved.
@ -46,32 +46,32 @@ namespace ns3 {
class DataWriterPrivate {
public:
DataWriterPrivate ();
~DataWriterPrivate ();
DataWriterPrivate ();
~DataWriterPrivate ();
void open (char const *filename);
void write (uint8_t *buffer, uint32_t size);
void open (char const *filename);
void write (uint8_t *buffer, uint32_t size);
private:
uint8_t m_data[BUFFER_SIZE];
uint32_t m_current;
int m_fd;
uint8_t m_data[BUFFER_SIZE];
uint32_t m_current;
int m_fd;
};
DataWriterPrivate::DataWriterPrivate ()
: m_current (0)
: m_current (0)
{}
DataWriterPrivate::~DataWriterPrivate ()
{
::write (m_fd, m_data, m_current);
::close (m_fd);
::write (m_fd, m_data, m_current);
::close (m_fd);
}
void
DataWriterPrivate::open (char const *filename)
{
m_fd = ::open (filename, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR);
assert (m_fd != -1);
m_fd = ::open (filename, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR);
assert (m_fd != -1);
}
#ifndef min
@ -81,39 +81,39 @@ DataWriterPrivate::open (char const *filename)
void
DataWriterPrivate::write (uint8_t *buffer, uint32_t size)
{
while (size > 0) {
uint32_t toCopy = min (BUFFER_SIZE - m_current, size);
memcpy (m_data + m_current, buffer, toCopy);
size -= toCopy;
m_current += toCopy;
buffer += toCopy;
if (m_current == BUFFER_SIZE) {
ssize_t written = 0;
written = ::write (m_fd, m_data, BUFFER_SIZE);
assert (written == BUFFER_SIZE);
m_current = 0;
}
}
while (size > 0) {
uint32_t toCopy = min (BUFFER_SIZE - m_current, size);
memcpy (m_data + m_current, buffer, toCopy);
size -= toCopy;
m_current += toCopy;
buffer += toCopy;
if (m_current == BUFFER_SIZE) {
ssize_t written = 0;
written = ::write (m_fd, m_data, BUFFER_SIZE);
assert (written == BUFFER_SIZE);
m_current = 0;
}
}
}
DataWriter::DataWriter ()
: m_priv (new DataWriterPrivate ())
: m_priv (new DataWriterPrivate ())
{}
DataWriter::~DataWriter ()
{
delete m_priv;
m_priv = 0;
delete m_priv;
m_priv = 0;
}
void
DataWriter::open (char const *filename)
{
m_priv->open (filename);
m_priv->open (filename);
}
void
DataWriter::write (uint8_t *buffer, uint32_t size)
{
m_priv->write (buffer, size);
m_priv->write (buffer, size);
}
}; // namespace

12
src/common/data-writer.h

@ -1,4 +1,4 @@
/* -*- Mode:C++; c-basic-offset:8; tab-width:8; indent-tabs-mode:t -*- */
/* -*- Mode:C++; c-basic-offset:4; tab-width:4; indent-tabs-mode:f -*- */
/*
* Copyright (c) 2005 INRIA
* All rights reserved.
@ -30,13 +30,13 @@ class DataWriterPrivate;
class DataWriter {
public:
DataWriter ();
~DataWriter ();
DataWriter ();
~DataWriter ();
void open (char const *filename);
void write (uint8_t *buffer, uint32_t size);
void open (char const *filename);
void write (uint8_t *buffer, uint32_t size);
private:
DataWriterPrivate *m_priv;
DataWriterPrivate *m_priv;
};
}; //namespace ns3

34
src/common/f-variable-tracer.h

@ -1,4 +1,4 @@
/* -*- Mode:C++; c-basic-offset:8; tab-width:8; indent-tabs-mode:t -*- */
/* -*- Mode:C++; c-basic-offset:4; tab-width:4; indent-tabs-mode:f -*- */
/*
* Copyright (c) 2006 INRIA
* All rights reserved.
@ -29,27 +29,27 @@ namespace ns3 {
class FVariableTracerBase {
public:
typedef Callback<void,double, double> ChangeNotifyCallback;
typedef Callback<void,double, double> ChangeNotifyCallback;
FVariableTracerBase () {}
FVariableTracerBase (FVariableTracerBase const &o) {}
FVariableTracerBase &operator = (FVariableTracerBase const &o) {
return *this;
}
FVariableTracerBase () {}
FVariableTracerBase (FVariableTracerBase const &o) {}
FVariableTracerBase &operator = (FVariableTracerBase const &o) {
return *this;
}
~FVariableTracerBase () {}
~FVariableTracerBase () {}
void setCallback(ChangeNotifyCallback callback) {
m_callback = callback;
}
void setCallback(ChangeNotifyCallback callback) {
m_callback = callback;
}
protected:
void notify (double oldVal, double newVal) {
if (oldVal != newVal && !m_callback.isNull ()) {
m_callback (oldVal, newVal);
}
}
void notify (double oldVal, double newVal) {
if (oldVal != newVal && !m_callback.isNull ()) {
m_callback (oldVal, newVal);
}
}
private:
ChangeNotifyCallback m_callback;
ChangeNotifyCallback m_callback;
};

80
src/common/packet.cc

@ -1,4 +1,4 @@
/* -*- Mode:C++; c-basic-offset:8; tab-width:8; indent-tabs-mode:t -*- */
/* -*- Mode:C++; c-basic-offset:4; tab-width:4; indent-tabs-mode:f -*- */
/*
* Copyright (c) 2005,2006 INRIA
* All rights reserved.
@ -24,104 +24,104 @@
namespace ns3 {
Packet::Packet ()
: m_buffer () {}
: m_buffer () {}
Packet::Packet (uint32_t size)
: m_buffer (size)
: m_buffer (size)
{}
Packet::Packet (Buffer buffer, Tags tags)
: m_buffer (buffer),
m_tags (tags)
: m_buffer (buffer),
m_tags (tags)
{}
Packet
Packet::createFragment (uint32_t start, uint32_t length) const
{
Buffer tmp = m_buffer.createFragment (start, length);
return Packet (tmp, m_tags);
Buffer tmp = m_buffer.createFragment (start, length);
return Packet (tmp, m_tags);
}
uint32_t
Packet::getSize (void) const
{
return m_buffer.getSize ();
return m_buffer.getSize ();
}
void
Packet::add (Chunk *chunk)
{
chunk->add (&m_buffer);
chunk->add (&m_buffer);
}
void
Packet::peek (Chunk *chunk) const
{
chunk->peek (&m_buffer);
chunk->peek (&m_buffer);
}
void
Packet::remove (Chunk *chunk)
{
chunk->remove (&m_buffer);
chunk->remove (&m_buffer);
}
void
Packet::write (PacketReadWriteCallback callback) const
{
uint8_t *data = m_buffer.peekData ();
uint32_t toWrite = getSize ();
callback (data, toWrite);
uint8_t *data = m_buffer.peekData ();
uint32_t toWrite = getSize ();
callback (data, toWrite);
}
void
Packet::addAtEnd (Packet packet)
{
Buffer src = packet.m_buffer;
m_buffer.addAtEnd (src.getSize ());
Buffer::Iterator destStart = m_buffer.end ();
destStart.prev (src.getSize ());
destStart.write (src.begin (), src.end ());
/**
* XXX: we might need to merge the tag list of the
* other packet into the current packet.
*/
Buffer src = packet.m_buffer;
m_buffer.addAtEnd (src.getSize ());
Buffer::Iterator destStart = m_buffer.end ();
destStart.prev (src.getSize ());
destStart.write (src.begin (), src.end ());
/**
* XXX: we might need to merge the tag list of the
* other packet into the current packet.
*/
}
void
Packet::addAtEnd (Packet packet, uint32_t start, uint32_t size)
{
assert (packet.getSize () <= start + size);
Buffer src = packet.m_buffer;
m_buffer.addAtEnd (src.getSize ());
Buffer::Iterator destStart = m_buffer.end ();
destStart.prev (size);
Buffer::Iterator srcStart = src.begin ();
srcStart.next (start);
Buffer::Iterator srcEnd = srcStart;
srcEnd.next (size);
destStart.write (srcStart, srcEnd);
/**
* XXX: we might need to merge the tag list of the
* other packet into the current packet.
*/
assert (packet.getSize () <= start + size);
Buffer src = packet.m_buffer;
m_buffer.addAtEnd (src.getSize ());
Buffer::Iterator destStart = m_buffer.end ();
destStart.prev (size);
Buffer::Iterator srcStart = src.begin ();
srcStart.next (start);
Buffer::Iterator srcEnd = srcStart;
srcEnd.next (size);
destStart.write (srcStart, srcEnd);
/**
* XXX: we might need to merge the tag list of the
* other packet into the current packet.
*/
}
void
Packet::removeAtEnd (uint32_t size)
{
m_buffer.removeAtEnd (size);
m_buffer.removeAtEnd (size);
}
void
Packet::removeAtStart (uint32_t size)
{
m_buffer.removeAtStart (size);
m_buffer.removeAtStart (size);
}
void
Packet::removeAllTags (void)
{
m_tags.removeAll ();
m_tags.removeAll ();
}
}; // namespace ns3

60
src/common/packet.h

@ -1,4 +1,4 @@
/* -*- Mode:C++; c-basic-offset:8; tab-width:8; indent-tabs-mode:t -*- */
/* -*- Mode:C++; c-basic-offset:4; tab-width:4; indent-tabs-mode:f -*- */
/*
* Copyright (c) 2005,2006 INRIA
* All rights reserved.
@ -31,33 +31,33 @@ namespace ns3 {
class Packet {
public:
typedef Callback<void,uint8_t *,uint32_t> PacketReadWriteCallback;
Packet ();
Packet (uint32_t size);
Packet createFragment (uint32_t start, uint32_t length) const;
uint32_t getSize (void) const;
void add (Chunk *chunk);
void peek (Chunk *chunk) const;
void remove (Chunk *chunk);
template <typename T>
void addTag (T const *tag);
template <typename T>
bool removeTag (T *tag);
template <typename T>
bool peekTag (T *tag) const;
template <typename T>
bool updateTag (T const*tag);
void removeAllTags (void);
void write (PacketReadWriteCallback callback) const;
void addAtEnd (Packet packet);
void addAtEnd (Packet packet, uint32_t offset, uint32_t size);
void removeAtEnd (uint32_t size);
void removeAtStart (uint32_t size);
typedef Callback<void,uint8_t *,uint32_t> PacketReadWriteCallback;
Packet ();
Packet (uint32_t size);
Packet createFragment (uint32_t start, uint32_t length) const;
uint32_t getSize (void) const;
void add (Chunk *chunk);
void peek (Chunk *chunk) const;
void remove (Chunk *chunk);
template <typename T>
void addTag (T const *tag);
template <typename T>
bool removeTag (T *tag);
template <typename T>
bool peekTag (T *tag) const;
template <typename T>
bool updateTag (T const*tag);
void removeAllTags (void);
void write (PacketReadWriteCallback callback) const;
void addAtEnd (Packet packet);
void addAtEnd (Packet packet, uint32_t offset, uint32_t size);
void removeAtEnd (uint32_t size);
void removeAtStart (uint32_t size);
private:
Packet (Buffer buffer, Tags tags);
Buffer m_buffer;
Tags m_tags;
Packet (Buffer buffer, Tags tags);
Buffer m_buffer;
Tags m_tags;
};
}; // namespace ns3
@ -67,22 +67,22 @@ namespace ns3 {
template <typename T>
void Packet::addTag (T const*tag)
{
m_tags.add (tag);
m_tags.add (tag);
}
template <typename T>
bool Packet::removeTag (T *tag)
{
return m_tags.remove (tag);
return m_tags.remove (tag);
}
template <typename T>
bool Packet::peekTag (T *tag) const
{
return m_tags.peek (tag);
return m_tags.peek (tag);
}
template <typename T>
bool Packet::updateTag (T const*tag)
{
return m_tags.update (tag);
return m_tags.update (tag);
}
}; // namespace ns3

54
src/common/pcap-writer.cc

@ -1,4 +1,4 @@
/* -*- Mode:C++; c-basic-offset:8; tab-width:8; indent-tabs-mode:t -*- */
/* -*- Mode:C++; c-basic-offset:4; tab-width:4; indent-tabs-mode:f -*- */
/*
* Copyright (c) 2005,2006 INRIA
* All rights reserved.
@ -33,67 +33,67 @@
namespace ns3 {
enum {
PCAP_ETHERNET = 1
PCAP_ETHERNET = 1
};
PcapWriter::PcapWriter ()
{
m_writer = 0;
m_writeCallback = makeCallback (&PcapWriter::writeData, this);
m_writer = 0;
m_writeCallback = makeCallback (&PcapWriter::writeData, this);
}
PcapWriter::~PcapWriter ()
{
delete m_writer;
delete m_writer;
}
void
PcapWriter::open (char const *name)
{
m_writer = new SystemFile ();
m_writer->open (name);
m_writer = new SystemFile ();
m_writer->open (name);
}
void
PcapWriter::writeHeaderEthernet (void)
{
write_32 (0xa1b2c3d4);
write_16 (2);
write_16 (4);
write_32 (0);
write_32 (0);
write_32 (0xffff);
write_32 (PCAP_ETHERNET);
write_32 (0xa1b2c3d4);
write_16 (2);
write_16 (4);
write_32 (0);
write_32 (0);
write_32 (0xffff);
write_32 (PCAP_ETHERNET);
}
void
PcapWriter::writePacket (Packet const packet)
{
if (m_writer != 0) {
uint64_t current = Simulator::now ().us ();
uint64_t s = current / 1000000;
uint64_t us = current % 1000000;
write_32 (s & 0xffffffff);
write_32 (us & 0xffffffff);
write_32 (packet.getSize ());
write_32 (packet.getSize ());
packet.write (m_writeCallback);
}
if (m_writer != 0) {
uint64_t current = Simulator::now ().us ();
uint64_t s = current / 1000000;
uint64_t us = current % 1000000;
write_32 (s & 0xffffffff);
write_32 (us & 0xffffffff);
write_32 (packet.getSize ());
write_32 (packet.getSize ());
packet.write (m_writeCallback);
}
}
void
PcapWriter::writeData (uint8_t *buffer, uint32_t size)
{
m_writer->write (buffer, size);
m_writer->write (buffer, size);
}
void
PcapWriter::write_32 (uint32_t data)
{
m_writer->write ((uint8_t*)&data, 4);
m_writer->write ((uint8_t*)&data, 4);
}
void
PcapWriter::write_16 (uint16_t data)
{
m_writer->write ((uint8_t*)&data, 2);
m_writer->write ((uint8_t*)&data, 2);
}
}; // namespace ns3

48
src/common/pcap-writer.h

@ -1,4 +1,4 @@
/* -*- Mode:C++; c-basic-offset:8; tab-width:8; indent-tabs-mode:t -*- */
/* -*- Mode:C++; c-basic-offset:4; tab-width:4; indent-tabs-mode:f -*- */
/*
* Copyright (c) 2005,2006 INRIA
* All rights reserved.
@ -38,34 +38,34 @@ class SystemFile;
*/
class PcapWriter {
public:
PcapWriter ();
~PcapWriter ();
PcapWriter ();
~PcapWriter ();
/**
* \param name the name of the file to store packet log into.
* This method creates the file if it does not exist. If it
* exists, the file is emptied.
*/
void open (char const *name);
/**
* \param name the name of the file to store packet log into.
* This method creates the file if it does not exist. If it
* exists, the file is emptied.
*/
void open (char const *name);
/**
* Write a pcap header in the output file which specifies
* that the content of the file will Packets with
* Ethernet/LLC/SNAP encapsulation.
*/
void writeHeaderEthernet (void);
/**
* Write a pcap header in the output file which specifies
* that the content of the file will Packets with
* Ethernet/LLC/SNAP encapsulation.
*/
void writeHeaderEthernet (void);
/**
* \param packet packet to write to output file
*/
void writePacket (Packet const packet);
/**
* \param packet packet to write to output file
*/
void writePacket (Packet const packet);
private:
void writeData (uint8_t *buffer, uint32_t size);
void write_32 (uint32_t data);
void write_16 (uint16_t data);
SystemFile *m_writer;
Callback<void,uint8_t *,uint32_t> m_writeCallback;
void writeData (uint8_t *buffer, uint32_t size);
void write_32 (uint32_t data);
void write_16 (uint16_t data);
SystemFile *m_writer;
Callback<void,uint8_t *,uint32_t> m_writeCallback;
};
}; // namespace ns3

210
src/common/si-variable-tracer.h

@ -1,4 +1,4 @@
/* -*- Mode:C++; c-basic-offset:8; tab-width:8; indent-tabs-mode:t -*- */
/* -*- Mode:C++; c-basic-offset:4; tab-width:4; indent-tabs-mode:f -*- */
/*
* Copyright (c) 2006 INRIA
* All rights reserved.
@ -29,27 +29,27 @@ namespace ns3 {
class SiVariableTracerBase {
public:
typedef Callback<void,int64_t, int64_t> ChangeNotifyCallback;
typedef Callback<void,int64_t, int64_t> ChangeNotifyCallback;
SiVariableTracerBase () {}
SiVariableTracerBase (SiVariableTracerBase const &o) {}
SiVariableTracerBase &operator = (SiVariableTracerBase const &o) {
return *this;
}
SiVariableTracerBase () {}
SiVariableTracerBase (SiVariableTracerBase const &o) {}
SiVariableTracerBase &operator = (SiVariableTracerBase const &o) {
return *this;
}
~SiVariableTracerBase () {}
~SiVariableTracerBase () {}
void setCallback(ChangeNotifyCallback callback) {
m_callback = callback;
}
void setCallback(ChangeNotifyCallback callback) {
m_callback = callback;
}
protected:
void notify (int64_t oldVal, int64_t newVal) {
if (oldVal != newVal && !m_callback.isNull ()) {
m_callback (oldVal, newVal);
}
}
void notify (int64_t oldVal, int64_t newVal) {
if (oldVal != newVal && !m_callback.isNull ()) {
m_callback (oldVal, newVal);
}
}
private:
ChangeNotifyCallback m_callback;
ChangeNotifyCallback m_callback;
};
template <typename T>
@ -83,153 +83,153 @@ class UiVariableTracer;
template <typename T>
class SiVariableTracer : public SiVariableTracerBase {
public:
SiVariableTracer ()
: m_var (0)
{}
SiVariableTracer (T const &var)
: m_var (var)
{}
SiVariableTracer &operator = (SiVariableTracer const &o) {
assign (o.get ());
return *this;
}
template <typename TT>
SiVariableTracer &operator = (SiVariableTracer<TT> const &o) {
assign (o.get ());
return *this;
}
template <typename TT>
SiVariableTracer &operator = (UiVariableTracer<TT> const &o) {
assign (o.get ());
return *this;
}
SiVariableTracer &operator++ () {
assign (get () + 1);
return *this;
}
SiVariableTracer &operator-- () {
assign (get () - 1);
return *this;
}
SiVariableTracer operator++ (int) {
SiVariableTracer old (*this);
++*this;
return old;
}
SiVariableTracer operator-- (int) {
SiVariableTracer old (*this);
--*this;
return old;
}
operator T () const {
return get ();
}
void assign (T var) {
notify (m_var, var);
m_var = var;
}
T get (void) const {
return m_var;
}
SiVariableTracer ()
: m_var (0)
{}
SiVariableTracer (T const &var)
: m_var (var)
{}
SiVariableTracer &operator = (SiVariableTracer const &o) {
assign (o.get ());
return *this;
}
template <typename TT>
SiVariableTracer &operator = (SiVariableTracer<TT> const &o) {
assign (o.get ());
return *this;
}
template <typename TT>
SiVariableTracer &operator = (UiVariableTracer<TT> const &o) {
assign (o.get ());
return *this;
}
SiVariableTracer &operator++ () {
assign (get () + 1);
return *this;
}
SiVariableTracer &operator-- () {
assign (get () - 1);
return *this;
}
SiVariableTracer operator++ (int) {
SiVariableTracer old (*this);
++*this;
return old;
}
SiVariableTracer operator-- (int) {
SiVariableTracer old (*this);
--*this;
return old;
}
operator T () const {
return get ();
}
void assign (T var) {
notify (m_var, var);
m_var = var;
}
T get (void) const {
return m_var;
}
private:
T m_var;
T m_var;
};
template <typename T>
SiVariableTracer<T> &operator += (SiVariableTracer<T> &lhs, SiVariableTracer<T> const &rhs) {
lhs.assign (lhs.get () + rhs.get ());
return lhs;
lhs.assign (lhs.get () + rhs.get ());
return lhs;
}
template <typename T>
SiVariableTracer<T> &operator -= (SiVariableTracer<T> &lhs, SiVariableTracer<T> const &rhs) {
lhs.assign (lhs.get () - rhs.get ());
return lhs;
lhs.assign (lhs.get () - rhs.get ());
return lhs;
}
template <typename T>
SiVariableTracer<T> &operator *= (SiVariableTracer<T> &lhs, SiVariableTracer<T> const &rhs) {
lhs.assign (lhs.get () * rhs.get ());
return lhs;
lhs.assign (lhs.get () * rhs.get ());
return lhs;
}
template <typename T>
SiVariableTracer<T> &operator /= (SiVariableTracer<T> &lhs, SiVariableTracer<T> const &rhs) {
lhs.assign (lhs.get () / rhs.get ());
return lhs;
lhs.assign (lhs.get () / rhs.get ());
return lhs;
}
template <typename T>
SiVariableTracer<T> &operator <<= (SiVariableTracer<T> &lhs, SiVariableTracer<T> const &rhs) {
lhs.assign (lhs.get () << rhs.get ());
return lhs;
lhs.assign (lhs.get () << rhs.get ());
return lhs;
}
template <typename T>
SiVariableTracer<T> &operator >>= (SiVariableTracer<T> &lhs, SiVariableTracer<T> const &rhs) {
lhs.assign (lhs.get () >> rhs.get ());
return lhs;
lhs.assign (lhs.get () >> rhs.get ());
return lhs;
}
template <typename T>
SiVariableTracer<T> &operator &= (SiVariableTracer<T> &lhs, SiVariableTracer<T> const &rhs) {
lhs.assign (lhs.get () & rhs.get ());
return lhs;
lhs.assign (lhs.get () & rhs.get ());
return lhs;
}
template <typename T>
SiVariableTracer<T> &operator |= (SiVariableTracer<T> &lhs, SiVariableTracer<T> const &rhs) {
lhs.assign (lhs.get () | rhs.get ());
return lhs;
lhs.assign (lhs.get () | rhs.get ());
return lhs;
}
template <typename T>
SiVariableTracer<T> &operator ^= (SiVariableTracer<T> &lhs, SiVariableTracer<T> const &rhs) {
lhs.assign (lhs.get () ^ rhs.get ());
return lhs;
lhs.assign (lhs.get () ^ rhs.get ());
return lhs;
}
template <typename T, typename U>
SiVariableTracer<T> &operator += (SiVariableTracer<T> &lhs, U const &rhs) {
lhs.assign (lhs.get () + rhs);
return lhs;
lhs.assign (lhs.get () + rhs);
return lhs;
}
template <typename T, typename U>
SiVariableTracer<T> &operator -= (SiVariableTracer<T> &lhs, U const &rhs) {
lhs.assign (lhs.get () - rhs);
return lhs;
lhs.assign (lhs.get () - rhs);
return lhs;
}
template <typename T, typename U>
SiVariableTracer<T> &operator *= (SiVariableTracer<T> &lhs, U const &rhs) {
lhs.assign (lhs.get () * rhs);
return lhs;
lhs.assign (lhs.get () * rhs);
return lhs;
}
template <typename T, typename U>
SiVariableTracer<T> &operator /= (SiVariableTracer<T> &lhs, U const &rhs) {
lhs.assign (lhs.get () / rhs);
return lhs;
lhs.assign (lhs.get () / rhs);
return lhs;
}
template <typename T, typename U>
SiVariableTracer<T> &operator <<= (SiVariableTracer<T> &lhs, U const &rhs) {
lhs.assign (lhs.get () << rhs);
return lhs;
lhs.assign (lhs.get () << rhs);
return lhs;
}
template <typename T, typename U>
SiVariableTracer<T> &operator >>= (SiVariableTracer<T> &lhs, U const &rhs) {
lhs.assign (lhs.get () >> rhs);
return lhs;
lhs.assign (lhs.get () >> rhs);
return lhs;
}
template <typename T, typename U>
SiVariableTracer<T> &operator &= (SiVariableTracer<T> &lhs, U const &rhs) {
lhs.assign (lhs.get () & rhs);
return lhs;
lhs.assign (lhs.get () & rhs);
return lhs;
}
template <typename T, typename U>
SiVariableTracer<T> &operator |= (SiVariableTracer<T> &lhs, U const &rhs) {
lhs.assign (lhs.get () | rhs);
return lhs;
lhs.assign (lhs.get () | rhs);
return lhs;
}
template <typename T, typename U>
SiVariableTracer<T> &operator ^= (SiVariableTracer<T> &lhs, U const &rhs) {
lhs.assign (lhs.get () ^ rhs);
return lhs;
lhs.assign (lhs.get () ^ rhs);
return lhs;
}
}; // namespace ns3

46
src/common/stream-tracer-test.cc

@ -1,4 +1,4 @@
/* -*- Mode:C++; c-basic-offset:8; tab-width:8; indent-tabs-mode:t -*- */
/* -*- Mode:C++; c-basic-offset:4; tab-width:4; indent-tabs-mode:f -*- */
/*
* Copyright (c) 2006 INRIA
* All rights reserved.
@ -28,38 +28,38 @@ namespace {
class TestStreamTracer : public ns3::Test {
public:
TestStreamTracer ();
virtual bool runTests (void);
TestStreamTracer ();
virtual bool runTests (void);
};
static TestStreamTracer gTestStream;
TestStreamTracer::TestStreamTracer ()
: Test ("StreamTracer")
: Test ("StreamTracer")
{}
bool
TestStreamTracer::runTests (void)
{
bool ok = true;
ns3::StreamTracer trace;
//trace.setStream (&std::cout);
trace << 1;
trace << " X ";
trace << 1.0;
trace << std::endl;
trace << "test ";
trace << 1 << " test";
trace << "test "
<< 1.0 << " "
<< 0xdeadbead
<< std::endl;
trace << "0x" << std::hex
<< 0xdeadbeaf
<< std::dec << " "
<< 0xdeadbeaf
<< std::endl;
return ok;
bool ok = true;
ns3::StreamTracer trace;
//trace.setStream (&std::cout);
trace << 1;
trace << " X ";
trace << 1.0;
trace << std::endl;
trace << "test ";
trace << 1 << " test";
trace << "test "
<< 1.0 << " "
<< 0xdeadbead
<< std::endl;
trace << "0x" << std::hex
<< 0xdeadbeaf
<< std::dec << " "
<< 0xdeadbeaf
<< std::endl;
return ok;
}

60
src/common/stream-tracer.h

@ -1,4 +1,4 @@
/* -*- Mode:C++; c-basic-offset:8; tab-width:8; indent-tabs-mode:t -*- */
/* -*- Mode:C++; c-basic-offset:4; tab-width:4; indent-tabs-mode:f -*- */
/*
* Copyright (c) 2006 INRIA
* All rights reserved.
@ -34,37 +34,37 @@ namespace ns3 {
*/
class StreamTracer {
public:
StreamTracer ()
: m_os (0) {}
template <typename T>
StreamTracer &operator << (T const&v) {
if (m_os != 0) {
(*m_os) << v;
}
return *this;
}
template <typename T>
StreamTracer &operator << (T &v) {
if (m_os != 0) {
(*m_os) << v;
}
return *this;
}
StreamTracer &operator << (std::ostream &(*v) (std::ostream &)) {
if (m_os != 0) {
(*m_os) << v;
}
return *this;
}
StreamTracer ()
: m_os (0) {}
template <typename T>
StreamTracer &operator << (T const&v) {
if (m_os != 0) {
(*m_os) << v;
}
return *this;
}
template <typename T>
StreamTracer &operator << (T &v) {
if (m_os != 0) {
(*m_os) << v;
}
return *this;
}
StreamTracer &operator << (std::ostream &(*v) (std::ostream &)) {
if (m_os != 0) {
(*m_os) << v;
}
return *this;
}
/**
* \param os the output stream to store
*/
void setStream (std::ostream * os) {
m_os = os;
}
/**
* \param os the output stream to store
*/
void setStream (std::ostream * os) {
m_os = os;
}
private:
std::ostream *m_os;
std::ostream *m_os;
};
}; // namespace ns3

356
src/common/tags.cc

@ -1,4 +1,4 @@
/* -*- Mode:C++; c-basic-offset:8; tab-width:8; indent-tabs-mode:t -*- */
/* -*- Mode:C++; c-basic-offset:4; tab-width:4; indent-tabs-mode:f -*- */
/*
* Copyright (c) 2006 INRIA
* All rights reserved.
@ -28,30 +28,30 @@ TagsPrettyPrinterRegistry::PrettyPrinters TagsPrettyPrinterRegistry::gPrettyPrin
void
TagsPrettyPrinterRegistry::record (uint32_t uid, void (*cb) (uint8_t [Tags::SIZE], std::ostream &))
{
for (PrettyPrintersI i = gPrettyPrinters.begin ();
i != gPrettyPrinters.end (); i++) {
if (i->first == uid) {
i->second = cb;
return;
}
}
gPrettyPrinters.push_back (std::make_pair (uid, cb));
for (PrettyPrintersI i = gPrettyPrinters.begin ();
i != gPrettyPrinters.end (); i++) {
if (i->first == uid) {
i->second = cb;
return;
}
}
gPrettyPrinters.push_back (std::make_pair (uid, cb));
}
void
TagsPrettyPrinterRegistry::prettyPrint (uint32_t uid, uint8_t buf[Tags::SIZE], std::ostream &os)
{
for (PrettyPrintersI i = gPrettyPrinters.begin ();
i != gPrettyPrinters.end (); i++) {
if (i->first == uid) {
if (i->second == 0) {
os << "tag uid="<<uid<<" null pretty printer."<<std::endl;
} else {
(*(i->second)) (buf, os);
}
return;
}
}
os << "tag uid="<<uid<<" no pretty printer registered."<< std::endl;
for (PrettyPrintersI i = gPrettyPrinters.begin ();
i != gPrettyPrinters.end (); i++) {
if (i->first == uid) {
if (i->second == 0) {
os << "tag uid="<<uid<<" null pretty printer."<<std::endl;
} else {
(*(i->second)) (buf, os);
}
return;
}
}
os << "tag uid="<<uid<<" no pretty printer registered."<< std::endl;
}
@ -59,9 +59,9 @@ TagsPrettyPrinterRegistry::prettyPrint (uint32_t uid, uint8_t buf[Tags::SIZE], s
uint32_t
Tags::UidFactory::create (void)
{
static uint32_t uid = 0;
uid++;
return uid;
static uint32_t uid = 0;
uid++;
return uid;
}
@ -73,104 +73,104 @@ uint32_t Tags::gN_free = 0;
struct Tags::TagData *
Tags::allocData (void)
{
struct Tags::TagData *retval;
if (gFree != 0) {
retval = gFree;
gFree = gFree->m_next;
gN_free--;
} else {
retval = new struct Tags::TagData ();
}
return retval;
struct Tags::TagData *retval;
if (gFree != 0) {
retval = gFree;
gFree = gFree->m_next;
gN_free--;
} else {
retval = new struct Tags::TagData ();
}
return retval;
}
void
Tags::freeData (struct TagData *data)
{
if (gN_free > 1000) {
delete data;
return;
}
gN_free++;
data->m_next = gFree;
gFree = data;
if (gN_free > 1000) {
delete data;
return;
}
gN_free++;
data->m_next = gFree;
gFree = data;
}
#else
struct Tags::TagData *
Tags::allocData (void)
{
struct Tags::TagData *retval;
retval = new struct Tags::TagData ();
return retval;
struct Tags::TagData *retval;
retval = new struct Tags::TagData ();
return retval;
}
void
Tags::freeData (struct TagData *data)
{
delete data;
delete data;
}
#endif
bool
Tags::remove (uint32_t id)
{
bool found = false;
for (struct TagData *cur = m_next; cur != 0; cur = cur->m_next) {
if (cur->m_id == id) {
found = true;
}
}
if (!found) {
return false;
}
struct TagData *start = 0;
struct TagData **prevNext = &start;
for (struct TagData *cur = m_next; cur != 0; cur = cur->m_next) {
if (cur->m_id == id) {
/**
* XXX
* Note: I believe that we could optimize this to
* avoid copying each TagData located after the target id
* and just link the already-copied list to the next tag.
*/
continue;
}
struct TagData *copy = allocData ();
copy->m_id = cur->m_id;
copy->m_count = 1;
copy->m_next = 0;
memcpy (copy->m_data, cur->m_data, Tags::SIZE);
*prevNext = copy;
prevNext = &copy->m_next;
}
*prevNext = 0;
removeAll ();
m_next = start;
return true;
bool found = false;
for (struct TagData *cur = m_next; cur != 0; cur = cur->m_next) {
if (cur->m_id == id) {
found = true;
}
}
if (!found) {
return false;
}
struct TagData *start = 0;
struct TagData **prevNext = &start;
for (struct TagData *cur = m_next; cur != 0; cur = cur->m_next) {
if (cur->m_id == id) {
/**
* XXX
* Note: I believe that we could optimize this to
* avoid copying each TagData located after the target id
* and just link the already-copied list to the next tag.
*/
continue;
}
struct TagData *copy = allocData ();
copy->m_id = cur->m_id;
copy->m_count = 1;
copy->m_next = 0;
memcpy (copy->m_data, cur->m_data, Tags::SIZE);
*prevNext = copy;
prevNext = &copy->m_next;
}
*prevNext = 0;
removeAll ();
m_next = start;
return true;
}
bool
Tags::update (uint8_t const*buffer, uint32_t id)
{
if (!remove (id)) {
return false;
}
struct TagData *newStart = allocData ();
newStart->m_count = 1;
newStart->m_next = 0;
newStart->m_id = id;
memcpy (newStart->m_data, buffer, Tags::SIZE);
newStart->m_next = m_next;
m_next = newStart;
return true;
if (!remove (id)) {
return false;
}
struct TagData *newStart = allocData ();
newStart->m_count = 1;
newStart->m_next = 0;
newStart->m_id = id;
memcpy (newStart->m_data, buffer, Tags::SIZE);
newStart->m_next = m_next;
m_next = newStart;
return true;
}
void
Tags::prettyPrint (std::ostream &os)
{
for (struct TagData *cur = m_next; cur != 0; cur = cur->m_next) {
TagsPrettyPrinterRegistry::prettyPrint (cur->m_id, cur->m_data, os);
}
for (struct TagData *cur = m_next; cur != 0; cur = cur->m_next) {
TagsPrettyPrinterRegistry::prettyPrint (cur->m_id, cur->m_data, os);
}
}
@ -186,38 +186,38 @@ namespace ns3 {
class TagsTest : Test {
public:
TagsTest ();
virtual ~TagsTest ();
virtual bool runTests (void);
TagsTest ();
virtual ~TagsTest ();
virtual bool runTests (void);
};
struct myTagA {
uint8_t a;
uint8_t a;
};
struct myTagB {
uint32_t b;
uint32_t b;
};
struct myTagC {
uint8_t c [Tags::SIZE];
uint8_t c [Tags::SIZE];
};
struct myInvalidTag {
uint8_t invalid [Tags::SIZE+1];
uint8_t invalid [Tags::SIZE+1];
};
static void
myTagAPrettyPrinterCb (struct myTagA *a, std::ostream &os)
{
os << "struct myTagA, a="<<(uint32_t)a->a<<std::endl;
os << "struct myTagA, a="<<(uint32_t)a->a<<std::endl;
}
static void
myTagBPrettyPrinterCb (struct myTagB *b, std::ostream &os)
{
os << "struct myTagB, b="<<b->b<<std::endl;
os << "struct myTagB, b="<<b->b<<std::endl;
}
static void
myTagCPrettyPrinterCb (struct myTagC *c, std::ostream &os)
{
os << "struct myTagC, c="<<(uint32_t)c->c[0]<<std::endl;
os << "struct myTagC, c="<<(uint32_t)c->c[0]<<std::endl;
}
@ -227,7 +227,7 @@ static TagPrettyPrinter<struct myTagC> gMyTagCPrettyPrinter (&myTagCPrettyPrinte
TagsTest::TagsTest ()
: Test ("Tags")
: Test ("Tags")
{}
TagsTest::~TagsTest ()
{}
@ -235,82 +235,82 @@ TagsTest::~TagsTest ()
bool
TagsTest::runTests (void)
{
bool ok = true;
// build initial tag.
Tags tags;
struct myTagA a;
a.a = 10;
tags.add (&a);
a.a = 0;
tags.peek (&a);
if (a.a != 10) {
ok = false;
}
//tags.prettyPrint (std::cout);
struct myTagB b;
b.b = 0xff;
tags.add (&b);
b.b = 0;
tags.peek (&b);
if (b.b != 0xff) {
ok = false;
}
//tags.prettyPrint (std::cout);
// make sure copy contains copy.
Tags other = tags;
//other.prettyPrint (std::cout);
//tags.prettyPrint (std::cout);
struct myTagA oA;
oA.a = 0;
other.peek (&oA);
if (oA.a != 10) {
ok = false;
}
struct myTagB oB;
other.peek (&oB);
if (oB.b != 0xff) {
ok = false;
}
// remove data.
other.remove (&oA);
if (other.peek (&oA)) {
ok = false;
}
//other.prettyPrint (std::cout);
if (!tags.peek (&oA)) {
ok = false;
}
other.remove (&oB);
if (other.peek (&oB)) {
ok = false;
}
if (!tags.peek (&oB)) {
ok = false;
}
other = tags;
Tags another = other;
struct myTagC c;
c.c[0] = 0x66;
another.add (&c);
c.c[0] = 0;
another.peek (&c);
if (!another.peek (&c)) {
ok = false;
}
if (tags.peek (&c)) {
ok = false;
}
other = other;
//other.prettyPrint (std::cout);
//struct myInvalidTag invalid;
//tags.add (&invalid);
return ok;
bool ok = true;
// build initial tag.
Tags tags;
struct myTagA a;
a.a = 10;
tags.add (&a);
a.a = 0;
tags.peek (&a);
if (a.a != 10) {
ok = false;
}
//tags.prettyPrint (std::cout);
struct myTagB b;
b.b = 0xff;
tags.add (&b);
b.b = 0;
tags.peek (&b);
if (b.b != 0xff) {
ok = false;
}
//tags.prettyPrint (std::cout);
// make sure copy contains copy.
Tags other = tags;
//other.prettyPrint (std::cout);
//tags.prettyPrint (std::cout);
struct myTagA oA;
oA.a = 0;
other.peek (&oA);
if (oA.a != 10) {
ok = false;
}
struct myTagB oB;
other.peek (&oB);
if (oB.b != 0xff) {
ok = false;
}
// remove data.
other.remove (&oA);
if (other.peek (&oA)) {
ok = false;
}
//other.prettyPrint (std::cout);
if (!tags.peek (&oA)) {
ok = false;
}
other.remove (&oB);
if (other.peek (&oB)) {
ok = false;
}
if (!tags.peek (&oB)) {
ok = false;
}
other = tags;
Tags another = other;
struct myTagC c;
c.c[0] = 0x66;
another.add (&c);
c.c[0] = 0;
another.peek (&c);
if (!another.peek (&c)) {
ok = false;
}
if (tags.peek (&c)) {
ok = false;
}
other = other;
//other.prettyPrint (std::cout);
//struct myInvalidTag invalid;
//tags.add (&invalid);
return ok;
}
static TagsTest gTagsTest;

234
src/common/tags.h

@ -1,4 +1,4 @@
/* -*- Mode:C++; c-basic-offset:8; tab-width:8; indent-tabs-mode:t -*- */
/* -*- Mode:C++; c-basic-offset:4; tab-width:4; indent-tabs-mode:f -*- */
/*
* Copyright (c) 2006 INRIA
* All rights reserved.
@ -32,51 +32,51 @@ class TagPrettyPrinter;
class Tags {
public:
inline Tags ();
inline Tags (Tags const &o);
inline Tags &operator = (Tags const &o);
inline ~Tags ();
inline Tags ();
inline Tags (Tags const &o);
inline Tags &operator = (Tags const &o);
inline ~Tags ();
template <typename T>
void add (T const*tag);
template <typename T>
void add (T const*tag);
template <typename T>
bool remove (T *tag);
template <typename T>
bool remove (T *tag);
template <typename T>
bool peek (T *tag) const;
template <typename T>
bool peek (T *tag) const;
template <typename T>
bool update (T const*tag);
template <typename T>
bool update (T const*tag);
void prettyPrint (std::ostream &os);
void prettyPrint (std::ostream &os);
inline void removeAll (void);
inline void removeAll (void);
enum {
SIZE = 16
};
enum {
SIZE = 16
};
private:
struct TagData {
struct TagData *m_next;
uint32_t m_id;
uint32_t m_count;
uint8_t m_data[Tags::SIZE];
};
class UidFactory {
public:
static uint32_t create (void);
};
bool remove (uint32_t id);
bool update (uint8_t const*buffer, uint32_t id);
struct Tags::TagData *allocData (void);
void freeData (struct TagData *data);
static struct Tags::TagData *gFree;
static uint32_t gN_free;
struct TagData *m_next;
struct TagData {
struct TagData *m_next;
uint32_t m_id;
uint32_t m_count;
uint8_t m_data[Tags::SIZE];
};
class UidFactory {
public:
static uint32_t create (void);
};
bool remove (uint32_t id);
bool update (uint8_t const*buffer, uint32_t id);
struct Tags::TagData *allocData (void);
void freeData (struct TagData *data);
static struct Tags::TagData *gFree;
static uint32_t gN_free;
struct TagData *m_next;
};
/**
@ -92,21 +92,21 @@ private:
template <typename T>
class TagPrettyPrinter {
public:
TagPrettyPrinter<T> (void(*) (T *, std::ostream &));
TagPrettyPrinter<T> (void(*) (T *, std::ostream &));
private:
TagPrettyPrinter<T> ();
static void prettyPrintCb (uint8_t *buf, std::ostream &os);
static void(*gPrettyPrinter) (T *, std::ostream &);
TagPrettyPrinter<T> ();
static void prettyPrintCb (uint8_t *buf, std::ostream &os);
static void(*gPrettyPrinter) (T *, std::ostream &);
};
class TagsPrettyPrinterRegistry {
public:
static void record (uint32_t uid, void (*cb) (uint8_t buf[Tags::SIZE], std::ostream &os));
static void prettyPrint (uint32_t uid, uint8_t buf[Tags::SIZE], std::ostream &os);
static void record (uint32_t uid, void (*cb) (uint8_t buf[Tags::SIZE], std::ostream &os));
static void prettyPrint (uint32_t uid, uint8_t buf[Tags::SIZE], std::ostream &os);
private:
typedef std::vector<std::pair<uint32_t, void (*) (uint8_t [Tags::SIZE], std::ostream &)> > PrettyPrinters;
typedef std::vector<std::pair<uint32_t, void (*) (uint8_t [Tags::SIZE], std::ostream &)> >::iterator PrettyPrintersI;
static PrettyPrinters gPrettyPrinters;
typedef std::vector<std::pair<uint32_t, void (*) (uint8_t [Tags::SIZE], std::ostream &)> > PrettyPrinters;
typedef std::vector<std::pair<uint32_t, void (*) (uint8_t [Tags::SIZE], std::ostream &)> >::iterator PrettyPrintersI;
static PrettyPrinters gPrettyPrinters;
};
@ -138,16 +138,16 @@ namespace ns3 {
template <typename T>
class TypeUid {
public:
static const uint32_t getUid (void);
static const uint32_t getUid (void);
private:
T realType;
T realType;
};
template <typename T>
const uint32_t TypeUid<T>::getUid (void)
{
static const uint32_t uid = Tags::UidFactory::create ();
return uid;
static const uint32_t uid = Tags::UidFactory::create ();
return uid;
}
@ -161,17 +161,17 @@ const uint32_t TypeUid<T>::getUid (void)
template <typename T>
TagPrettyPrinter<T>::TagPrettyPrinter (void(*prettyPrinter) (T *, std::ostream &))
{
gPrettyPrinter = prettyPrinter;
TagsPrettyPrinterRegistry::record (TypeUid<T>::getUid (),
&TagPrettyPrinter<T>::prettyPrintCb);
gPrettyPrinter = prettyPrinter;
TagsPrettyPrinterRegistry::record (TypeUid<T>::getUid (),
&TagPrettyPrinter<T>::prettyPrintCb);
}
template <typename T>
void
TagPrettyPrinter<T>::prettyPrintCb (uint8_t buf[Tags::SIZE], std::ostream &os)
{
assert (sizeof (T) <= Tags::SIZE);
T *tag = reinterpret_cast<T *> (buf);
(*gPrettyPrinter) (tag, os);
assert (sizeof (T) <= Tags::SIZE);
T *tag = reinterpret_cast<T *> (buf);
(*gPrettyPrinter) (tag, os);
}
template <typename T>
@ -184,106 +184,106 @@ template <typename T>
void
Tags::add (T const*tag)
{
assert (sizeof (T) <= Tags::SIZE);
uint8_t const*buf = reinterpret_cast<uint8_t const*> (tag);
// ensure this id was not yet added
for (struct TagData *cur = m_next; cur != 0; cur = cur->m_next) {
assert (cur->m_id != TypeUid<T>::getUid ());
}
struct TagData *newStart = allocData ();
newStart->m_count = 1;
newStart->m_next = 0;
newStart->m_id = TypeUid<T>::getUid ();
memcpy (newStart->m_data, buf, sizeof (T));
newStart->m_next = m_next;
m_next = newStart;
assert (sizeof (T) <= Tags::SIZE);
uint8_t const*buf = reinterpret_cast<uint8_t const*> (tag);
// ensure this id was not yet added
for (struct TagData *cur = m_next; cur != 0; cur = cur->m_next) {
assert (cur->m_id != TypeUid<T>::getUid ());
}
struct TagData *newStart = allocData ();
newStart->m_count = 1;
newStart->m_next = 0;
newStart->m_id = TypeUid<T>::getUid ();
memcpy (newStart->m_data, buf, sizeof (T));
newStart->m_next = m_next;
m_next = newStart;
}
template <typename T>
bool
Tags::remove (T *tag)
{
assert (sizeof (T) <= Tags::SIZE);
return remove (TypeUid<T>::getUid ());
assert (sizeof (T) <= Tags::SIZE);
return remove (TypeUid<T>::getUid ());
}
template <typename T>
bool
Tags::peek (T *tag) const
{
assert (sizeof (T) <= Tags::SIZE);
uint8_t *buf = reinterpret_cast<uint8_t *> (tag);
for (struct TagData *cur = m_next; cur != 0; cur = cur->m_next) {
if (cur->m_id == TypeUid<T>::getUid ()) {
/* found tag */
memcpy (buf, cur->m_data, sizeof (T));
return true;
}
}
/* no tag found */
return false;
assert (sizeof (T) <= Tags::SIZE);
uint8_t *buf = reinterpret_cast<uint8_t *> (tag);
for (struct TagData *cur = m_next; cur != 0; cur = cur->m_next) {
if (cur->m_id == TypeUid<T>::getUid ()) {
/* found tag */
memcpy (buf, cur->m_data, sizeof (T));
return true;
}
}
/* no tag found */
return false;
}
template <typename T>
bool
Tags::update (T const*tag)
{
assert (sizeof (T) <= Tags::SIZE);
uint8_t const*buf = reinterpret_cast<uint8_t const*> (tag);
return update (buf, TypeUid<T>::getUid ());
assert (sizeof (T) <= Tags::SIZE);
uint8_t const*buf = reinterpret_cast<uint8_t const*> (tag);
return update (buf, TypeUid<T>::getUid ());
}
Tags::Tags ()
: m_next ()
: m_next ()
{}
Tags::Tags (Tags const &o)
: m_next (o.m_next)
: m_next (o.m_next)
{
if (m_next != 0) {
m_next->m_count++;
}
if (m_next != 0) {
m_next->m_count++;
}
}
Tags &
Tags::operator = (Tags const &o)
{
// self assignment
if (m_next == o.m_next) {
return *this;
}
removeAll ();
m_next = o.m_next;
if (m_next != 0) {
m_next->m_count++;
}
return *this;
// self assignment
if (m_next == o.m_next) {
return *this;
}
removeAll ();
m_next = o.m_next;
if (m_next != 0) {
m_next->m_count++;
}
return *this;
}
Tags::~Tags ()
{
removeAll ();
removeAll ();
}
void
Tags::removeAll (void)
{
struct TagData *prev = 0;
for (struct TagData *cur = m_next; cur != 0; cur = cur->m_next) {
cur->m_count--;
if (cur->m_count > 0) {
break;
}
if (prev != 0) {
freeData (prev);
}
prev = cur;
}
if (prev != 0) {
freeData (prev);
}
m_next = 0;
struct TagData *prev = 0;
for (struct TagData *cur = m_next; cur != 0; cur = cur->m_next) {
cur->m_count--;
if (cur->m_count > 0) {
break;
}
if (prev != 0) {
freeData (prev);
}
prev = cur;
}
if (prev != 0) {
freeData (prev);
}
m_next = 0;
}

164
src/common/trace-container.cc

@ -1,4 +1,4 @@
/* -*- Mode:C++; c-basic-offset:8; tab-width:8; indent-tabs-mode:t -*- */
/* -*- Mode:C++; c-basic-offset:4; tab-width:4; indent-tabs-mode:f -*- */
/*
* Copyright (c) 2006 INRIA
* All rights reserved.
@ -30,104 +30,104 @@ TraceContainer::TraceContainer ()
{}
TraceContainer::~TraceContainer ()
{
m_uiList.erase (m_uiList.begin (), m_uiList.end ());
m_siList.erase (m_siList.begin (), m_siList.end ());
m_fList.erase (m_fList.begin (), m_fList.end ());
m_uiList.erase (m_uiList.begin (), m_uiList.end ());
m_siList.erase (m_siList.begin (), m_siList.end ());
m_fList.erase (m_fList.begin (), m_fList.end ());
}
void
TraceContainer::setUiVariableCallback (char const *name, Callback<void,uint64_t, uint64_t> callback)
{
for (UiListI i = m_uiList.begin (); i != m_uiList.end (); i++) {
if ((*i).second == name) {
(*i).first->setCallback (callback);
return;
}
}
assert (false);
for (UiListI i = m_uiList.begin (); i != m_uiList.end (); i++) {
if ((*i).second == name) {
(*i).first->setCallback (callback);
return;
}
}
assert (false);
}
void
TraceContainer::setSiVariableCallback (char const *name, Callback<void,int64_t, int64_t> callback)
{
for (SiListI i = m_siList.begin (); i != m_siList.end (); i++) {
if ((*i).second == name) {
(*i).first->setCallback (callback);
return;
}
}
assert (false);
for (SiListI i = m_siList.begin (); i != m_siList.end (); i++) {
if ((*i).second == name) {
(*i).first->setCallback (callback);
return;
}
}
assert (false);
}
void
TraceContainer::setFVariableCallback (char const *name, Callback<void,double, double> callback)
{
assert (false);
assert (false);
}
void
TraceContainer::setStream (char const *name, std::ostream *os)
{
for (StreamTracerListI i = m_traceStreamList.begin (); i != m_traceStreamList.end (); i++) {
if ((*i).second == name) {
(*i).first->setStream (os);
return;
}
}
assert (false);
for (StreamTracerListI i = m_traceStreamList.begin (); i != m_traceStreamList.end (); i++) {
if ((*i).second == name) {
(*i).first->setStream (os);
return;
}
}
assert (false);
}
void
TraceContainer::registerUiVariable (char const *name, UiVariableTracerBase *var)
{
// ensure unicity
for (UiListI i = m_uiList.begin (); i != m_uiList.end (); i++) {
if (i->second == name) {
m_uiList.erase (i);
break;
}
}
m_uiList.push_back (std::make_pair (var, name));
// ensure unicity
for (UiListI i = m_uiList.begin (); i != m_uiList.end (); i++) {
if (i->second == name) {
m_uiList.erase (i);
break;
}
}
m_uiList.push_back (std::make_pair (var, name));
}
void
TraceContainer::registerSiVariable (char const *name, SiVariableTracerBase *var)
{
// ensure unicity
for (SiListI i = m_siList.begin (); i != m_siList.end (); i++) {
if (i->second == name) {
m_siList.erase (i);
break;
}
}
m_siList.push_back (std::make_pair (var, name));
// ensure unicity
for (SiListI i = m_siList.begin (); i != m_siList.end (); i++) {
if (i->second == name) {
m_siList.erase (i);
break;
}
}
m_siList.push_back (std::make_pair (var, name));
}
void
TraceContainer::registerFVariable (char const *name, FVariableTracerBase *var)
{
assert (false);
assert (false);
}
void
TraceContainer::registerStream (char const *name, StreamTracer *stream)
{
// ensure unicity
for (StreamTracerListI i = m_traceStreamList.begin (); i != m_traceStreamList.end (); i++) {
if (i->second == name) {
m_traceStreamList.erase (i);
break;
}
}
m_traceStreamList.push_back (std::make_pair (stream,name));
// ensure unicity
for (StreamTracerListI i = m_traceStreamList.begin (); i != m_traceStreamList.end (); i++) {
if (i->second == name) {
m_traceStreamList.erase (i);
break;
}
}
m_traceStreamList.push_back (std::make_pair (stream,name));
}
void
TraceContainer::registerCallback (char const *name, CallbackTracerBase *tracer)
{
for (CallbackListI i = m_callbackList.begin (); i != m_callbackList.end (); i++) {
if (i->second == name) {
m_callbackList.erase (i);
break;
}
}
m_callbackList.push_back (std::make_pair (tracer, name));
for (CallbackListI i = m_callbackList.begin (); i != m_callbackList.end (); i++) {
if (i->second == name) {
m_callbackList.erase (i);
break;
}
}
m_callbackList.push_back (std::make_pair (tracer, name));
}
@ -139,28 +139,28 @@ TraceContainer::registerCallback (char const *name, CallbackTracerBase *tracer)
void
ns3::TraceContainer::printDebug (void)
{
if (!m_uiList.empty ()) {
std::cout << "ui var: " << std::endl;
for (UiListI i = m_uiList.begin (); i != m_uiList.end (); i++) {
std::cout << " \"" << (*i).second << "\""<<std::endl;
}
}
if (!m_siList.empty ()) {
std::cout << "si var: " << std::endl;
for (SiListI i = m_siList.begin (); i != m_siList.end (); i++) {
std::cout << " \"" << (*i).second << "\""<<std::endl;
}
}
if (!m_fList.empty ()) {
std::cout << "f var: " << std::endl;
for (FListI i = m_fList.begin (); i != m_fList.end (); i++) {
std::cout << " \"" << (*i).second << "\""<<std::endl;
}
}
if (!m_callbackList.empty ()) {
std::cout << "callback list: "<<std::endl;
for (CallbackListI i = m_callbackList.begin (); i != m_callbackList.end (); i++) {
std::cout << " \"" << i->second << "\""<<std::endl;
}
}
if (!m_uiList.empty ()) {
std::cout << "ui var: " << std::endl;
for (UiListI i = m_uiList.begin (); i != m_uiList.end (); i++) {
std::cout << " \"" << (*i).second << "\""<<std::endl;
}
}
if (!m_siList.empty ()) {
std::cout << "si var: " << std::endl;
for (SiListI i = m_siList.begin (); i != m_siList.end (); i++) {
std::cout << " \"" << (*i).second << "\""<<std::endl;
}
}
if (!m_fList.empty ()) {
std::cout << "f var: " << std::endl;
for (FListI i = m_fList.begin (); i != m_fList.end (); i++) {
std::cout << " \"" << (*i).second << "\""<<std::endl;
}
}
if (!m_callbackList.empty ()) {
std::cout << "callback list: "<<std::endl;
for (CallbackListI i = m_callbackList.begin (); i != m_callbackList.end (); i++) {
std::cout << " \"" << i->second << "\""<<std::endl;
}
}
}

326
src/common/trace-container.h

@ -1,4 +1,4 @@
/* -*- Mode:C++; c-basic-offset:8; tab-width:8; indent-tabs-mode:t -*- */
/* -*- Mode:C++; c-basic-offset:4; tab-width:4; indent-tabs-mode:f -*- */
/*
* Copyright (c) 2006 INRIA
* All rights reserved.
@ -58,140 +58,140 @@ class StreamTracer;
*/
class TraceContainer {
public:
TraceContainer ();
~TraceContainer ();
TraceContainer ();
~TraceContainer ();
/**
* \param name the name of the target event source
* \param callback the callback being connected to the target event source
*
* This method targets only event sources which are variables of any unsigned
* integer type.
*/
void setUiVariableCallback (char const *name,
Callback<void,uint64_t, uint64_t> callback);
/**
* \param name the name of the target event source
* \param callback the callback being connected to the target event source
*
* This method targets only event sources which are variables of any signed
* integer type.
*/
void setSiVariableCallback (char const *name, Callback<void,int64_t, int64_t> callback);
/**
* \param name the name of the target event source
* \param callback the callback being connected to the target event source
*
* This method targets only event sources which are variables of any double type.
*/
void setFVariableCallback (char const *name, Callback<void,double, double> callback);
/**
* \param name the name of the target event source
* \param os the output stream being connected to the source trace stream
*
* This method targets only event sources which are of type StreamTracer.
*/
void setStream (char const *name, std::ostream *os);
/**
* \param name the name of the target event source
* \param callback the callback being connected to the target event source
*
* This method targets only event sources which are variables of any unsigned
* integer type.
*/
void setUiVariableCallback (char const *name,
Callback<void,uint64_t, uint64_t> callback);
/**
* \param name the name of the target event source
* \param callback the callback being connected to the target event source
*
* This method targets only event sources which are variables of any signed
* integer type.
*/
void setSiVariableCallback (char const *name, Callback<void,int64_t, int64_t> callback);
/**
* \param name the name of the target event source
* \param callback the callback being connected to the target event source
*
* This method targets only event sources which are variables of any double type.
*/
void setFVariableCallback (char const *name, Callback<void,double, double> callback);
/**
* \param name the name of the target event source
* \param os the output stream being connected to the source trace stream
*
* This method targets only event sources which are of type StreamTracer.
*/
void setStream (char const *name, std::ostream *os);
/**
* \param name the name of the target event source
* \param callback the callback being connected to the target event source.
*
* This method targets only event sources which are of type CallbackTracer<T1>
*/
template <typename T1>
void setCallback (char const *name, Callback<void,T1> callback);
/**
* \param name the name of the target event source
* \param callback the callback being connected to the target event source.
*
* This method targets only event sources which are of type CallbackTracer<T1,T2>
*/
template <typename T1, typename T2>
void setCallback (char const *name, Callback<void,T1,T2> callback);
/**
* \param name the name of the target event source
* \param callback the callback being connected to the target event source.
*
* This method targets only event sources which are of type CallbackTracer<T1,T2,T3>
*/
template <typename T1, typename T2, typename T3>
void setCallback (char const *name, Callback<void,T1,T2,T3> callback);
/**
* \param name the name of the target event source
* \param callback the callback being connected to the target event source.
*
* This method targets only event sources which are of type CallbackTracer<T1,T2,T3,T4>
*/
template <typename T1, typename T2, typename T3, typename T4>
void setCallback (char const *name, Callback<void,T1,T2,T3,T4> callback);
/**
* \param name the name of the target event source
* \param callback the callback being connected to the target event source.
*
* This method targets only event sources which are of type CallbackTracer<T1,T2,T3,T4,T5>
*/
template <typename T1, typename T2, typename T3, typename T4, typename T5>
void setCallback (char const *name, Callback<void,T1,T2,T3,T4,T5> callback);
/**
* \param name the name of the target event source
* \param callback the callback being connected to the target event source.
*
* This method targets only event sources which are of type CallbackTracer<T1>
*/
template <typename T1>
void setCallback (char const *name, Callback<void,T1> callback);
/**
* \param name the name of the target event source
* \param callback the callback being connected to the target event source.
*
* This method targets only event sources which are of type CallbackTracer<T1,T2>
*/
template <typename T1, typename T2>
void setCallback (char const *name, Callback<void,T1,T2> callback);
/**
* \param name the name of the target event source
* \param callback the callback being connected to the target event source.
*
* This method targets only event sources which are of type CallbackTracer<T1,T2,T3>
*/
template <typename T1, typename T2, typename T3>
void setCallback (char const *name, Callback<void,T1,T2,T3> callback);
/**
* \param name the name of the target event source
* \param callback the callback being connected to the target event source.
*
* This method targets only event sources which are of type CallbackTracer<T1,T2,T3,T4>
*/
template <typename T1, typename T2, typename T3, typename T4>
void setCallback (char const *name, Callback<void,T1,T2,T3,T4> callback);
/**
* \param name the name of the target event source
* \param callback the callback being connected to the target event source.
*
* This method targets only event sources which are of type CallbackTracer<T1,T2,T3,T4,T5>
*/
template <typename T1, typename T2, typename T3, typename T4, typename T5>
void setCallback (char const *name, Callback<void,T1,T2,T3,T4,T5> callback);
/**
* \param name the name of the registered event source
* \param var the event source being registered
*
* This method registers only event sources of type "unsigned integer".
*/
void registerUiVariable (char const *name, UiVariableTracerBase *var);
/**
* \param name the name of the registered event source
* \param var the event source being registered
*
* This method registers only event sources of type "signed integer".
*/
void registerSiVariable (char const *name, SiVariableTracerBase *var);
/**
* \param name the name of the registered event source
* \param var the event source being registered
*
* This method registers only event sources of type "double".
*/
void registerFVariable (char const *name, FVariableTracerBase *var);
/**
* \param name the name of the registered event source
* \param stream the event source being registered
*
* This method registers only event sources of type StreamTracer.
*/
void registerStream (char const *name, StreamTracer *stream);
/**
* \param name the name of the registered event source
* \param var the event source being registered
*
* This method registers only event sources of type "unsigned integer".
*/
void registerUiVariable (char const *name, UiVariableTracerBase *var);
/**
* \param name the name of the registered event source
* \param var the event source being registered
*
* This method registers only event sources of type "signed integer".
*/
void registerSiVariable (char const *name, SiVariableTracerBase *var);
/**
* \param name the name of the registered event source
* \param var the event source being registered
*
* This method registers only event sources of type "double".
*/
void registerFVariable (char const *name, FVariableTracerBase *var);
/**
* \param name the name of the registered event source
* \param stream the event source being registered
*
* This method registers only event sources of type StreamTracer.
*/
void registerStream (char const *name, StreamTracer *stream);
/**
* \param name the name of the registeref event source
* \param tracer the callback tracer being registered.
*
* This method registers only event sources of type CallbackTracer
*/
void registerCallback (char const *name, CallbackTracerBase*tracer);
/**
* \param name the name of the registeref event source
* \param tracer the callback tracer being registered.
*
* This method registers only event sources of type CallbackTracer
*/
void registerCallback (char const *name, CallbackTracerBase*tracer);
/**
* Print the list of registered event sources in this container only.
*/
void printDebug (void);
/**
* Print the list of registered event sources in this container only.
*/
void printDebug (void);
private:
typedef std::list<std::pair<UiVariableTracerBase *, std::string> > UiList;
typedef std::list<std::pair<UiVariableTracerBase *, std::string> >::iterator UiListI;
typedef std::list<std::pair<SiVariableTracerBase *, std::string> > SiList;
typedef std::list<std::pair<SiVariableTracerBase *, std::string> >::iterator SiListI;
typedef std::list<std::pair<FVariableTracerBase *, std::string> > FList;
typedef std::list<std::pair<FVariableTracerBase *, std::string> >::iterator FListI;
typedef std::list<std::pair<StreamTracer *, std::string> > StreamTracerList;
typedef std::list<std::pair<StreamTracer *, std::string> >::iterator StreamTracerListI;
typedef std::list<std::pair<CallbackTracerBase *, std::string> > CallbackList;
typedef std::list<std::pair<CallbackTracerBase *, std::string> >::iterator CallbackListI;
typedef std::list<std::pair<UiVariableTracerBase *, std::string> > UiList;
typedef std::list<std::pair<UiVariableTracerBase *, std::string> >::iterator UiListI;
typedef std::list<std::pair<SiVariableTracerBase *, std::string> > SiList;
typedef std::list<std::pair<SiVariableTracerBase *, std::string> >::iterator SiListI;
typedef std::list<std::pair<FVariableTracerBase *, std::string> > FList;
typedef std::list<std::pair<FVariableTracerBase *, std::string> >::iterator FListI;
typedef std::list<std::pair<StreamTracer *, std::string> > StreamTracerList;
typedef std::list<std::pair<StreamTracer *, std::string> >::iterator StreamTracerListI;
typedef std::list<std::pair<CallbackTracerBase *, std::string> > CallbackList;
typedef std::list<std::pair<CallbackTracerBase *, std::string> >::iterator CallbackListI;
UiList m_uiList;
SiList m_siList;
FList m_fList;
StreamTracerList m_traceStreamList;
CallbackList m_callbackList;
UiList m_uiList;
SiList m_siList;
FList m_fList;
StreamTracerList m_traceStreamList;
CallbackList m_callbackList;
};
}; // namespace ns3
@ -206,70 +206,70 @@ template <typename T1>
void
TraceContainer::setCallback (char const *name, Callback<void,T1> callback)
{
for (CallbackListI i = m_callbackList.begin (); i != m_callbackList.end (); i++) {
if (i->second == name) {
static_cast<CallbackTracer<T1> *> (i->first)->setCallback (callback);
return;
}
}
for (CallbackListI i = m_callbackList.begin (); i != m_callbackList.end (); i++) {
if (i->second == name) {
static_cast<CallbackTracer<T1> *> (i->first)->setCallback (callback);
return;
}
}
#ifndef NDEBUG
assert (false);
assert (false);
#endif
}
template <typename T1, typename T2>
void
TraceContainer::setCallback (char const *name, Callback<void,T1,T2> callback)
{
for (CallbackListI i = m_callbackList.begin (); i != m_callbackList.end (); i++) {
if (i->second == name) {
static_cast<CallbackTracer<T1,T2> *> (i->first)->setCallback (callback);
return;
}
}
for (CallbackListI i = m_callbackList.begin (); i != m_callbackList.end (); i++) {
if (i->second == name) {
static_cast<CallbackTracer<T1,T2> *> (i->first)->setCallback (callback);
return;
}
}
#ifndef NDEBUG
assert (false);
assert (false);
#endif
}
template <typename T1, typename T2, typename T3>
void
TraceContainer::setCallback (char const *name, Callback<void,T1,T2,T3> callback)
{
for (CallbackListI i = m_callbackList.begin (); i != m_callbackList.end (); i++) {
if (i->second == name) {
static_cast<CallbackTracer<T1,T2,T3> *> (i->first)->setCallback (callback);
return;
}
}
for (CallbackListI i = m_callbackList.begin (); i != m_callbackList.end (); i++) {
if (i->second == name) {
static_cast<CallbackTracer<T1,T2,T3> *> (i->first)->setCallback (callback);
return;
}
}
#ifndef NDEBUG
assert (false);
assert (false);
#endif
}
template <typename T1, typename T2, typename T3, typename T4>
void
TraceContainer::setCallback (char const *name, Callback<void,T1,T2,T3,T4> callback)
{
for (CallbackListI i = m_callbackList.begin (); i != m_callbackList.end (); i++) {
if (i->second == name) {
static_cast<CallbackTracer<T1,T2,T3,T4> *> (i->first)->setCallback (callback);
return;
}
}
for (CallbackListI i = m_callbackList.begin (); i != m_callbackList.end (); i++) {
if (i->second == name) {
static_cast<CallbackTracer<T1,T2,T3,T4> *> (i->first)->setCallback (callback);
return;
}
}
#ifndef NDEBUG
assert (false);
assert (false);
#endif
}
template <typename T1, typename T2, typename T3, typename T4, typename T5>
void
TraceContainer::setCallback (char const *name, Callback<void,T1,T2,T3,T4,T5> callback)
{
for (CallbackListI i = m_callbackList.begin (); i != m_callbackList.end (); i++) {
if (i->second == name) {
static_cast<CallbackTracer<T1,T2,T3,T4,T5> *> (i->first)->setCallback (callback);
return;
}
}
for (CallbackListI i = m_callbackList.begin (); i != m_callbackList.end (); i++) {
if (i->second == name) {
static_cast<CallbackTracer<T1,T2,T3,T4,T5> *> (i->first)->setCallback (callback);
return;
}
}
#ifndef NDEBUG
assert (false);
assert (false);
#endif
}

222
src/common/ui-variable-tracer.h

@ -1,4 +1,4 @@
/* -*- Mode:C++; c-basic-offset:8; tab-width:8; indent-tabs-mode:t -*- */
/* -*- Mode:C++; c-basic-offset:4; tab-width:4; indent-tabs-mode:f -*- */
/*
* Copyright (c) 2006 INRIA
* All rights reserved.
@ -29,30 +29,30 @@ namespace ns3 {
class UiVariableTracerBase {
public:
typedef Callback<void, uint64_t, uint64_t> ChangeNotifyCallback;
UiVariableTracerBase ()
: m_callback () {}
/* We don't want to copy the base callback. Only setCallback on
* a specific instance will do something to it. */
UiVariableTracerBase (UiVariableTracerBase const &o)
: m_callback () {}
UiVariableTracerBase &operator = (UiVariableTracerBase const &o) {
return *this;
}
~UiVariableTracerBase () {}
void setCallback(ChangeNotifyCallback callback) {
m_callback = callback;
}
typedef Callback<void, uint64_t, uint64_t> ChangeNotifyCallback;
UiVariableTracerBase ()
: m_callback () {}
/* We don't want to copy the base callback. Only setCallback on
* a specific instance will do something to it. */
UiVariableTracerBase (UiVariableTracerBase const &o)
: m_callback () {}
UiVariableTracerBase &operator = (UiVariableTracerBase const &o) {
return *this;
}
~UiVariableTracerBase () {}
void setCallback(ChangeNotifyCallback callback) {
m_callback = callback;
}
protected:
void notify (uint64_t oldVal, uint64_t newVal) {
if (oldVal != newVal && !m_callback.isNull ()) {
m_callback (oldVal, newVal);
}
}
void notify (uint64_t oldVal, uint64_t newVal) {
if (oldVal != newVal && !m_callback.isNull ()) {
m_callback (oldVal, newVal);
}
}
private:
ChangeNotifyCallback m_callback;
ChangeNotifyCallback m_callback;
};
template <typename T>
@ -85,153 +85,153 @@ class SiVariableTracer;
template <typename T>
class UiVariableTracer : public UiVariableTracerBase {
public:
UiVariableTracer ()
: m_var ()
{}
UiVariableTracer (T const &var)
: m_var (var)
{}
UiVariableTracer &operator = (UiVariableTracer const &o) {
assign (o.get ());
return *this;
}
template <typename TT>
UiVariableTracer &operator = (UiVariableTracer<TT> const &o) {
assign (o.get ());
return *this;
}
template <typename TT>
UiVariableTracer &operator = (SiVariableTracer<TT> const &o) {
assign (o.get ());
return *this;
}
UiVariableTracer &operator++ () {
assign (get () + 1);
return *this;
}
UiVariableTracer &operator-- () {
assign (get () - 1);
return *this;
}
UiVariableTracer operator++ (int) {
UiVariableTracer old (*this);
++*this;
return old;
}
UiVariableTracer operator-- (int) {
UiVariableTracer old (*this);
--*this;
return old;
}
operator T () const {
return get ();
}
void assign (T var) {
notify (m_var, var);
m_var = var;
}
T get (void) const {
return m_var;
}
UiVariableTracer ()
: m_var ()
{}
UiVariableTracer (T const &var)
: m_var (var)
{}
UiVariableTracer &operator = (UiVariableTracer const &o) {
assign (o.get ());
return *this;
}
template <typename TT>
UiVariableTracer &operator = (UiVariableTracer<TT> const &o) {
assign (o.get ());
return *this;
}
template <typename TT>
UiVariableTracer &operator = (SiVariableTracer<TT> const &o) {
assign (o.get ());
return *this;
}
UiVariableTracer &operator++ () {
assign (get () + 1);
return *this;
}
UiVariableTracer &operator-- () {
assign (get () - 1);
return *this;
}
UiVariableTracer operator++ (int) {
UiVariableTracer old (*this);
++*this;
return old;
}
UiVariableTracer operator-- (int) {
UiVariableTracer old (*this);
--*this;
return old;
}
operator T () const {
return get ();
}
void assign (T var) {
notify (m_var, var);
m_var = var;
}
T get (void) const {
return m_var;
}
private:
T m_var;
T m_var;
};
template <typename T>
UiVariableTracer<T> &operator += (UiVariableTracer<T> &lhs, UiVariableTracer<T> const &rhs) {
lhs.assign (lhs.get () + rhs.get ());
return lhs;
lhs.assign (lhs.get () + rhs.get ());
return lhs;
}
template <typename T>
UiVariableTracer<T> &operator -= (UiVariableTracer<T> &lhs, UiVariableTracer<T> const &rhs) {
lhs.assign (lhs.get () - rhs.get ());
return lhs;
lhs.assign (lhs.get () - rhs.get ());
return lhs;
}
template <typename T>
UiVariableTracer<T> &operator *= (UiVariableTracer<T> &lhs, UiVariableTracer<T> const &rhs) {
lhs.assign (lhs.get () * rhs.get ());
return lhs;
lhs.assign (lhs.get () * rhs.get ());
return lhs;
}
template <typename T>
UiVariableTracer<T> &operator /= (UiVariableTracer<T> &lhs, UiVariableTracer<T> const &rhs) {
lhs.assign (lhs.get () / rhs.get ());
return lhs;
lhs.assign (lhs.get () / rhs.get ());
return lhs;
}
template <typename T>
UiVariableTracer<T> &operator <<= (UiVariableTracer<T> &lhs, UiVariableTracer<T> const &rhs) {
lhs.assign (lhs.get () << rhs.get ());
return lhs;
lhs.assign (lhs.get () << rhs.get ());
return lhs;
}
template <typename T>
UiVariableTracer<T> &operator >>= (UiVariableTracer<T> &lhs, UiVariableTracer<T> const &rhs) {
lhs.assign (lhs.get () >> rhs.get ());
return lhs;
lhs.assign (lhs.get () >> rhs.get ());
return lhs;
}
template <typename T>
UiVariableTracer<T> &operator &= (UiVariableTracer<T> &lhs, UiVariableTracer<T> const &rhs) {
lhs.assign (lhs.get () & rhs.get ());
return lhs;
lhs.assign (lhs.get () & rhs.get ());
return lhs;
}
template <typename T>
UiVariableTracer<T> &operator |= (UiVariableTracer<T> &lhs, UiVariableTracer<T> const &rhs) {
lhs.assign (lhs.get () | rhs.get ());
return lhs;
lhs.assign (lhs.get () | rhs.get ());
return lhs;
}
template <typename T>
UiVariableTracer<T> &operator ^= (UiVariableTracer<T> &lhs, UiVariableTracer<T> const &rhs) {
lhs.assign (lhs.get () ^ rhs.get ());
return lhs;
lhs.assign (lhs.get () ^ rhs.get ());
return lhs;
}
template <typename T, typename U>
UiVariableTracer<T> &operator += (UiVariableTracer<T> &lhs, U const &rhs) {
lhs.assign (lhs.get () + rhs);
return lhs;
lhs.assign (lhs.get () + rhs);
return lhs;
}
template <typename T, typename U>
UiVariableTracer<T> &operator -= (UiVariableTracer<T> &lhs, U const &rhs) {
lhs.assign (lhs.get () - rhs);
return lhs;
lhs.assign (lhs.get () - rhs);
return lhs;
}
template <typename T, typename U>
UiVariableTracer<T> &operator *= (UiVariableTracer<T> &lhs, U const &rhs) {
lhs.assign (lhs.get () * rhs);
return lhs;
lhs.assign (lhs.get () * rhs);
return lhs;
}
template <typename T, typename U>
UiVariableTracer<T> &operator /= (UiVariableTracer<T> &lhs, U const &rhs) {
lhs.assign (lhs.get () / rhs);
return lhs;
lhs.assign (lhs.get () / rhs);
return lhs;
}
template <typename T, typename U>
UiVariableTracer<T> &operator <<= (UiVariableTracer<T> &lhs, U const &rhs) {
lhs.assign (lhs.get () << rhs);
return lhs;
lhs.assign (lhs.get () << rhs);
return lhs;
}
template <typename T, typename U>
UiVariableTracer<T> &operator >>= (UiVariableTracer<T> &lhs, U const &rhs) {
lhs.assign (lhs.get () >> rhs);
return lhs;
lhs.assign (lhs.get () >> rhs);
return lhs;
}
template <typename T, typename U>
UiVariableTracer<T> &operator &= (UiVariableTracer<T> &lhs, U const &rhs) {
lhs.assign (lhs.get () & rhs);
return lhs;
lhs.assign (lhs.get () & rhs);
return lhs;
}
template <typename T, typename U>
UiVariableTracer<T> &operator |= (UiVariableTracer<T> &lhs, U const &rhs) {
lhs.assign (lhs.get () | rhs);
return lhs;
lhs.assign (lhs.get () | rhs);
return lhs;
}
template <typename T, typename U>
UiVariableTracer<T> &operator ^= (UiVariableTracer<T> &lhs, U const &rhs) {
lhs.assign (lhs.get () ^ rhs);
return lhs;
lhs.assign (lhs.get () ^ rhs);
return lhs;
}
}; // namespace ns3

388
src/common/variable-tracer-test.cc

@ -1,4 +1,4 @@
/* -*- Mode:C++; c-basic-offset:8; tab-width:8; indent-tabs-mode:t -*- */
/* -*- Mode:C++; c-basic-offset:4; tab-width:4; indent-tabs-mode:f -*- */
/*
* Copyright (c) 2006 INRIA
* All rights reserved.
@ -29,221 +29,221 @@ namespace ns3 {
class Foo {
public:
void notify (uint64_t oldVal, uint64_t newVal) {}
void notify (uint64_t oldVal, uint64_t newVal) {}
};
class VariableTracerTest: public Test {
public:
VariableTracerTest ();
void runUnsignedTests (void);
void runSignedUnsignedTests (void);
virtual bool runTests (void);
VariableTracerTest ();
void runUnsignedTests (void);
void runSignedUnsignedTests (void);
virtual bool runTests (void);
};
void
VariableTracerTest::runUnsignedTests (void)
{
UiVariableTracer<uint32_t> var, ovar, tmp;
uint32_t utmp;
Foo *foo = new Foo ();
var.setCallback (makeCallback (&Foo::notify, foo));
var = 10;
ovar = var;
if (var == ovar) {
}
if (var != ovar) {
}
if (var > ovar) {
}
if (var >= ovar) {
}
if (var < ovar) {
}
if (var <= ovar) {
}
if (var == 1) {
}
if (var != 1) {
}
if (var > 1) {
}
if (var >= 1) {
}
if (var < 1) {
}
if (var <= 1) {
}
if (1 == ovar) {
}
if (1 != ovar) {
}
if (1 > ovar) {
}
if (1 >= ovar) {
}
if (1 < ovar) {
}
if (1 <= ovar) {
}
var++;
++var;
var--;
--var;
tmp = var + ovar;
tmp = var - ovar;
tmp = var / ovar;
tmp = var * ovar;
tmp = var << ovar;
tmp = var >> ovar;
tmp = var & ovar;
tmp = var | ovar;
tmp = var ^ ovar;
tmp = var + 1;
tmp = var - 1;
tmp = var / 1;
tmp = var * 1;
tmp = var << 1;
tmp = var >> 1;
tmp = var & 1;
tmp = var | 1;
tmp = var ^ 1;
tmp = 1 + ovar;
tmp = 1 - ovar;
tmp = 1 / ovar;
tmp = 1 * ovar;
tmp = 1 << ovar;
tmp = 1 >> ovar;
tmp = 1 & ovar;
tmp = 1 | ovar;
tmp = 1 ^ ovar;
tmp += var;
tmp -= var;
tmp /= var;
tmp *= var;
tmp <<= var;
tmp >>= var;
tmp &= var;
tmp |= var;
tmp ^= var;
tmp += 1;
tmp -= 1;
tmp /= 1;
tmp *= 1;
tmp <<= 1;
tmp >>= 1;
tmp &= 1;
tmp |= 1;
tmp ^= 1;
utmp = var + ovar;
utmp = var - ovar;
utmp = var / ovar;
utmp = var * ovar;
utmp = var << ovar;
utmp = var >> ovar;
utmp = var & ovar;
utmp = var | ovar;
utmp = var ^ ovar;
utmp = var + 1;
utmp = var - 1;
utmp = var / 1;
utmp = var * 1;
utmp = var << 1;
utmp = var >> 1;
utmp = var & 1;
utmp = var | 1;
utmp = var ^ 1;
utmp = 1 + ovar;
utmp = 1 - ovar;
utmp = 1 / ovar;
utmp = 1 * ovar;
utmp = 1 << ovar;
utmp = 1 >> ovar;
utmp = 1 & ovar;
utmp = 1 | ovar;
utmp = 1 ^ ovar;
utmp += var;
utmp -= var;
utmp /= var;
utmp *= var;
utmp <<= var;
utmp >>= var;
utmp &= var;
utmp |= var;
utmp ^= var;
utmp += 1;
utmp -= 1;
utmp /= 1;
utmp *= 1;
utmp <<= 1;
utmp >>= 1;
utmp &= 1;
utmp |= 1;
utmp ^= 1;
UiVariableTracer<uint32_t> var, ovar, tmp;
uint32_t utmp;
Foo *foo = new Foo ();
var.setCallback (makeCallback (&Foo::notify, foo));
var = 10;
ovar = var;
if (var == ovar) {
}
if (var != ovar) {
}
if (var > ovar) {
}
if (var >= ovar) {
}
if (var < ovar) {
}
if (var <= ovar) {
}
if (var == 1) {
}
if (var != 1) {
}
if (var > 1) {
}
if (var >= 1) {
}
if (var < 1) {
}
if (var <= 1) {
}
if (1 == ovar) {
}
if (1 != ovar) {
}
if (1 > ovar) {
}
if (1 >= ovar) {
}
if (1 < ovar) {
}
if (1 <= ovar) {
}
var++;
++var;
var--;
--var;
tmp = var + ovar;
tmp = var - ovar;
tmp = var / ovar;
tmp = var * ovar;
tmp = var << ovar;
tmp = var >> ovar;
tmp = var & ovar;
tmp = var | ovar;
tmp = var ^ ovar;
tmp = var + 1;
tmp = var - 1;
tmp = var / 1;
tmp = var * 1;
tmp = var << 1;
tmp = var >> 1;
tmp = var & 1;
tmp = var | 1;
tmp = var ^ 1;
tmp = 1 + ovar;
tmp = 1 - ovar;
tmp = 1 / ovar;
tmp = 1 * ovar;
tmp = 1 << ovar;
tmp = 1 >> ovar;
tmp = 1 & ovar;
tmp = 1 | ovar;
tmp = 1 ^ ovar;
tmp += var;
tmp -= var;
tmp /= var;
tmp *= var;
tmp <<= var;
tmp >>= var;
tmp &= var;
tmp |= var;
tmp ^= var;
tmp += 1;
tmp -= 1;
tmp /= 1;
tmp *= 1;
tmp <<= 1;
tmp >>= 1;
tmp &= 1;
tmp |= 1;
tmp ^= 1;
utmp = var + ovar;
utmp = var - ovar;
utmp = var / ovar;
utmp = var * ovar;
utmp = var << ovar;
utmp = var >> ovar;
utmp = var & ovar;
utmp = var | ovar;
utmp = var ^ ovar;
utmp = var + 1;
utmp = var - 1;
utmp = var / 1;
utmp = var * 1;
utmp = var << 1;
utmp = var >> 1;
utmp = var & 1;
utmp = var | 1;
utmp = var ^ 1;
utmp = 1 + ovar;
utmp = 1 - ovar;
utmp = 1 / ovar;
utmp = 1 * ovar;
utmp = 1 << ovar;
utmp = 1 >> ovar;
utmp = 1 & ovar;
utmp = 1 | ovar;
utmp = 1 ^ ovar;
utmp += var;
utmp -= var;
utmp /= var;
utmp *= var;
utmp <<= var;
utmp >>= var;
utmp &= var;
utmp |= var;
utmp ^= var;
utmp += 1;
utmp -= 1;
utmp /= 1;
utmp *= 1;
utmp <<= 1;
utmp >>= 1;
utmp &= 1;
utmp |= 1;
utmp ^= 1;
}
void
VariableTracerTest::runSignedUnsignedTests (void)
{
unsigned short utmp = 10;
unsigned int uitmp = 7;
short stmp = 5;
utmp = stmp;
utmp += stmp;
uitmp = utmp;
utmp = uitmp;
UiVariableTracer<unsigned short> uvar = 10;
UiVariableTracer<unsigned int> uivar = 5;
SiVariableTracer<short> svar = 5;
SiVariableTracer<int> sivar = 5;
uvar = svar;
svar = uvar;
uvar += svar;
svar += uvar;
uvar = sivar;
sivar = uvar;
uvar += sivar;
sivar += uvar;
uivar = uvar;
uvar = uivar;
uivar += uvar;
uvar += uivar;
sivar = svar;
svar = sivar;
sivar += svar;
svar += sivar;
unsigned short utmp = 10;
unsigned int uitmp = 7;
short stmp = 5;
utmp = stmp;
utmp += stmp;
uitmp = utmp;
utmp = uitmp;
UiVariableTracer<unsigned short> uvar = 10;
UiVariableTracer<unsigned int> uivar = 5;
SiVariableTracer<short> svar = 5;
SiVariableTracer<int> sivar = 5;
uvar = svar;
svar = uvar;
uvar += svar;
svar += uvar;
uvar = sivar;
sivar = uvar;
uvar += sivar;
sivar += uvar;
uivar = uvar;
uvar = uivar;
uivar += uvar;
uvar += uivar;
sivar = svar;
svar = sivar;
sivar += svar;
svar += sivar;
}
bool
VariableTracerTest::runTests (void)
{
runUnsignedTests ();
runSignedUnsignedTests ();
runUnsignedTests ();
runSignedUnsignedTests ();
return true;
return true;
}
VariableTracerTest::VariableTracerTest ()
: Test ("VariableTracer") {}
: Test ("VariableTracer") {}
static VariableTracerTest gVariableTracerTest;

208
src/core/callback-test.cc

@ -1,4 +1,4 @@
/* -*- Mode:C++; c-basic-offset:8; tab-width:8; indent-tabs-mode:t -*- */
/* -*- Mode:C++; c-basic-offset:4; tab-width:4; indent-tabs-mode:f -*- */
/*
* Copyright (c) 2005,2006 INRIA
* All rights reserved.
@ -33,161 +33,161 @@ static bool gTest7 = false;
void test5 (void)
{
gTest5 = true;
gTest5 = true;
}
void test6 (int)
{
gTest6 = true;
gTest6 = true;
}
int test7 (int a)
{
gTest7 = true;
return a;
gTest7 = true;
return a;
}
class CallbackTest : public ns3::Test {
private:
bool m_test1;
bool m_test2;
bool m_test3;
bool m_test4;
bool m_test1;
bool m_test2;
bool m_test3;
bool m_test4;
public:
CallbackTest ();
virtual bool runTests (void);
void reset (void);
bool isWrong (void);
void test1 (void);
int test2 (void);
void test3 (double a);
int test4 (double a, int b);
void test8 (Callback<void, int> callback);
CallbackTest ();
virtual bool runTests (void);
void reset (void);
bool isWrong (void);
void test1 (void);
int test2 (void);
void test3 (double a);
int test4 (double a, int b);
void test8 (Callback<void, int> callback);
};
CallbackTest::CallbackTest ()
: ns3::Test ("Callback"),
m_test1 (false),
m_test2 (false),
m_test3 (false),
m_test4 (false)
: ns3::Test ("Callback"),
m_test1 (false),
m_test2 (false),
m_test3 (false),
m_test4 (false)
{}
void
CallbackTest::test1 (void)
{
m_test1 = true;
m_test1 = true;
}
int
CallbackTest::test2 (void)
{
m_test2 = true;
return 2;
m_test2 = true;
return 2;
}
void
CallbackTest::test3 (double a)
{
m_test3 = true;
m_test3 = true;
}
int
CallbackTest::test4 (double a, int b)
{
m_test4 = true;
return 4;
m_test4 = true;
return 4;
}
void
CallbackTest::test8 (Callback<void,int> callback)
{
callback (3);
callback (3);
}
bool
CallbackTest::isWrong (void)
{
if (!m_test1 ||
!m_test2 ||
!m_test3 ||
!m_test4 ||
!gTest5 ||
!gTest6 ||
!gTest7) {
return true;
}
return false;
if (!m_test1 ||
!m_test2 ||
!m_test3 ||
!m_test4 ||
!gTest5 ||
!gTest6 ||
!gTest7) {
return true;
}
return false;
}
void
CallbackTest::reset (void)
{
m_test1 = false;
m_test2 = false;
m_test3 = false;
m_test4 = false;
gTest5 = false;
gTest6 = false;
gTest7 = false;
m_test1 = false;
m_test2 = false;
m_test3 = false;
m_test4 = false;
gTest5 = false;
gTest6 = false;
gTest7 = false;
}
bool
CallbackTest::runTests (void)
{
bool ok = true;
typedef ns3::Callback<void> A;
typedef ns3::Callback<int> B;
typedef ns3::Callback<void, double> C;
typedef ns3::Callback<int, double, int> D;
typedef ns3::Callback<void> E;
typedef ns3::Callback<void,int> F;
typedef ns3::Callback<int,int> G;
A a0 (this, &CallbackTest::test1);
B b0;
b0 = B (this, &CallbackTest::test2);
C c0 = C (this, &CallbackTest::test3);
D d0 = D (this, &CallbackTest::test4);
E e0 = E (&test5);
F f0 = F (&test6);
G g0 = G (&test7);
a0 ();
b0 ();
c0 (0.0);
d0 (0.0, 1);
e0 ();
f0 (1);
g0 (1);
if (isWrong ()) {
ok = false;
}
reset ();
A a1 = ns3::makeCallback (&CallbackTest::test1, this);
B b1 = ns3::makeCallback (&CallbackTest::test2, this);
C c1 = ns3::makeCallback (&CallbackTest::test3, this);
D d1 = ns3::makeCallback (&CallbackTest::test4, this);
E e1 = ns3::makeCallback (&test5);
F f1 = ns3::makeCallback (&test6);
G g1 = ns3::makeCallback (&test7);
a1 ();
b1 ();
c1 (0.0);
d1 (0.0, 1);
e1 ();
f1 (1);
g1 (2);
test8 (f1);
Callback<void, int64_t,int64_t> a2;
if (isWrong ()) {
ok = false;
}
return ok;
bool ok = true;
typedef ns3::Callback<void> A;
typedef ns3::Callback<int> B;
typedef ns3::Callback<void, double> C;
typedef ns3::Callback<int, double, int> D;
typedef ns3::Callback<void> E;
typedef ns3::Callback<void,int> F;
typedef ns3::Callback<int,int> G;
A a0 (this, &CallbackTest::test1);
B b0;
b0 = B (this, &CallbackTest::test2);
C c0 = C (this, &CallbackTest::test3);
D d0 = D (this, &CallbackTest::test4);
E e0 = E (&test5);
F f0 = F (&test6);
G g0 = G (&test7);
a0 ();
b0 ();
c0 (0.0);
d0 (0.0, 1);
e0 ();
f0 (1);
g0 (1);
if (isWrong ()) {
ok = false;
}
reset ();
A a1 = ns3::makeCallback (&CallbackTest::test1, this);
B b1 = ns3::makeCallback (&CallbackTest::test2, this);
C c1 = ns3::makeCallback (&CallbackTest::test3, this);
D d1 = ns3::makeCallback (&CallbackTest::test4, this);
E e1 = ns3::makeCallback (&test5);
F f1 = ns3::makeCallback (&test6);
G g1 = ns3::makeCallback (&test7);
a1 ();
b1 ();
c1 (0.0);
d1 (0.0, 1);
e1 ();
f1 (1);
g1 (2);
test8 (f1);
Callback<void, int64_t,int64_t> a2;
if (isWrong ()) {
ok = false;
}
return ok;
}
static CallbackTest gCallbackTest;

312
src/core/callback.h

@ -1,4 +1,4 @@
/* -*- Mode:C++; c-basic-offset:8; tab-width:8; indent-tabs-mode:t -*- */
/* -*- Mode:C++; c-basic-offset:4; tab-width:4; indent-tabs-mode:f -*- */
/*
* Copyright (c) 2005,2006 INRIA
* All rights reserved.
@ -64,43 +64,43 @@ class CallbackImpl;
template <typename R>
class CallbackImpl<R,empty,empty,empty,empty,empty> {
public:
virtual ~CallbackImpl () {}
virtual R operator() (void) = 0;
virtual ~CallbackImpl () {}
virtual R operator() (void) = 0;
};
// define CallbackImpl for 1 params
template <typename R, typename T1>
class CallbackImpl<R,T1,empty,empty,empty,empty> {
public:
virtual ~CallbackImpl () {}
virtual R operator() (T1) = 0;
virtual ~CallbackImpl () {}
virtual R operator() (T1) = 0;
};
// define CallbackImpl for 2 params
template <typename R, typename T1, typename T2>
class CallbackImpl<R,T1,T2,empty,empty,empty> {
public:
virtual ~CallbackImpl () {}
virtual R operator() (T1, T2) = 0;
virtual ~CallbackImpl () {}
virtual R operator() (T1, T2) = 0;
};
// define CallbackImpl for 3 params
template <typename R, typename T1, typename T2, typename T3>
class CallbackImpl<R,T1,T2,T3,empty,empty> {
public:
virtual ~CallbackImpl () {}
virtual R operator() (T1, T2, T3) = 0;
virtual ~CallbackImpl () {}
virtual R operator() (T1, T2, T3) = 0;
};
// define CallbackImpl for 4 params
template <typename R, typename T1, typename T2, typename T3, typename T4>
class CallbackImpl<R,T1,T2,T3,T4,empty> {
public:
virtual ~CallbackImpl () {}
virtual R operator() (T1, T2, T3, T4) = 0;
virtual ~CallbackImpl () {}
virtual R operator() (T1, T2, T3, T4) = 0;
};
// define CallbackImpl for 5 params
template <typename R, typename T1, typename T2, typename T3, typename T4, typename T5>
class CallbackImpl {
public:
virtual ~CallbackImpl () {}
virtual R operator() (T1, T2, T3, T4, T5) = 0;
virtual ~CallbackImpl () {}
virtual R operator() (T1, T2, T3, T4, T5) = 0;
};
@ -108,59 +108,59 @@ public:
template <typename T, typename R, typename T1, typename T2, typename T3, typename T4,typename T5>
class FunctorCallbackImpl : public CallbackImpl<R,T1,T2,T3,T4,T5> {
public:
FunctorCallbackImpl (T const &functor)
: m_functor (functor) {}
virtual ~FunctorCallbackImpl () {}
R operator() (void) {
return m_functor ();
}
R operator() (T1 a1) {
return m_functor (a1);
}
R operator() (T1 a1,T2 a2) {
return m_functor (a1,a2);
}
R operator() (T1 a1,T2 a2,T3 a3) {
return m_functor (a1,a2,a3);
}
R operator() (T1 a1,T2 a2,T3 a3,T4 a4) {
return m_functor (a1,a2,a3,a4);
}
R operator() (T1 a1,T2 a2,T3 a3,T4 a4,T5 a5) {
return m_functor (a1,a2,a3,a4,a5);
}
FunctorCallbackImpl (T const &functor)
: m_functor (functor) {}
virtual ~FunctorCallbackImpl () {}
R operator() (void) {
return m_functor ();
}
R operator() (T1 a1) {
return m_functor (a1);
}
R operator() (T1 a1,T2 a2) {
return m_functor (a1,a2);
}
R operator() (T1 a1,T2 a2,T3 a3) {
return m_functor (a1,a2,a3);
}
R operator() (T1 a1,T2 a2,T3 a3,T4 a4) {
return m_functor (a1,a2,a3,a4);
}
R operator() (T1 a1,T2 a2,T3 a3,T4 a4,T5 a5) {
return m_functor (a1,a2,a3,a4,a5);
}
private:
T m_functor;
T m_functor;
};
// an impl for Bound Functors:
template <typename T, typename R, typename TX, typename T1, typename T2, typename T3, typename T4,typename T5>
class BoundFunctorCallbackImpl : public CallbackImpl<R,T1,T2,T3,T4,T5> {
public:
BoundFunctorCallbackImpl (T const &functor, TX a)
: m_functor (functor), m_a (a) {}
virtual ~BoundFunctorCallbackImpl () {}
R operator() (void) {
return m_functor (m_a);
}
R operator() (T1 a1) {
return m_functor (m_a,a1);
}
R operator() (T1 a1,T2 a2) {
return m_functor (m_a,a1,a2);
}
R operator() (T1 a1,T2 a2,T3 a3) {
return m_functor (m_a,a1,a2,a3);
}
R operator() (T1 a1,T2 a2,T3 a3,T4 a4) {
return m_functor (m_a,a1,a2,a3,a4);
}
R operator() (T1 a1,T2 a2,T3 a3,T4 a4,T5 a5) {
return m_functor (m_a,a1,a2,a3,a4,a5);
}
BoundFunctorCallbackImpl (T const &functor, TX a)
: m_functor (functor), m_a (a) {}
virtual ~BoundFunctorCallbackImpl () {}
R operator() (void) {
return m_functor (m_a);
}
R operator() (T1 a1) {
return m_functor (m_a,a1);
}
R operator() (T1 a1,T2 a2) {
return m_functor (m_a,a1,a2);
}
R operator() (T1 a1,T2 a2,T3 a3) {
return m_functor (m_a,a1,a2,a3);
}
R operator() (T1 a1,T2 a2,T3 a3,T4 a4) {
return m_functor (m_a,a1,a2,a3,a4);
}
R operator() (T1 a1,T2 a2,T3 a3,T4 a4,T5 a5) {
return m_functor (m_a,a1,a2,a3,a4,a5);
}
private:
T m_functor;
TX m_a;
T m_functor;
TX m_a;
};
@ -168,30 +168,30 @@ private:
template <typename OBJ_PTR, typename MEM_PTR, typename R, typename T1, typename T2, typename T3, typename T4, typename T5>
class MemPtrCallbackImpl : public CallbackImpl<R,T1,T2,T3,T4,T5> {
public:
MemPtrCallbackImpl (OBJ_PTR const&objPtr, MEM_PTR mem_ptr)
: m_objPtr (objPtr), m_memPtr (mem_ptr) {}
virtual ~MemPtrCallbackImpl () {}
R operator() (void) {
return ((*m_objPtr).*m_memPtr) ();
}
R operator() (T1 a1) {
return ((*m_objPtr).*m_memPtr) (a1);
}
R operator() (T1 a1,T2 a2) {
return ((*m_objPtr).*m_memPtr) (a1,a2);
}
R operator() (T1 a1,T2 a2,T3 a3) {
return ((*m_objPtr).*m_memPtr) (a1,a2,a3);
}
R operator() (T1 a1,T2 a2,T3 a3,T4 a4) {
return ((*m_objPtr).*m_memPtr) (a1,a2,a3,a4);
}
R operator() (T1 a1,T2 a2,T3 a3,T4 a4,T5 a5) {
return ((*m_objPtr).*m_memPtr) (a1,a2,a3,a4,a5);
}
MemPtrCallbackImpl (OBJ_PTR const&objPtr, MEM_PTR mem_ptr)
: m_objPtr (objPtr), m_memPtr (mem_ptr) {}
virtual ~MemPtrCallbackImpl () {}
R operator() (void) {
return ((*m_objPtr).*m_memPtr) ();
}
R operator() (T1 a1) {
return ((*m_objPtr).*m_memPtr) (a1);
}
R operator() (T1 a1,T2 a2) {
return ((*m_objPtr).*m_memPtr) (a1,a2);
}
R operator() (T1 a1,T2 a2,T3 a3) {
return ((*m_objPtr).*m_memPtr) (a1,a2,a3);
}
R operator() (T1 a1,T2 a2,T3 a3,T4 a4) {
return ((*m_objPtr).*m_memPtr) (a1,a2,a3,a4);
}
R operator() (T1 a1,T2 a2,T3 a3,T4 a4,T5 a5) {
return ((*m_objPtr).*m_memPtr) (a1,a2,a3,a4,a5);
}
private:
OBJ_PTR const m_objPtr;
MEM_PTR m_memPtr;
OBJ_PTR const m_objPtr;
MEM_PTR m_memPtr;
};
/**
@ -223,50 +223,50 @@ private:
* \include samples/main-callback.cc
*/
template<typename R,
typename T1 = empty, typename T2 = empty,
typename T3 = empty, typename T4 = empty,
typename T5 = empty>
typename T1 = empty, typename T2 = empty,
typename T3 = empty, typename T4 = empty,
typename T5 = empty>
class Callback {
public:
template <typename FUNCTOR>
Callback (FUNCTOR const &functor)
: m_impl (new FunctorCallbackImpl<FUNCTOR,R,T1,T2,T3,T4,T5> (functor))
{}
template <typename FUNCTOR>
Callback (FUNCTOR const &functor)
: m_impl (new FunctorCallbackImpl<FUNCTOR,R,T1,T2,T3,T4,T5> (functor))
{}
template <typename OBJ_PTR, typename MEM_PTR>
Callback (OBJ_PTR const &objPtr, MEM_PTR mem_ptr)
: m_impl (new MemPtrCallbackImpl<OBJ_PTR,MEM_PTR,R,T1,T2,T3,T4,T5> (objPtr, mem_ptr))
{}
template <typename OBJ_PTR, typename MEM_PTR>
Callback (OBJ_PTR const &objPtr, MEM_PTR mem_ptr)
: m_impl (new MemPtrCallbackImpl<OBJ_PTR,MEM_PTR,R,T1,T2,T3,T4,T5> (objPtr, mem_ptr))
{}
Callback (ReferenceList<CallbackImpl<R,T1,T2,T3,T4,T5> *> const &impl)
: m_impl (impl)
{}
Callback (ReferenceList<CallbackImpl<R,T1,T2,T3,T4,T5> *> const &impl)
: m_impl (impl)
{}
bool isNull (void) {
return (m_impl.get () == 0)?true:false;
}
bool isNull (void) {
return (m_impl.get () == 0)?true:false;
}
Callback () : m_impl () {}
R operator() (void) {
return (*(m_impl.get ())) ();
}
R operator() (T1 a1) {
return (*(m_impl.get ())) (a1);
}
R operator() (T1 a1, T2 a2) {
return (*(m_impl).get ()) (a1,a2);
}
R operator() (T1 a1, T2 a2, T3 a3) {
return (*(m_impl).get ()) (a1,a2,a3);
}
R operator() (T1 a1, T2 a2, T3 a3, T4 a4) {
return (*(m_impl).get ()) (a1,a2,a3,a4);
}
R operator() (T1 a1, T2 a2, T3 a3, T4 a4,T5 a5) {
return (*(m_impl).get ()) (a1,a2,a3,a4,a5);
}
Callback () : m_impl () {}
R operator() (void) {
return (*(m_impl.get ())) ();
}
R operator() (T1 a1) {
return (*(m_impl.get ())) (a1);
}
R operator() (T1 a1, T2 a2) {
return (*(m_impl).get ()) (a1,a2);
}
R operator() (T1 a1, T2 a2, T3 a3) {
return (*(m_impl).get ()) (a1,a2,a3);
}
R operator() (T1 a1, T2 a2, T3 a3, T4 a4) {
return (*(m_impl).get ()) (a1,a2,a3,a4);
}
R operator() (T1 a1, T2 a2, T3 a3, T4 a4,T5 a5) {
return (*(m_impl).get ()) (a1,a2,a3,a4,a5);
}
private:
ReferenceList<CallbackImpl<R,T1,T2,T3,T4,T5>*> m_impl;
ReferenceList<CallbackImpl<R,T1,T2,T3,T4,T5>*> m_impl;
};
/**
@ -284,7 +284,7 @@ private:
*/
template <typename OBJ, typename R>
Callback<R> makeCallback (R (OBJ::*mem_ptr) (), OBJ *const objPtr) {
return Callback<R> (objPtr, mem_ptr);
return Callback<R> (objPtr, mem_ptr);
}
/**
* \ingroup makeCallback
@ -296,7 +296,7 @@ Callback<R> makeCallback (R (OBJ::*mem_ptr) (), OBJ *const objPtr) {
*/
template <typename OBJ, typename R, typename T1>
Callback<R,T1> makeCallback (R (OBJ::*mem_ptr) (T1), OBJ *const objPtr) {
return Callback<R,T1> (objPtr, mem_ptr);
return Callback<R,T1> (objPtr, mem_ptr);
}
/**
* \ingroup makeCallback
@ -308,7 +308,7 @@ Callback<R,T1> makeCallback (R (OBJ::*mem_ptr) (T1), OBJ *const objPtr) {
*/
template <typename OBJ, typename R, typename T1, typename T2>
Callback<R,T1,T2> makeCallback (R (OBJ::*mem_ptr) (T1,T2), OBJ *const objPtr) {
return Callback<R,T1,T2> (objPtr, mem_ptr);
return Callback<R,T1,T2> (objPtr, mem_ptr);
}
/**
* \ingroup makeCallback
@ -320,7 +320,7 @@ Callback<R,T1,T2> makeCallback (R (OBJ::*mem_ptr) (T1,T2), OBJ *const objPtr) {
*/
template <typename OBJ, typename R, typename T1,typename T2, typename T3>
Callback<R,T1,T2,T3> makeCallback (R (OBJ::*mem_ptr) (T1,T2,T3), OBJ *const objPtr) {
return Callback<R,T1,T2,T3> (objPtr, mem_ptr);
return Callback<R,T1,T2,T3> (objPtr, mem_ptr);
}
/**
* \ingroup makeCallback
@ -332,7 +332,7 @@ Callback<R,T1,T2,T3> makeCallback (R (OBJ::*mem_ptr) (T1,T2,T3), OBJ *const objP
*/
template <typename OBJ, typename R, typename T1, typename T2, typename T3, typename T4>
Callback<R,T1,T2,T3,T4> makeCallback (R (OBJ::*mem_ptr) (T1,T2,T3,T4), OBJ *const objPtr) {
return Callback<R,T1,T2,T3,T4> (objPtr, mem_ptr);
return Callback<R,T1,T2,T3,T4> (objPtr, mem_ptr);
}
/**
* \ingroup makeCallback
@ -344,7 +344,7 @@ Callback<R,T1,T2,T3,T4> makeCallback (R (OBJ::*mem_ptr) (T1,T2,T3,T4), OBJ *cons
*/
template <typename OBJ, typename R, typename T1, typename T2, typename T3, typename T4,typename T5>
Callback<R,T1,T2,T3,T4,T5> makeCallback (R (OBJ::*mem_ptr) (T1,T2,T3,T4,T5), OBJ *const objPtr) {
return Callback<R,T1,T2,T3,T4,T5> (objPtr, mem_ptr);
return Callback<R,T1,T2,T3,T4,T5> (objPtr, mem_ptr);
}
/**
@ -356,7 +356,7 @@ Callback<R,T1,T2,T3,T4,T5> makeCallback (R (OBJ::*mem_ptr) (T1,T2,T3,T4,T5), OBJ
*/
template <typename R>
Callback<R> makeCallback (R (*fnPtr) ()) {
return Callback<R> (fnPtr);
return Callback<R> (fnPtr);
}
/**
* \ingroup makeCallback
@ -367,7 +367,7 @@ Callback<R> makeCallback (R (*fnPtr) ()) {
*/
template <typename R, typename T1>
Callback<R,T1> makeCallback (R (*fnPtr) (T1)) {
return Callback<R,T1> (fnPtr);
return Callback<R,T1> (fnPtr);
}
/**
* \ingroup makeCallback
@ -378,7 +378,7 @@ Callback<R,T1> makeCallback (R (*fnPtr) (T1)) {
*/
template <typename R, typename T1, typename T2>
Callback<R,T1,T2> makeCallback (R (*fnPtr) (T1,T2)) {
return Callback<R,T1,T2> (fnPtr);
return Callback<R,T1,T2> (fnPtr);
}
/**
* \ingroup makeCallback
@ -389,7 +389,7 @@ Callback<R,T1,T2> makeCallback (R (*fnPtr) (T1,T2)) {
*/
template <typename R, typename T1, typename T2,typename T3>
Callback<R,T1,T2,T3> makeCallback (R (*fnPtr) (T1,T2,T3)) {
return Callback<R,T1,T2,T3> (fnPtr);
return Callback<R,T1,T2,T3> (fnPtr);
}
/**
* \ingroup makeCallback
@ -400,7 +400,7 @@ Callback<R,T1,T2,T3> makeCallback (R (*fnPtr) (T1,T2,T3)) {
*/
template <typename R, typename T1, typename T2,typename T3,typename T4>
Callback<R,T1,T2,T3,T4> makeCallback (R (*fnPtr) (T1,T2,T3,T4)) {
return Callback<R,T1,T2,T3,T4> (fnPtr);
return Callback<R,T1,T2,T3,T4> (fnPtr);
}
/**
* \ingroup makeCallback
@ -411,7 +411,7 @@ Callback<R,T1,T2,T3,T4> makeCallback (R (*fnPtr) (T1,T2,T3,T4)) {
*/
template <typename R, typename T1, typename T2,typename T3,typename T4,typename T5>
Callback<R,T1,T2,T3,T4,T5> makeCallback (R (*fnPtr) (T1,T2,T3,T4,T5)) {
return Callback<R,T1,T2,T3,T4,T5> (fnPtr);
return Callback<R,T1,T2,T3,T4,T5> (fnPtr);
}
@ -424,7 +424,7 @@ Callback<R,T1,T2,T3,T4,T5> makeCallback (R (*fnPtr) (T1,T2,T3,T4,T5)) {
*/
template <typename R>
Callback<R> makeNullCallback (void) {
return Callback<R> ();
return Callback<R> ();
}
/**
* \ingroup makeCallback
@ -434,7 +434,7 @@ Callback<R> makeNullCallback (void) {
*/
template <typename R, typename T1>
Callback<R,T1> makeNullCallback (void) {
return Callback<R,T1> ();
return Callback<R,T1> ();
}
/**
* \ingroup makeCallback
@ -444,7 +444,7 @@ Callback<R,T1> makeNullCallback (void) {
*/
template <typename R, typename T1, typename T2>
Callback<R,T1,T2> makeNullCallback (void) {
return Callback<R,T1,T2> ();
return Callback<R,T1,T2> ();
}
/**
* \ingroup makeCallback
@ -454,7 +454,7 @@ Callback<R,T1,T2> makeNullCallback (void) {
*/
template <typename R, typename T1, typename T2,typename T3>
Callback<R,T1,T2,T3> makeNullCallback (void) {
return Callback<R,T1,T2,T3> ();
return Callback<R,T1,T2,T3> ();
}
/**
* \ingroup makeCallback
@ -464,7 +464,7 @@ Callback<R,T1,T2,T3> makeNullCallback (void) {
*/
template <typename R, typename T1, typename T2,typename T3,typename T4>
Callback<R,T1,T2,T3,T4> makeNullCallback (void) {
return Callback<R,T1,T2,T3,T4> ();
return Callback<R,T1,T2,T3,T4> ();
}
/**
* \ingroup makeCallback
@ -474,41 +474,41 @@ Callback<R,T1,T2,T3,T4> makeNullCallback (void) {
*/
template <typename R, typename T1, typename T2,typename T3,typename T4,typename T5>
Callback<R,T1,T2,T3,T4,T5> makeNullCallback (void) {
return Callback<R,T1,T2,T3,T4,T5> ();
return Callback<R,T1,T2,T3,T4,T5> ();
}
template <typename R, typename TX, typename T1>
Callback<R,T1> makeBoundCallback (R (*fnPtr) (TX,T1), TX a) {
ReferenceList<CallbackImpl<R,T1,empty,empty,empty,empty>*> impl =
ReferenceList<CallbackImpl<R,T1,empty,empty,empty,empty>*> (
new BoundFunctorCallbackImpl<R (*) (TX,T1),R,TX,T1,empty,empty,empty,empty> (fnPtr, a)
);
return Callback<R,T1> (impl);
ReferenceList<CallbackImpl<R,T1,empty,empty,empty,empty>*> impl =
ReferenceList<CallbackImpl<R,T1,empty,empty,empty,empty>*> (
new BoundFunctorCallbackImpl<R (*) (TX,T1),R,TX,T1,empty,empty,empty,empty> (fnPtr, a)
);
return Callback<R,T1> (impl);
}
template <typename R, typename TX, typename T1, typename T2>
Callback<R,T1,T2> makeBoundCallback (R (*fnPtr) (TX,T1,T2), TX a) {
ReferenceList<CallbackImpl<R,T1,T2,empty,empty,empty>*> impl =
ReferenceList<CallbackImpl<R,T1,T2,empty,empty,empty>*> (
new BoundFunctorCallbackImpl<R (*) (TX,T1,T2),R,TX,T1,T2,empty,empty,empty> (fnPtr, a)
);
return Callback<R,T1,T2> (impl);
ReferenceList<CallbackImpl<R,T1,T2,empty,empty,empty>*> impl =
ReferenceList<CallbackImpl<R,T1,T2,empty,empty,empty>*> (
new BoundFunctorCallbackImpl<R (*) (TX,T1,T2),R,TX,T1,T2,empty,empty,empty> (fnPtr, a)
);
return Callback<R,T1,T2> (impl);
}
template <typename R, typename TX, typename T1, typename T2,typename T3,typename T4>
Callback<R,T1,T2,T3,T4> makeBoundCallback (R (*fnPtr) (TX,T1,T2,T3,T4), TX a) {
ReferenceList<CallbackImpl<R,T1,T2,T3,T4,empty>*> impl =
ReferenceList<CallbackImpl<R,T1,T2,T3,T4,empty>*> (
new BoundFunctorCallbackImpl<R (*) (TX,T1,T2,T3,T4),R,TX,T1,T2,T3,T4,empty> (fnPtr, a)
);
return Callback<R,T1,T2,T3,T4> (impl);
ReferenceList<CallbackImpl<R,T1,T2,T3,T4,empty>*> impl =
ReferenceList<CallbackImpl<R,T1,T2,T3,T4,empty>*> (
new BoundFunctorCallbackImpl<R (*) (TX,T1,T2,T3,T4),R,TX,T1,T2,T3,T4,empty> (fnPtr, a)
);
return Callback<R,T1,T2,T3,T4> (impl);
}
template <typename R, typename TX, typename T1, typename T2,typename T3,typename T4,typename T5>
Callback<R,T1,T2,T3,T4,T5> makeBoundCallback (R (*fnPtr) (TX,T1,T2,T3,T4,T5), TX a) {
ReferenceList<CallbackImpl<R,T1,T2,T3,T4,T5>*> impl =
ReferenceList<CallbackImpl<R,T1,T2,T3,T4,T5>*> (
new BoundFunctorCallbackImpl<R (*) (TX,T1,T2,T3,T4,T5),R,TX,T1,T2,T3,T4,T5> (fnPtr, a)
);
return Callback<R,T1,T2,T3,T4,T5> (impl);
ReferenceList<CallbackImpl<R,T1,T2,T3,T4,T5>*> impl =
ReferenceList<CallbackImpl<R,T1,T2,T3,T4,T5>*> (
new BoundFunctorCallbackImpl<R (*) (TX,T1,T2,T3,T4,T5),R,TX,T1,T2,T3,T4,T5> (fnPtr, a)
);
return Callback<R,T1,T2,T3,T4,T5> (impl);
}

114
src/core/reference-list-test.cc

@ -1,4 +1,4 @@
/* -*- Mode:C++; c-basic-offset:8; tab-width:8; indent-tabs-mode:t -*- */
/* -*- Mode:C++; c-basic-offset:4; tab-width:4; indent-tabs-mode:f -*- */
/*
* Copyright (c) 2006 INRIA
* All rights reserved.
@ -28,7 +28,7 @@
#ifdef REFTEST_DEBUG
#include <iostream>
#define TRACE(x) \
std::cout << x << std::endl;
std::cout << x << std::endl;
#else
#define TRACE(x)
#endif
@ -37,79 +37,79 @@ namespace {
class A {
public:
A () {
TRACE ("constructor");
}
~A () {
TRACE ("destructor");
}
void trace (void) {
TRACE ("trace");
}
A () {
TRACE ("constructor");
}
~A () {
TRACE ("destructor");
}
void trace (void) {
TRACE ("trace");
}
};
class RefTest : public ns3::Test {
public:
RefTest ();
virtual bool runTests (void);
RefTest ();
virtual bool runTests (void);
private:
void test (ns3::ReferenceList<A *>);
void test (ns3::ReferenceList<A *>);
};
RefTest::RefTest ()
: ns3::Test ("ReferenceList")
: ns3::Test ("ReferenceList")
{}
void
RefTest::test (ns3::ReferenceList<A *> a)
{
a->trace ();
a->trace ();
}
bool
RefTest::runTests (void)
{
bool ok = true;
{
ns3::ReferenceList<A *> tmp;
{
ns3::ReferenceList<A *> a (new A ());
test (a);
tmp = a;
test (tmp);
a = tmp;
test (a);
TRACE ("leave inner scope");
}
test (tmp);
TRACE ("leave outer scope");
}
{
ns3::ReferenceList<A *> tmp;
}
{
ns3::ReferenceList<A *> tmp (new A ());
}
{
ns3::ReferenceList<A *> tmp;
tmp.set (new A ());
}
{
TRACE ("test assignement");
ns3::ReferenceList<A *> a0 (new A ());
ns3::ReferenceList<A *> a1 (new A ());
a0 = a1;
}
return ok;
bool ok = true;
{
ns3::ReferenceList<A *> tmp;
{
ns3::ReferenceList<A *> a (new A ());
test (a);
tmp = a;
test (tmp);
a = tmp;
test (a);
TRACE ("leave inner scope");
}
test (tmp);
TRACE ("leave outer scope");
}
{
ns3::ReferenceList<A *> tmp;
}
{
ns3::ReferenceList<A *> tmp (new A ());
}
{
ns3::ReferenceList<A *> tmp;
tmp.set (new A ());
}
{
TRACE ("test assignement");
ns3::ReferenceList<A *> a0 (new A ());
ns3::ReferenceList<A *> a1 (new A ());
a0 = a1;
}
return ok;
}

146
src/core/reference-list.h

@ -1,4 +1,4 @@
/* -*- Mode:C++; c-basic-offset:8; tab-width:8; indent-tabs-mode:t -*- */
/* -*- Mode:C++; c-basic-offset:4; tab-width:4; indent-tabs-mode:f -*- */
/*
* Copyright (c) 2006 INRIA
* All rights reserved.
@ -37,79 +37,79 @@ class ReferenceList;
template <typename OBJ_PTR>
class ReferenceList {
public:
ReferenceList ()
: m_objPtr (),
m_prev (),
m_next ()
{
m_prev = this;
m_next = this;
}
ReferenceList (ReferenceList &o)
: m_objPtr (),
m_prev (),
m_next ()
{
m_prev = this;
m_next = this;
insertSelfInOther (o);
}
ReferenceList (ReferenceList const&o)
: m_objPtr (),
m_prev (),
m_next ()
{
m_prev = this;
m_next = this;
insertSelfInOther (o);
}
ReferenceList (OBJ_PTR const &objPtr)
: m_objPtr (objPtr),
m_prev (),
m_next ()
{
m_prev = this;
m_next = this;
}
~ReferenceList () {
removeFrom_list ();
}
ReferenceList & operator= (ReferenceList const&o) {
removeFrom_list ();
insertSelfInOther (o);
return *this;
}
OBJ_PTR operator-> () {
return m_objPtr;
}
void set (OBJ_PTR objPtr) {
removeFrom_list ();
m_objPtr = objPtr;
}
OBJ_PTR get (void) {
// explicit conversion to raw pointer type.
return m_objPtr;
}
ReferenceList ()
: m_objPtr (),
m_prev (),
m_next ()
{
m_prev = this;
m_next = this;
}
ReferenceList (ReferenceList &o)
: m_objPtr (),
m_prev (),
m_next ()
{
m_prev = this;
m_next = this;
insertSelfInOther (o);
}
ReferenceList (ReferenceList const&o)
: m_objPtr (),
m_prev (),
m_next ()
{
m_prev = this;
m_next = this;
insertSelfInOther (o);
}
ReferenceList (OBJ_PTR const &objPtr)
: m_objPtr (objPtr),
m_prev (),
m_next ()
{
m_prev = this;
m_next = this;
}
~ReferenceList () {
removeFrom_list ();
}
ReferenceList & operator= (ReferenceList const&o) {
removeFrom_list ();
insertSelfInOther (o);
return *this;
}
OBJ_PTR operator-> () {
return m_objPtr;
}
void set (OBJ_PTR objPtr) {
removeFrom_list ();
m_objPtr = objPtr;
}
OBJ_PTR get (void) {
// explicit conversion to raw pointer type.
return m_objPtr;
}
private:
void insertSelfInOther (ReferenceList const&o) {
m_prev = &o;
m_next = o.m_next;
m_next->m_prev = this;
o.m_next = this;
m_objPtr = o.m_objPtr;
}
void removeFrom_list (void) {
if (m_prev == this) {
//assert (m_next == this);
delete m_objPtr;
m_objPtr = OBJ_PTR ();
}
m_prev->m_next = m_next;
m_next->m_prev = m_prev;
}
OBJ_PTR m_objPtr;
mutable ReferenceList const*m_prev;
mutable ReferenceList const*m_next;
void insertSelfInOther (ReferenceList const&o) {
m_prev = &o;
m_next = o.m_next;
m_next->m_prev = this;
o.m_next = this;
m_objPtr = o.m_objPtr;
}
void removeFrom_list (void) {
if (m_prev == this) {
//assert (m_next == this);
delete m_objPtr;
m_objPtr = OBJ_PTR ();
}
m_prev->m_next = m_next;
m_next->m_prev = m_prev;
}
OBJ_PTR m_objPtr;
mutable ReferenceList const*m_prev;
mutable ReferenceList const*m_next;
};
}; // namespace ns3

12
src/core/system-file.h

@ -1,4 +1,4 @@
/* -*- Mode:C++; c-basic-offset:8; tab-width:8; indent-tabs-mode:t -*- */
/* -*- Mode:C++; c-basic-offset:4; tab-width:4; indent-tabs-mode:f -*- */
/*
* Copyright (c) 2005 INRIA
* All rights reserved.
@ -30,13 +30,13 @@ class SystemFilePrivate;
class SystemFile {
public:
SystemFile ();
~SystemFile ();
SystemFile ();
~SystemFile ();
void open (char const *filename);
void write (uint8_t *buffer, uint32_t size);
void open (char const *filename);
void write (uint8_t *buffer, uint32_t size);
private:
SystemFilePrivate *m_priv;
SystemFilePrivate *m_priv;
};
}; //namespace ns3

12
src/core/system-wall-clock-ms.h

@ -1,4 +1,4 @@
/* -*- Mode:C++; c-basic-offset:8; tab-width:8; indent-tabs-mode:t -*- */
/* -*- Mode:C++; c-basic-offset:4; tab-width:4; indent-tabs-mode:f -*- */
/*
* Copyright (c) 2005 INRIA
* All rights reserved.
@ -26,13 +26,13 @@ namespace ns3 {
class SystemWallClockMs {
public:
SystemWallClockMs ();
~SystemWallClockMs ();
SystemWallClockMs ();
~SystemWallClockMs ();
void start (void);
unsigned long long end (void);
void start (void);
unsigned long long end (void);
private:
class SystemWallClockMsPrivate *m_priv;
class SystemWallClockMsPrivate *m_priv;
};
}; // namespace ns3

66
src/core/test.cc

@ -1,4 +1,4 @@
/* -*- Mode:C++; c-basic-offset:8; tab-width:8; indent-tabs-mode:t -*- */
/* -*- Mode:C++; c-basic-offset:4; tab-width:4; indent-tabs-mode:f -*- */
/*
* Copyright (c) 2005 INRIA
* All rights reserved.
@ -29,68 +29,68 @@ namespace ns3 {
TestManager *
TestManager::get (void)
{
static TestManager manager;
return &manager;
static TestManager manager;
return &manager;
}
TestManager::TestManager ()
: m_verbose (false)
: m_verbose (false)
{}
TestManager::~TestManager ()
{
TestsI i = m_tests.begin ();
while (i != m_tests.end ()) {
delete (*i).second;
i = m_tests.erase (i);
}
TestsI i = m_tests.begin ();
while (i != m_tests.end ()) {
delete (*i).second;
i = m_tests.erase (i);
}
}
void
TestManager::add (Test *test, char const *name)
{
get ()->m_tests.push_back (std::make_pair (test, new std::string (name)));
get ()->m_tests.push_back (std::make_pair (test, new std::string (name)));
}
void
TestManager::enableVerbose (void)
{
get ()->m_verbose = true;
get ()->m_verbose = true;
}
std::ostream &
TestManager::failure (void)
{
return std::cerr;
return std::cerr;
}
bool
TestManager::runTests (void)
{
return get ()->realRunTests ();
return get ()->realRunTests ();
}
bool
TestManager::realRunTests (void)
{
bool isSuccess = true;
for (TestsCI i = m_tests.begin (); i != m_tests.end (); i++) {
std::string *testName = (*i).second;
if (!(*i).first->runTests ()) {
isSuccess = false;
if (m_verbose) {
std::cerr << "FAIL " << *testName << std::endl;
}
} else {
if (m_verbose) {
std::cerr << "PASS "<<*testName << std::endl;
}
}
}
if (!isSuccess) {
std::cerr << "FAIL" << std::endl;
}
return isSuccess;
bool isSuccess = true;
for (TestsCI i = m_tests.begin (); i != m_tests.end (); i++) {
std::string *testName = (*i).second;
if (!(*i).first->runTests ()) {
isSuccess = false;
if (m_verbose) {
std::cerr << "FAIL " << *testName << std::endl;
}
} else {
if (m_verbose) {
std::cerr << "PASS "<<*testName << std::endl;
}
}
}
if (!isSuccess) {
std::cerr << "FAIL" << std::endl;
}
return isSuccess;
}
Test::Test (char const *name)
{
TestManager::add (this, name);
TestManager::add (this, name);
}
Test::~Test ()
@ -99,7 +99,7 @@ Test::~Test ()
std::ostream &
Test::failure (void)
{
return TestManager::failure ();
return TestManager::failure ();
}
}; // namespace ns3

42
src/core/test.h

@ -1,4 +1,4 @@
/* -*- Mode:C++; c-basic-offset:8; tab-width:8; indent-tabs-mode:t -*- */
/* -*- Mode:C++; c-basic-offset:4; tab-width:4; indent-tabs-mode:f -*- */
/*
* Copyright (c) 2005 INRIA
* All rights reserved.
@ -35,38 +35,38 @@ class TestManager;
class Test {
public:
Test (char const *name);
virtual ~Test ();
Test (char const *name);
virtual ~Test ();
virtual bool runTests (void) = 0;
virtual bool runTests (void) = 0;
protected:
std::ostream &failure (void);
std::ostream &failure (void);
};
class TestManager {
public:
// main methods the test runner is supposed to
// invoke.
static void enableVerbose (void);
static bool runTests (void);
// main methods the test runner is supposed to
// invoke.
static void enableVerbose (void);
static bool runTests (void);
// helper methods
static void add (Test *test, char const *name);
static std::ostream &failure (void);
// helper methods
static void add (Test *test, char const *name);
static std::ostream &failure (void);
private:
static TestManager *get (void);
bool realRunTests (void);
static TestManager *get (void);
bool realRunTests (void);
TestManager ();
~TestManager ();
TestManager ();
~TestManager ();
typedef std::list<std::pair<Test *,std::string *> > Tests;
typedef std::list<std::pair<Test *,std::string *> >::iterator TestsI;
typedef std::list<std::pair<Test *,std::string *> >::const_iterator TestsCI;
typedef std::list<std::pair<Test *,std::string *> > Tests;
typedef std::list<std::pair<Test *,std::string *> >::iterator TestsI;
typedef std::list<std::pair<Test *,std::string *> >::const_iterator TestsCI;
Tests m_tests;
bool m_verbose;
Tests m_tests;
bool m_verbose;
};
}; // namespace ns3

62
src/core/unix-system-file.cc

@ -1,4 +1,4 @@
/* -*- Mode:C++; c-basic-offset:8; tab-width:8; indent-tabs-mode:t -*- */
/* -*- Mode:C++; c-basic-offset:4; tab-width:4; indent-tabs-mode:f -*- */
/*
* Copyright (c) 2005 INRIA
* All rights reserved.
@ -46,32 +46,32 @@ namespace ns3 {
class SystemFilePrivate {
public:
SystemFilePrivate ();
~SystemFilePrivate ();
SystemFilePrivate ();
~SystemFilePrivate ();
void open (char const *filename);
void write (uint8_t *buffer, uint32_t size);
void open (char const *filename);
void write (uint8_t *buffer, uint32_t size);
private:
uint8_t m_data[BUFFER_SIZE];
uint32_t m_current;
int m_fd;
uint8_t m_data[BUFFER_SIZE];
uint32_t m_current;
int m_fd;
};
SystemFilePrivate::SystemFilePrivate ()
: m_current (0)
: m_current (0)
{}
SystemFilePrivate::~SystemFilePrivate ()
{
::write (m_fd, m_data, m_current);
::close (m_fd);
::write (m_fd, m_data, m_current);
::close (m_fd);
}
void
SystemFilePrivate::open (char const *filename)
{
m_fd = ::open (filename, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR);
assert (m_fd != -1);
m_fd = ::open (filename, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR);
assert (m_fd != -1);
}
#ifndef min
@ -81,39 +81,39 @@ SystemFilePrivate::open (char const *filename)
void
SystemFilePrivate::write (uint8_t *buffer, uint32_t size)
{
while (size > 0) {
uint32_t toCopy = min (BUFFER_SIZE - m_current, size);
memcpy (m_data + m_current, buffer, toCopy);
size -= toCopy;
m_current += toCopy;
buffer += toCopy;
if (m_current == BUFFER_SIZE) {
ssize_t written = 0;
written = ::write (m_fd, m_data, BUFFER_SIZE);
assert (written == BUFFER_SIZE);
m_current = 0;
}
}
while (size > 0) {
uint32_t toCopy = min (BUFFER_SIZE - m_current, size);
memcpy (m_data + m_current, buffer, toCopy);
size -= toCopy;
m_current += toCopy;
buffer += toCopy;
if (m_current == BUFFER_SIZE) {
ssize_t written = 0;
written = ::write (m_fd, m_data, BUFFER_SIZE);
assert (written == BUFFER_SIZE);
m_current = 0;
}
}
}
SystemFile::SystemFile ()
: m_priv (new SystemFilePrivate ())
: m_priv (new SystemFilePrivate ())
{}
SystemFile::~SystemFile ()
{
delete m_priv;
m_priv = 0;
delete m_priv;
m_priv = 0;
}
void
SystemFile::open (char const *filename)
{
m_priv->open (filename);
m_priv->open (filename);
}
void
SystemFile::write (uint8_t *buffer, uint32_t size)
{
m_priv->write (buffer, size);
m_priv->write (buffer, size);
}
}; // namespace

34
src/core/unix-system-wall-clock-ms.cc

@ -1,4 +1,4 @@
/* -*- Mode:C++; c-basic-offset:8; tab-width:8; indent-tabs-mode:t -*- */
/* -*- Mode:C++; c-basic-offset:4; tab-width:4; indent-tabs-mode:f -*- */
/*
* Copyright (c) 2005 INRIA
* All rights reserved.
@ -26,49 +26,49 @@ namespace ns3 {
class SystemWallClockMsPrivate {
public:
void start (void);
unsigned long long end (void);
void start (void);
unsigned long long end (void);
private:
struct timeval m_startTv;
struct timeval m_endTv;
struct timeval m_startTv;
struct timeval m_endTv;
};
void
SystemWallClockMsPrivate::start (void)
{
struct timezone tz;
gettimeofday (&m_startTv, &tz);
struct timezone tz;
gettimeofday (&m_startTv, &tz);
}
unsigned long long
SystemWallClockMsPrivate::end (void)
{
struct timezone tz;
gettimeofday (&m_endTv, &tz);
unsigned long long end = m_endTv.tv_sec *1000 + m_endTv.tv_usec / 1000;
unsigned long long start = m_startTv.tv_sec *1000 + m_startTv.tv_usec / 1000;
return end - start;
struct timezone tz;
gettimeofday (&m_endTv, &tz);
unsigned long long end = m_endTv.tv_sec *1000 + m_endTv.tv_usec / 1000;
unsigned long long start = m_startTv.tv_sec *1000 + m_startTv.tv_usec / 1000;
return end - start;
}
SystemWallClockMs::SystemWallClockMs ()
: m_priv (new SystemWallClockMsPrivate ())
: m_priv (new SystemWallClockMsPrivate ())
{}
SystemWallClockMs::~SystemWallClockMs ()
{
delete m_priv;
m_priv = 0;
delete m_priv;
m_priv = 0;
}
void
SystemWallClockMs::start (void)
{
m_priv->start ();
m_priv->start ();
}
unsigned long long
SystemWallClockMs::end (void)
{
return m_priv->end ();
return m_priv->end ();
}
}; // namespace ns3

20
src/core/win32-system-file.cc

@ -1,4 +1,4 @@
/* -*- Mode:C++; c-basic-offset:8; tab-width:8; indent-tabs-mode:t -*- */
/* -*- Mode:C++; c-basic-offset:4; tab-width:4; indent-tabs-mode:f -*- */
/*
* Copyright (c) 2005 INRIA
* All rights reserved.
@ -38,11 +38,11 @@ namespace ns3 {
class SystemFilePrivate {
public:
SystemFilePrivate ();
~SystemFilePrivate ();
SystemFilePrivate ();
~SystemFilePrivate ();
void open (char const *filename);
void write (uint8_t *buffer, uint32_t size);
void open (char const *filename);
void write (uint8_t *buffer, uint32_t size);
private:
};
@ -64,23 +64,23 @@ SystemFilePrivate::write (uint8_t *buffer, uint32_t size)
}
SystemFile::SystemFile ()
: m_priv (new SystemFilePrivate ())
: m_priv (new SystemFilePrivate ())
{}
SystemFile::~SystemFile ()
{
delete m_priv;
m_priv = 0;
delete m_priv;
m_priv = 0;
}
void
SystemFile::open (char const *filename)
{
m_priv->open (filename);
m_priv->open (filename);
}
void
SystemFile::write (uint8_t *buffer, uint32_t size)
{
m_priv->write (buffer, size);
m_priv->write (buffer, size);
}
}; // namespace

18
src/core/win32-system-wall-clock-ms.cc

@ -1,4 +1,4 @@
/* -*- Mode:C++; c-basic-offset:8; tab-width:8; indent-tabs-mode:t -*- */
/* -*- Mode:C++; c-basic-offset:4; tab-width:4; indent-tabs-mode:f -*- */
/*
* Copyright (c) 2005 INRIA
* All rights reserved.
@ -25,8 +25,8 @@ namespace ns3 {
class SystemWallClockMsPrivate {
public:
void start (void);
unsigned long long end (void);
void start (void);
unsigned long long end (void);
private:
};
@ -38,28 +38,28 @@ SystemWallClockMsPrivate::start (void)
unsigned long long
SystemWallClockMsPrivate::end (void)
{
return 0;
return 0;
}
SystemWallClockMs::SystemWallClockMs ()
: m_priv (new SystemWallClockMsPrivate ())
: m_priv (new SystemWallClockMsPrivate ())
{}
SystemWallClockMs::~SystemWallClockMs ()
{
delete m_priv;
m_priv = 0;
delete m_priv;
m_priv = 0;
}
void
SystemWallClockMs::start (void)
{
m_priv->start ();
m_priv->start ();
}
unsigned long long
SystemWallClockMs::end (void)
{
return m_priv->end ();
return m_priv->end ();
}
}; // namespace ns3

24
src/simulator/event-id.cc

@ -1,4 +1,4 @@
/* -*- Mode:C++; c-basic-offset:8; tab-width:8; indent-tabs-mode:t -*- */
/* -*- Mode:C++; c-basic-offset:4; tab-width:4; indent-tabs-mode:f -*- */
/*
* Copyright (c) 2005 INRIA
* All rights reserved.
@ -24,40 +24,40 @@
namespace ns3 {
EventId::EventId ()
: m_eventImpl (0),
m_ns (0),
m_uid (0)
: m_eventImpl (0),
m_ns (0),
m_uid (0)
{}
EventId::EventId (EventImpl *impl, uint64_t ns, uint32_t uid)
: m_eventImpl (impl),
m_ns (ns),
m_uid (uid)
: m_eventImpl (impl),
m_ns (ns),
m_uid (uid)
{}
void
EventId::cancel (void)
{
Simulator::cancel (*this);
Simulator::cancel (*this);
}
bool
EventId::isExpired (void)
{
return Simulator::isExpired (*this);
return Simulator::isExpired (*this);
}
EventImpl *
EventId::getEventImpl (void) const
{
return m_eventImpl;
return m_eventImpl;
}
uint64_t
EventId::getNs (void) const
{
return m_ns;
return m_ns;
}
uint32_t
EventId::getUid (void) const
{
return m_uid;
return m_uid;
}

30
src/simulator/event-id.h

@ -1,4 +1,4 @@
/* -*- Mode:C++; c-basic-offset:8; tab-width:8; indent-tabs-mode:t -*- */
/* -*- Mode:C++; c-basic-offset:4; tab-width:4; indent-tabs-mode:f -*- */
/*
* Copyright (c) 2005 INRIA
* All rights reserved.
@ -29,22 +29,22 @@ class EventImpl;
class EventId {
public:
EventId ();
EventId (EventImpl *impl, uint64_t ns, uint32_t uid);
void cancel (void);
bool isExpired (void);
EventId ();
EventId (EventImpl *impl, uint64_t ns, uint32_t uid);
void cancel (void);
bool isExpired (void);
public:
/* The following methods are semi-private
* they are supposed to be invoked only by
* subclasses of the Scheduler base class.
*/
EventImpl *getEventImpl (void) const;
uint64_t getNs (void) const;
uint32_t getUid (void) const;
/* The following methods are semi-private
* they are supposed to be invoked only by
* subclasses of the Scheduler base class.
*/
EventImpl *getEventImpl (void) const;
uint64_t getNs (void) const;
uint32_t getUid (void) const;
private:
EventImpl *m_eventImpl;
uint64_t m_ns;
uint32_t m_uid;
EventImpl *m_eventImpl;
uint64_t m_ns;
uint32_t m_uid;
};
}; // namespace ns3

18
src/simulator/event-impl.cc

@ -1,4 +1,4 @@
/* -*- Mode:C++; c-basic-offset:8; tab-width:8; indent-tabs-mode:t -*- */
/* -*- Mode:C++; c-basic-offset:4; tab-width:4; indent-tabs-mode:f -*- */
/*
* Copyright (c) 2005 INRIA
* All rights reserved.
@ -29,30 +29,30 @@ EventImpl::~EventImpl ()
{}
EventImpl::EventImpl ()
: m_internalIterator (0),
m_cancel (false)
: m_internalIterator (0),
m_cancel (false)
{}
void
EventImpl::invoke (void)
{
if (!m_cancel) {
notify ();
}
if (!m_cancel) {
notify ();
}
}
void
EventImpl::setInternalIterator (void *tag)
{
m_internalIterator = tag;
m_internalIterator = tag;
}
void *
EventImpl::getInternalIterator (void) const
{
return m_internalIterator;
return m_internalIterator;
}
void
EventImpl::cancel (void)
{
m_cancel = true;
m_cancel = true;
}
}; // namespace ns3

22
src/simulator/event-impl.h

@ -1,4 +1,4 @@
/* -*- Mode:C++; c-basic-offset:8; tab-width:8; indent-tabs-mode:t -*- */
/* -*- Mode:C++; c-basic-offset:4; tab-width:4; indent-tabs-mode:f -*- */
/*
* Copyright (c) 2005,2006 INRIA
* All rights reserved.
@ -27,18 +27,18 @@ namespace ns3 {
class EventImpl {
public:
EventImpl ();
virtual ~EventImpl () = 0;
void invoke (void);
void cancel (void);
void setInternalIterator (void *iterator);
void *getInternalIterator (void) const;
EventImpl ();
virtual ~EventImpl () = 0;
void invoke (void);
void cancel (void);
void setInternalIterator (void *iterator);
void *getInternalIterator (void) const;
protected:
virtual void notify (void) = 0;
virtual void notify (void) = 0;
private:
friend class Event;
void *m_internalIterator;
bool m_cancel;
friend class Event;
void *m_internalIterator;
bool m_cancel;
};
}; // namespace ns3

4
src/simulator/scheduler-factory.cc

@ -1,4 +1,4 @@
/* -*- Mode:C++; c-basic-offset:8; tab-width:8; indent-tabs-mode:t -*- */
/* -*- Mode:C++; c-basic-offset:4; tab-width:4; indent-tabs-mode:f -*- */
/*
* Copyright (c) 2006 INRIA
* All rights reserved.
@ -28,7 +28,7 @@ SchedulerFactory::~SchedulerFactory ()
Scheduler *
SchedulerFactory::create (void) const
{
return realCreate ();
return realCreate ();
}
}; // namespace ns3

16
src/simulator/scheduler-factory.h

@ -1,4 +1,4 @@
/* -*- Mode:C++; c-basic-offset:8; tab-width:8; indent-tabs-mode:t -*- */
/* -*- Mode:C++; c-basic-offset:4; tab-width:4; indent-tabs-mode:f -*- */
/*
* Copyright (c) 2006 INRIA
* All rights reserved.
@ -35,14 +35,14 @@ class Scheduler;
*/
class SchedulerFactory {
public:
virtual ~SchedulerFactory ();
Scheduler *create (void) const;
virtual ~SchedulerFactory ();
Scheduler *create (void) const;
private:
/**
* \returns a newly-created scheduler. The caller takes
* ownership of the returned pointer.
*/
virtual Scheduler *realCreate (void) const = 0;
/**
* \returns a newly-created scheduler. The caller takes
* ownership of the returned pointer.
*/
virtual Scheduler *realCreate (void) const = 0;
};
}; // namespace ns3

154
src/simulator/scheduler-heap.cc

@ -1,4 +1,4 @@
/* -*- Mode:C++; c-basic-offset:8; tab-width:8; indent-tabs-mode:t -*- */
/* -*- Mode:C++; c-basic-offset:4; tab-width:4; indent-tabs-mode:f -*- */
/*
* Copyright (c) 2006 INRIA
* Copyright (c) 2005 Mathieu Lacage
@ -53,11 +53,11 @@ namespace ns3 {
SchedulerHeap::SchedulerHeap ()
{
// we purposedly waste an item at the start of
// the array to make sure the indexes in the
// array start at one.
Scheduler::EventKey emptyKey = {0,0};
m_heap.push_back (std::make_pair (static_cast<EventImpl *>(0), emptyKey));
// we purposedly waste an item at the start of
// the array to make sure the indexes in the
// array start at one.
Scheduler::EventKey emptyKey = {0,0};
m_heap.push_back (std::make_pair (static_cast<EventImpl *>(0), emptyKey));
}
SchedulerHeap::~SchedulerHeap ()
@ -66,7 +66,7 @@ SchedulerHeap::~SchedulerHeap ()
void
SchedulerHeap::storeInEvent (EventImpl *ev, uint32_t index) const
{
ev->setInternalIterator ((void *)index);
ev->setInternalIterator ((void *)index);
}
uint32_t
SchedulerHeap::getFrom_event (EventImpl *ev) const
@ -76,168 +76,168 @@ SchedulerHeap::getFrom_event (EventImpl *ev) const
uint32_t
SchedulerHeap::parent (uint32_t id) const
{
return id / 2;
return id / 2;
}
uint32_t
SchedulerHeap::sibling (uint32_t id) const
{
return id + 1;
return id + 1;
}
uint32_t
SchedulerHeap::leftChild (uint32_t id) const
{
return id * 2;
return id * 2;
}
uint32_t
SchedulerHeap::rightChild (uint32_t id) const
{
return id * 2 + 1;
return id * 2 + 1;
}
uint32_t
SchedulerHeap::root (void) const
{
return 1;
return 1;
}
bool
SchedulerHeap::isRoot (uint32_t id) const
{
return (id == root ())?true:false;
return (id == root ())?true:false;
}
uint32_t
SchedulerHeap::last (void) const
{
return m_heap.size () - 1;
return m_heap.size () - 1;
}
bool
SchedulerHeap::isBottom (uint32_t id) const
{
return (id >= m_heap.size ())?true:false;
return (id >= m_heap.size ())?true:false;
}
void
SchedulerHeap::exch (uint32_t a, uint32_t b)
{
assert (b < m_heap.size () && a < m_heap.size ());
TRACE ("exch " << a << ", " << b);
std::pair<EventImpl*, Scheduler::EventKey> tmp (m_heap[a]);
m_heap[a] = m_heap[b];
m_heap[b] = tmp;
storeInEvent (m_heap[a].first, a);
storeInEvent (m_heap[b].first, b);
assert (b < m_heap.size () && a < m_heap.size ());
TRACE ("exch " << a << ", " << b);
std::pair<EventImpl*, Scheduler::EventKey> tmp (m_heap[a]);
m_heap[a] = m_heap[b];
m_heap[b] = tmp;
storeInEvent (m_heap[a].first, a);
storeInEvent (m_heap[b].first, b);
}
bool
SchedulerHeap::isLess (uint32_t a, uint32_t b)
{
Scheduler::EventKeyCompare compare;
return compare (m_heap[a].second, m_heap[b].second);
Scheduler::EventKeyCompare compare;
return compare (m_heap[a].second, m_heap[b].second);
}
uint32_t
SchedulerHeap::smallest (uint32_t a, uint32_t b)
{
return isLess (a,b)?a:b;
return isLess (a,b)?a:b;
}
bool
SchedulerHeap::realIsEmpty (void) const
{
return (m_heap.size () == 1)?true:false;
return (m_heap.size () == 1)?true:false;
}
void
SchedulerHeap::bottom_up (void)
{
uint32_t index = last ();
while (!isRoot (index) &&
isLess (index, parent (index))) {
exch(index, parent (index));
index = parent (index);
}
uint32_t index = last ();
while (!isRoot (index) &&
isLess (index, parent (index))) {
exch(index, parent (index));
index = parent (index);
}
}
void
SchedulerHeap::topDown (void)
{
uint32_t index = root ();
uint32_t right = rightChild (index);
while (!isBottom (right)) {
uint32_t left = leftChild (index);
uint32_t tmp = smallest (left, right);
if (isLess (index, tmp)) {
return;
}
exch (index, tmp);
index = tmp;
right = rightChild (index);
}
if (isBottom (index)) {
return;
}
assert (!isBottom (index));
uint32_t left = leftChild (index);
if (isBottom (left)) {
return;
}
if (isLess (index, left)) {
return;
}
exch (index, left);
uint32_t index = root ();
uint32_t right = rightChild (index);
while (!isBottom (right)) {
uint32_t left = leftChild (index);
uint32_t tmp = smallest (left, right);
if (isLess (index, tmp)) {
return;
}
exch (index, tmp);
index = tmp;
right = rightChild (index);
}
if (isBottom (index)) {
return;
}
assert (!isBottom (index));
uint32_t left = leftChild (index);
if (isBottom (left)) {
return;
}
if (isLess (index, left)) {
return;
}
exch (index, left);
}
EventId
SchedulerHeap::realInsert (EventImpl *event, Scheduler::EventKey key)
{
m_heap.push_back (std::make_pair (event, key));
bottom_up ();
storeInEvent (event, last ());
return EventId (event, key.m_ns, key.m_uid);
m_heap.push_back (std::make_pair (event, key));
bottom_up ();
storeInEvent (event, last ());
return EventId (event, key.m_ns, key.m_uid);
}
EventImpl *
SchedulerHeap::realPeekNext (void) const
{
return m_heap[root ()].first;
return m_heap[root ()].first;
}
Scheduler::EventKey
SchedulerHeap::realPeekNextKey (void) const
{
return m_heap[root ()].second;
return m_heap[root ()].second;
}
void
SchedulerHeap::realRemoveNext (void)
{
exch (root (), last ());
m_heap.pop_back ();
topDown ();
exch (root (), last ());
m_heap.pop_back ();
topDown ();
}
EventImpl *
SchedulerHeap::realRemove (EventId id, Scheduler::EventKey *key)
{
EventImpl *ev = id.getEventImpl ();
uint32_t i = getFrom_event (ev);
*key = m_heap[i].second;
exch (i, last ());
m_heap.pop_back ();
topDown ();
return ev;
EventImpl *ev = id.getEventImpl ();
uint32_t i = getFrom_event (ev);
*key = m_heap[i].second;
exch (i, last ());
m_heap.pop_back ();
topDown ();
return ev;
}
bool
SchedulerHeap::realIsValid (EventId id)
{
EventImpl *ev = id.getEventImpl ();
uint32_t i = getFrom_event (ev);
Scheduler::EventKey key = m_heap[i].second;
return (key.m_ns == id.getNs () &&
key.m_uid == id.getUid ());
EventImpl *ev = id.getEventImpl ();
uint32_t i = getFrom_event (ev);
Scheduler::EventKey key = m_heap[i].second;
return (key.m_ns == id.getNs () &&
key.m_uid == id.getUid ());
}
}; // namespace ns3

54
src/simulator/scheduler-heap.h

@ -1,4 +1,4 @@
/* -*- Mode:C++; c-basic-offset:8; tab-width:8; indent-tabs-mode:t -*- */
/* -*- Mode:C++; c-basic-offset:4; tab-width:4; indent-tabs-mode:f -*- */
/*
* Copyright (c) 2005 INRIA
* All rights reserved.
@ -32,38 +32,38 @@ class EventHolder;
class SchedulerHeap : public Scheduler {
public:
SchedulerHeap ();
virtual ~SchedulerHeap ();
SchedulerHeap ();
virtual ~SchedulerHeap ();
private:
virtual EventId realInsert (EventImpl *event, Scheduler::EventKey key);
virtual bool realIsEmpty (void) const;
virtual EventImpl *realPeekNext (void) const;
virtual Scheduler::EventKey realPeekNextKey (void) const;
virtual void realRemoveNext (void);
virtual EventImpl *realRemove (EventId ev, Scheduler::EventKey *key);
virtual bool realIsValid (EventId id);
virtual EventId realInsert (EventImpl *event, Scheduler::EventKey key);
virtual bool realIsEmpty (void) const;
virtual EventImpl *realPeekNext (void) const;
virtual Scheduler::EventKey realPeekNextKey (void) const;
virtual void realRemoveNext (void);
virtual EventImpl *realRemove (EventId ev, Scheduler::EventKey *key);
virtual bool realIsValid (EventId id);
typedef std::vector<std::pair<EventImpl *, Scheduler::EventKey> > BinaryHeap;
inline void storeInEvent (EventImpl *ev, uint32_t index) const;
uint32_t getFrom_event (EventImpl *ev) const;
typedef std::vector<std::pair<EventImpl *, Scheduler::EventKey> > BinaryHeap;
inline void storeInEvent (EventImpl *ev, uint32_t index) const;
uint32_t getFrom_event (EventImpl *ev) const;
inline uint32_t parent (uint32_t id) const;
uint32_t sibling (uint32_t id) const;
inline uint32_t leftChild (uint32_t id) const;
inline uint32_t rightChild (uint32_t id) const;
inline uint32_t root (void) const;
uint32_t last (void) const;
inline bool isRoot (uint32_t id) const;
inline bool isBottom (uint32_t id) const;
inline bool isLess (uint32_t a, uint32_t b);
inline uint32_t smallest (uint32_t a, uint32_t b);
inline uint32_t parent (uint32_t id) const;
uint32_t sibling (uint32_t id) const;
inline uint32_t leftChild (uint32_t id) const;
inline uint32_t rightChild (uint32_t id) const;
inline uint32_t root (void) const;
uint32_t last (void) const;
inline bool isRoot (uint32_t id) const;
inline bool isBottom (uint32_t id) const;
inline bool isLess (uint32_t a, uint32_t b);
inline uint32_t smallest (uint32_t a, uint32_t b);
inline void exch (uint32_t a, uint32_t b);
void bottom_up (void);
void topDown (void);
inline void exch (uint32_t a, uint32_t b);
void bottom_up (void);
void topDown (void);
BinaryHeap m_heap;
BinaryHeap m_heap;
};
}; // namespace ns3

76
src/simulator/scheduler-list.cc

@ -1,4 +1,4 @@
/* -*- Mode:C++; c-basic-offset:8; tab-width:8; indent-tabs-mode:t -*- */
/* -*- Mode:C++; c-basic-offset:4; tab-width:4; indent-tabs-mode:f -*- */
/*
* Copyright (c) 2005 INRIA
* All rights reserved.
@ -40,80 +40,80 @@ SchedulerList::~SchedulerList ()
EventId
SchedulerList::getEventId (Scheduler::EventKey key, EventsI i)
{
assert (sizeof (i) <= sizeof (void *));
void *internalIterator;
memcpy ((char *)&(internalIterator), (char *)&i, sizeof (void *));
EventImpl *ev = i->first;
ev->setInternalIterator (internalIterator);
return EventId (ev, key.m_ns, key.m_uid);
assert (sizeof (i) <= sizeof (void *));
void *internalIterator;
memcpy ((char *)&(internalIterator), (char *)&i, sizeof (void *));
EventImpl *ev = i->first;
ev->setInternalIterator (internalIterator);
return EventId (ev, key.m_ns, key.m_uid);
}
SchedulerList::EventsI
SchedulerList::getIterator (EventId id)
{
SchedulerList::EventsI i;
assert (sizeof (i) <= sizeof (void *));
EventImpl *ev = id.getEventImpl ();
void *internalIterator = ev->getInternalIterator ();
memcpy ((char *)&i, (char *)&(internalIterator), sizeof (void *));
return i;
SchedulerList::EventsI i;
assert (sizeof (i) <= sizeof (void *));
EventImpl *ev = id.getEventImpl ();
void *internalIterator = ev->getInternalIterator ();
memcpy ((char *)&i, (char *)&(internalIterator), sizeof (void *));
return i;
}
EventId
SchedulerList::realInsert (EventImpl *event, Scheduler::EventKey key)
{
Scheduler::EventKeyCompare compare;
for (EventsI i = m_events.begin (); i != m_events.end (); i++) {
if (compare (key, i->second)) {
m_events.insert (i, std::make_pair (event, key));
return getEventId (key, i);
}
}
m_events.push_back (std::make_pair (event, key));
return getEventId (key, --(m_events.end ()));
Scheduler::EventKeyCompare compare;
for (EventsI i = m_events.begin (); i != m_events.end (); i++) {
if (compare (key, i->second)) {
m_events.insert (i, std::make_pair (event, key));
return getEventId (key, i);
}
}
m_events.push_back (std::make_pair (event, key));
return getEventId (key, --(m_events.end ()));
}
bool
SchedulerList::realIsEmpty (void) const
{
return m_events.empty ();
return m_events.empty ();
}
EventImpl *
SchedulerList::realPeekNext (void) const
{
return m_events.front ().first;
return m_events.front ().first;
}
Scheduler::EventKey
SchedulerList::realPeekNextKey (void) const
{
return m_events.front ().second;
return m_events.front ().second;
}
void
SchedulerList::realRemoveNext (void)
{
m_events.pop_front ();
m_events.pop_front ();
}
EventImpl *
SchedulerList::realRemove (EventId id, Scheduler::EventKey *key)
{
EventsI i = getIterator (id);
*key = i->second;
assert (key->m_ns == id.getNs () &&
key->m_uid == id.getUid ());
EventImpl *ev = i->first;
m_events.erase (i);
return ev;
EventsI i = getIterator (id);
*key = i->second;
assert (key->m_ns == id.getNs () &&
key->m_uid == id.getUid ());
EventImpl *ev = i->first;
m_events.erase (i);
return ev;
}
bool
SchedulerList::realIsValid (EventId id)
{
EventsI i = getIterator (id);
Scheduler::EventKey key = i->second;
return (key.m_ns == id.getNs () &&
key.m_uid == id.getUid ());
EventsI i = getIterator (id);
Scheduler::EventKey key = i->second;
return (key.m_ns == id.getNs () &&
key.m_uid == id.getUid ());
}
}; // namespace ns3

32
src/simulator/scheduler-list.h

@ -1,4 +1,4 @@
/* -*- Mode:C++; c-basic-offset:8; tab-width:8; indent-tabs-mode:t -*- */
/* -*- Mode:C++; c-basic-offset:4; tab-width:4; indent-tabs-mode:f -*- */
/*
* Copyright (c) 2005 INRIA
* All rights reserved.
@ -34,23 +34,23 @@ class EventImpl;
class SchedulerList : public Scheduler {
public:
SchedulerList ();
virtual ~SchedulerList ();
SchedulerList ();
virtual ~SchedulerList ();
private:
virtual EventId realInsert (EventImpl *event, EventKey key);
virtual bool realIsEmpty (void) const;
virtual EventImpl *realPeekNext (void) const;
virtual Scheduler::EventKey realPeekNextKey (void) const;
virtual void realRemoveNext (void);
virtual EventImpl *realRemove (EventId ev, Scheduler::EventKey *key);
virtual bool realIsValid (EventId id);
typedef std::list<std::pair<EventImpl*, EventKey> > Events;
typedef std::list<std::pair<EventImpl*, EventKey> >::iterator EventsI;
EventId getEventId (Scheduler::EventKey key, EventsI i);
EventsI getIterator (EventId id);
Events m_events;
virtual EventId realInsert (EventImpl *event, EventKey key);
virtual bool realIsEmpty (void) const;
virtual EventImpl *realPeekNext (void) const;
virtual Scheduler::EventKey realPeekNextKey (void) const;
virtual void realRemoveNext (void);
virtual EventImpl *realRemove (EventId ev, Scheduler::EventKey *key);
virtual bool realIsValid (EventId id);
typedef std::list<std::pair<EventImpl*, EventKey> > Events;
typedef std::list<std::pair<EventImpl*, EventKey> >::iterator EventsI;
EventId getEventId (Scheduler::EventKey key, EventsI i);
EventsI getIterator (EventId id);
Events m_events;
};
}; // namespace ns3

56
src/simulator/scheduler-map.cc

@ -1,4 +1,4 @@
/* -*- Mode:C++; c-basic-offset:8; tab-width:8; indent-tabs-mode:t -*- */
/* -*- Mode:C++; c-basic-offset:4; tab-width:4; indent-tabs-mode:f -*- */
/*
* Copyright (c) 2006 INRIA
* All rights reserved.
@ -47,70 +47,70 @@ SchedulerMap::~SchedulerMap ()
void
SchedulerMap::storeInEvent (EventImpl *ev, EventMapI i) const
{
void *tag;
memcpy (&(tag), &i, sizeof (tag));
ev->setInternalIterator (tag);
void *tag;
memcpy (&(tag), &i, sizeof (tag));
ev->setInternalIterator (tag);
}
SchedulerMap::EventMapI
SchedulerMap::getFrom_event (EventImpl *ev) const
{
EventMapI i;
void *tag = ev->getInternalIterator ();
memcpy (&i, &(tag), sizeof (i));
return i;
EventMapI i;
void *tag = ev->getInternalIterator ();
memcpy (&i, &(tag), sizeof (i));
return i;
}
EventId
SchedulerMap::realInsert (EventImpl *event, Scheduler::EventKey key)
{
std::pair<EventMapI,bool> result = m_list.insert (std::make_pair (key, event));
assert (result.second);
storeInEvent (event, result.first);
return EventId (event, key.m_ns, key.m_uid);
std::pair<EventMapI,bool> result = m_list.insert (std::make_pair (key, event));
assert (result.second);
storeInEvent (event, result.first);
return EventId (event, key.m_ns, key.m_uid);
}
bool
SchedulerMap::realIsEmpty (void) const
{
return m_list.empty ();
return m_list.empty ();
}
EventImpl *
SchedulerMap::realPeekNext (void) const
{
EventMapCI i = m_list.begin ();
assert (i != m_list.end ());
return (*i).second;
EventMapCI i = m_list.begin ();
assert (i != m_list.end ());
return (*i).second;
}
Scheduler::EventKey
SchedulerMap::realPeekNextKey (void) const
{
EventMapCI i = m_list.begin ();
assert (i != m_list.end ());
return (*i).first;
EventMapCI i = m_list.begin ();
assert (i != m_list.end ());
return (*i).first;
}
void
SchedulerMap::realRemoveNext (void)
{
m_list.erase (m_list.begin ());
m_list.erase (m_list.begin ());
}
EventImpl *
SchedulerMap::realRemove (EventId id, Scheduler::EventKey *key)
{
EventMapI i = getFrom_event (id.getEventImpl ());
*key = i->first;
m_list.erase (i);
return i->second;
EventMapI i = getFrom_event (id.getEventImpl ());
*key = i->first;
m_list.erase (i);
return i->second;
}
bool
SchedulerMap::realIsValid (EventId id)
{
EventMapI i = getFrom_event (id.getEventImpl ());
Scheduler::EventKey key = i->first;
return (key.m_ns == id.getNs () &&
key.m_uid == id.getUid ());
EventMapI i = getFrom_event (id.getEventImpl ());
Scheduler::EventKey key = i->first;
return (key.m_ns == id.getNs () &&
key.m_uid == id.getUid ());
}

40
src/simulator/scheduler-map.h

@ -1,4 +1,4 @@
/* -*- Mode:C++; c-basic-offset:8; tab-width:8; indent-tabs-mode:t -*- */
/* -*- Mode:C++; c-basic-offset:4; tab-width:4; indent-tabs-mode:f -*- */
/*
* Copyright (c) 2006 INRIA
* All rights reserved.
@ -33,27 +33,27 @@ class EventImpl;
class SchedulerMap : public Scheduler {
public:
SchedulerMap ();
virtual ~SchedulerMap ();
SchedulerMap ();
virtual ~SchedulerMap ();
private:
virtual EventId realInsert (EventImpl *event, Scheduler::EventKey key);
virtual bool realIsEmpty (void) const;
virtual EventImpl *realPeekNext (void) const;
virtual Scheduler::EventKey realPeekNextKey (void) const;
virtual void realRemoveNext (void);
virtual EventImpl *realRemove (EventId ev, Scheduler::EventKey *key);
virtual bool realIsValid (EventId id);
typedef std::map<Scheduler::EventKey, EventImpl*, Scheduler::EventKeyCompare> EventMap;
typedef std::map<Scheduler::EventKey, EventImpl*, Scheduler::EventKeyCompare>::iterator EventMapI;
typedef std::map<Scheduler::EventKey, EventImpl*, Scheduler::EventKeyCompare>::const_iterator EventMapCI;
void storeInEvent (EventImpl *ev, EventMapI i) const;
SchedulerMap::EventMapI getFrom_event (EventImpl *ev) const;
EventMap m_list;
uint32_t m_uid;
virtual EventId realInsert (EventImpl *event, Scheduler::EventKey key);
virtual bool realIsEmpty (void) const;
virtual EventImpl *realPeekNext (void) const;
virtual Scheduler::EventKey realPeekNextKey (void) const;
virtual void realRemoveNext (void);
virtual EventImpl *realRemove (EventId ev, Scheduler::EventKey *key);
virtual bool realIsValid (EventId id);
typedef std::map<Scheduler::EventKey, EventImpl*, Scheduler::EventKeyCompare> EventMap;
typedef std::map<Scheduler::EventKey, EventImpl*, Scheduler::EventKeyCompare>::iterator EventMapI;
typedef std::map<Scheduler::EventKey, EventImpl*, Scheduler::EventKeyCompare>::const_iterator EventMapCI;
void storeInEvent (EventImpl *ev, EventMapI i) const;
SchedulerMap::EventMapI getFrom_event (EventImpl *ev) const;
EventMap m_list;
uint32_t m_uid;
};
}; // namespace ns3

40
src/simulator/scheduler.cc

@ -1,4 +1,4 @@
/* -*- Mode:C++; c-basic-offset:8; tab-width:8; indent-tabs-mode:t -*- */
/* -*- Mode:C++; c-basic-offset:4; tab-width:4; indent-tabs-mode:f -*- */
/*
* Copyright (c) 2006 INRIA
* All rights reserved.
@ -35,55 +35,55 @@ Scheduler::~Scheduler ()
bool
Scheduler::EventKeyCompare::operator () (struct EventKey a, struct EventKey b)
{
assert (a.m_uid != b.m_uid);
if (a.m_ns < b.m_ns) {
return true;
} else if (a.m_ns == b.m_ns && a.m_uid < b.m_uid) {
return true;
} else {
return false;
}
assert (a.m_uid != b.m_uid);
if (a.m_ns < b.m_ns) {
return true;
} else if (a.m_ns == b.m_ns && a.m_uid < b.m_uid) {
return true;
} else {
return false;
}
}
EventId
Scheduler::insert (EventImpl *event, struct EventKey key)
{
return realInsert (event, key);
return realInsert (event, key);
}
bool
Scheduler::isEmpty (void) const
{
return realIsEmpty ();
return realIsEmpty ();
}
EventImpl *
Scheduler::peekNext (void) const
{
assert (!realIsEmpty ());
return realPeekNext ();
assert (!realIsEmpty ());
return realPeekNext ();
}
Scheduler::EventKey
Scheduler::peekNextKey (void) const
{
assert (!realIsEmpty ());
return realPeekNextKey ();
assert (!realIsEmpty ());
return realPeekNextKey ();
}
void
Scheduler::removeNext (void)
{
assert (!realIsEmpty ());
return realRemoveNext ();
assert (!realIsEmpty ());
return realRemoveNext ();
}
EventImpl *
Scheduler::remove (EventId id, EventKey *key)
{
assert (!realIsEmpty ());
return realRemove (id, key);
assert (!realIsEmpty ());
return realRemove (id, key);
}
bool
Scheduler::isValid (EventId id)
{
return realIsValid (id);
return realIsValid (id);
}
}; // namespace ns3

124
src/simulator/scheduler.h

@ -1,4 +1,4 @@
/* -*- Mode:C++; c-basic-offset:8; tab-width:8; indent-tabs-mode:t -*- */
/* -*- Mode:C++; c-basic-offset:4; tab-width:4; indent-tabs-mode:f -*- */
/*
* Copyright (c) 2005 INRIA
* All rights reserved.
@ -51,71 +51,71 @@ class EventImpl;
*/
class Scheduler {
public:
struct EventKey {
uint64_t m_ns;
uint32_t m_uid;
};
class EventKeyCompare {
public:
bool operator () (struct EventKey a, struct EventKey b);
};
struct EventKey {
uint64_t m_ns;
uint32_t m_uid;
};
class EventKeyCompare {
public:
bool operator () (struct EventKey a, struct EventKey b);
};
virtual ~Scheduler () = 0;
virtual ~Scheduler () = 0;
EventId insert (EventImpl *event, EventKey key);
bool isEmpty (void) const;
EventImpl *peekNext (void) const;
Scheduler::EventKey peekNextKey (void) const ;
void removeNext (void);
EventImpl *remove (EventId id, EventKey *key);
bool isValid (EventId id);
EventId insert (EventImpl *event, EventKey key);
bool isEmpty (void) const;
EventImpl *peekNext (void) const;
Scheduler::EventKey peekNextKey (void) const ;
void removeNext (void);
EventImpl *remove (EventId id, EventKey *key);
bool isValid (EventId id);
private:
/**
* \param event event to store in the event list
* \param key timecode associated to this new event
* \returns an event id which identifies the event inserted
*
* This method takes ownership of the event pointer.
*/
virtual EventId realInsert (EventImpl *event, EventKey key) = 0;
/**
* \returns true if the event list is empty and false otherwise.
*/
virtual bool realIsEmpty (void) const = 0;
/**
* \returns a pointer to the next earliest event. The caller
* takes ownership of the returned pointer.
*
* This method cannot be invoked if the list is empty.
*/
virtual EventImpl *realPeekNext (void) const = 0;
/**
* \returns the timecode associated with the next earliest event.
*
* This method cannot be invoked if the list is empty.
*/
virtual Scheduler::EventKey realPeekNextKey (void) const = 0;
/**
* This method cannot be invoked if the list is empty.
* Remove the next earliest event from the event list.
*/
virtual void realRemoveNext (void) = 0;
/**
* \param id the id of the event to remove
* \param key the timecode of the event removed
* \returns a pointer to the event removed. The caller
* takes ownership of the returned pointer.
*
* This methods cannot be invoked if the list is empty.
*/
virtual EventImpl *realRemove (EventId id, EventKey *key) = 0;
/**
* \param id event id to validate
* \returns true if the event id identifies an existing valid
* event stored in the event list and false otherwise.
*/
virtual bool realIsValid (EventId id) = 0;
/**
* \param event event to store in the event list
* \param key timecode associated to this new event
* \returns an event id which identifies the event inserted
*
* This method takes ownership of the event pointer.
*/
virtual EventId realInsert (EventImpl *event, EventKey key) = 0;
/**
* \returns true if the event list is empty and false otherwise.
*/
virtual bool realIsEmpty (void) const = 0;
/**
* \returns a pointer to the next earliest event. The caller
* takes ownership of the returned pointer.
*
* This method cannot be invoked if the list is empty.
*/
virtual EventImpl *realPeekNext (void) const = 0;
/**
* \returns the timecode associated with the next earliest event.
*
* This method cannot be invoked if the list is empty.
*/
virtual Scheduler::EventKey realPeekNextKey (void) const = 0;
/**
* This method cannot be invoked if the list is empty.
* Remove the next earliest event from the event list.
*/
virtual void realRemoveNext (void) = 0;
/**
* \param id the id of the event to remove
* \param key the timecode of the event removed
* \returns a pointer to the event removed. The caller
* takes ownership of the returned pointer.
*
* This methods cannot be invoked if the list is empty.
*/
virtual EventImpl *realRemove (EventId id, EventKey *key) = 0;
/**
* \param id event id to validate
* \returns true if the event id identifies an existing valid
* event stored in the event list and false otherwise.
*/
virtual bool realIsValid (EventId id) = 0;
};
}; // namespace ns3

374
src/simulator/simulator.cc

@ -1,4 +1,4 @@
/* -*- Mode:C++; c-basic-offset:8; tab-width:8; indent-tabs-mode:t -*- */
/* -*- Mode:C++; c-basic-offset:4; tab-width:4; indent-tabs-mode:f -*- */
/*
* Copyright (c) 2005,2006 INRIA
* All rights reserved.
@ -49,36 +49,36 @@ namespace ns3 {
class SimulatorPrivate {
public:
SimulatorPrivate (Scheduler *events);
~SimulatorPrivate ();
void enableLogTo (char const *filename);
bool isFinished (void) const;
Time next (void) const;
void stop (void);
void stopAt (Time time);
EventId schedule (Time time, EventImpl *event);
void remove (EventId ev);
void cancel (EventId ev);
bool isExpired (EventId ev);
void run (void);
Time now (void) const;
SimulatorPrivate (Scheduler *events);
~SimulatorPrivate ();
void enableLogTo (char const *filename);
bool isFinished (void) const;
Time next (void) const;
void stop (void);
void stopAt (Time time);
EventId schedule (Time time, EventImpl *event);
void remove (EventId ev);
void cancel (EventId ev);
bool isExpired (EventId ev);
void run (void);
Time now (void) const;
private:
void processOneEvent (void);
typedef std::list<std::pair<EventImpl *,uint32_t> > Events;
Events m_destroy;
uint64_t m_stopAt;
bool m_stop;
Scheduler *m_events;
uint32_t m_uid;
uint32_t m_currentUid;
uint64_t m_currentNs;
std::ofstream m_log;
std::ifstream m_inputLog;
bool m_logEnable;
void processOneEvent (void);
typedef std::list<std::pair<EventImpl *,uint32_t> > Events;
Events m_destroy;
uint64_t m_stopAt;
bool m_stop;
Scheduler *m_events;
uint32_t m_uid;
uint32_t m_currentUid;
uint64_t m_currentNs;
std::ofstream m_log;
std::ifstream m_inputLog;
bool m_logEnable;
};
@ -86,143 +86,143 @@ private:
SimulatorPrivate::SimulatorPrivate (Scheduler *events)
{
m_stop = false;
m_stopAt = 0;
m_events = events;
m_uid = 0;
m_logEnable = false;
m_currentNs = 0;
m_stop = false;
m_stopAt = 0;
m_events = events;
m_uid = 0;
m_logEnable = false;
m_currentNs = 0;
}
SimulatorPrivate::~SimulatorPrivate ()
{
while (!m_destroy.empty ()) {
EventImpl *ev = m_destroy.front ().first;
m_destroy.pop_front ();
TRACE ("handle destroy " << ev);
ev->invoke ();
delete ev;
}
delete m_events;
m_events = (Scheduler *)0xdeadbeaf;
while (!m_destroy.empty ()) {
EventImpl *ev = m_destroy.front ().first;
m_destroy.pop_front ();
TRACE ("handle destroy " << ev);
ev->invoke ();
delete ev;
}
delete m_events;
m_events = (Scheduler *)0xdeadbeaf;
}
void
SimulatorPrivate::enableLogTo (char const *filename)
{
m_log.open (filename);
m_logEnable = true;
m_log.open (filename);
m_logEnable = true;
}
void
SimulatorPrivate::processOneEvent (void)
{
EventImpl *nextEv = m_events->peekNext ();
Scheduler::EventKey nextKey = m_events->peekNextKey ();
m_events->removeNext ();
TRACE ("handle " << nextEv);
m_currentNs = nextKey.m_ns;
m_currentUid = nextKey.m_uid;
if (m_logEnable) {
m_log << "e "<<nextKey.m_uid << " " << nextKey.m_ns << std::endl;
}
nextEv->invoke ();
delete nextEv;
EventImpl *nextEv = m_events->peekNext ();
Scheduler::EventKey nextKey = m_events->peekNextKey ();
m_events->removeNext ();
TRACE ("handle " << nextEv);
m_currentNs = nextKey.m_ns;
m_currentUid = nextKey.m_uid;
if (m_logEnable) {
m_log << "e "<<nextKey.m_uid << " " << nextKey.m_ns << std::endl;
}
nextEv->invoke ();
delete nextEv;
}
bool
SimulatorPrivate::isFinished (void) const
{
return m_events->isEmpty ();
return m_events->isEmpty ();
}
Time
SimulatorPrivate::next (void) const
{
assert (!m_events->isEmpty ());
Scheduler::EventKey nextKey = m_events->peekNextKey ();
return Time::absNs (nextKey.m_ns);
assert (!m_events->isEmpty ());
Scheduler::EventKey nextKey = m_events->peekNextKey ();
return Time::absNs (nextKey.m_ns);
}
void
SimulatorPrivate::run (void)
{
while (!m_events->isEmpty () && !m_stop &&
(m_stopAt == 0 || m_stopAt > next ().ns ())) {
processOneEvent ();
}
m_log.close ();
while (!m_events->isEmpty () && !m_stop &&
(m_stopAt == 0 || m_stopAt > next ().ns ())) {
processOneEvent ();
}
m_log.close ();
}
void
SimulatorPrivate::stop (void)
{
m_stop = true;
m_stop = true;
}
void
SimulatorPrivate::stopAt (Time at)
{
m_stopAt = at.ns ();
m_stopAt = at.ns ();
}
EventId
SimulatorPrivate::schedule (Time time, EventImpl *event)
{
if (time.isDestroy ()) {
m_destroy.push_back (std::make_pair (event, m_uid));
if (m_logEnable) {
m_log << "id " << m_currentUid << " " << now ().ns () << " "
<< m_uid << std::endl;
}
m_uid++;
//XXX
return EventId ();
}
assert (time.ns () >= now ().ns ());
Scheduler::EventKey key = {time.ns (), m_uid};
if (m_logEnable) {
m_log << "i "<<m_currentUid<<" "<<now ().ns ()<<" "
<<m_uid<<" "<<time.ns () << std::endl;
}
m_uid++;
return m_events->insert (event, key);
if (time.isDestroy ()) {
m_destroy.push_back (std::make_pair (event, m_uid));
if (m_logEnable) {
m_log << "id " << m_currentUid << " " << now ().ns () << " "
<< m_uid << std::endl;
}
m_uid++;
//XXX
return EventId ();
}
assert (time.ns () >= now ().ns ());
Scheduler::EventKey key = {time.ns (), m_uid};
if (m_logEnable) {
m_log << "i "<<m_currentUid<<" "<<now ().ns ()<<" "
<<m_uid<<" "<<time.ns () << std::endl;
}
m_uid++;
return m_events->insert (event, key);
}
Time
SimulatorPrivate::now (void) const
{
return Time::absNs (m_currentNs);
return Time::absNs (m_currentNs);
}
void
SimulatorPrivate::remove (EventId ev)
{
Scheduler::EventKey key;
EventImpl *impl = m_events->remove (ev, &key);
delete impl;
if (m_logEnable) {
m_log << "r " << m_currentUid << " " << now ().ns () << " "
<< key.m_uid << " " << key.m_ns << std::endl;
}
Scheduler::EventKey key;
EventImpl *impl = m_events->remove (ev, &key);
delete impl;
if (m_logEnable) {
m_log << "r " << m_currentUid << " " << now ().ns () << " "
<< key.m_uid << " " << key.m_ns << std::endl;
}
}
void
SimulatorPrivate::cancel (EventId id)
{
assert (m_events->isValid (id));
EventImpl *ev = id.getEventImpl ();
ev->cancel ();
assert (m_events->isValid (id));
EventImpl *ev = id.getEventImpl ();
ev->cancel ();
}
bool
SimulatorPrivate::isExpired (EventId ev)
{
if (ev.getEventImpl () != 0 &&
ev.getNs () <= now ().ns () &&
ev.getUid () < m_currentUid) {
return false;
}
return true;
if (ev.getEventImpl () != 0 &&
ev.getNs () <= now ().ns () &&
ev.getUid () < m_currentUid) {
return false;
}
return true;
}
@ -243,120 +243,120 @@ SchedulerFactory const*Simulator::m_schedFactory = 0;
void Simulator::setLinkedList (void)
{
m_listType = LINKED_LIST;
m_listType = LINKED_LIST;
}
void Simulator::setBinaryHeap (void)
{
m_listType = BINARY_HEAP;
m_listType = BINARY_HEAP;
}
void Simulator::setStdMap (void)
{
m_listType = STD_MAP;
m_listType = STD_MAP;
}
void
Simulator::setExternal (SchedulerFactory const*factory)
{
assert (factory != 0);
m_schedFactory = factory;
m_listType = EXTERNAL;
assert (factory != 0);
m_schedFactory = factory;
m_listType = EXTERNAL;
}
void Simulator::enableLogTo (char const *filename)
{
getPriv ()->enableLogTo (filename);
getPriv ()->enableLogTo (filename);
}
SimulatorPrivate *
Simulator::getPriv (void)
{
if (m_priv == 0) {
Scheduler *events;
switch (m_listType) {
case LINKED_LIST:
events = new SchedulerList ();
break;
case BINARY_HEAP:
events = new SchedulerHeap ();
break;
case STD_MAP:
events = new SchedulerMap ();
break;
case EXTERNAL:
events = m_schedFactory->create ();
default: // not reached
events = 0;
assert (false);
break;
}
m_priv = new SimulatorPrivate (events);
}
TRACE_S ("priv " << m_priv);
return m_priv;
if (m_priv == 0) {
Scheduler *events;
switch (m_listType) {
case LINKED_LIST:
events = new SchedulerList ();
break;
case BINARY_HEAP:
events = new SchedulerHeap ();
break;
case STD_MAP:
events = new SchedulerMap ();
break;
case EXTERNAL:
events = m_schedFactory->create ();
default: // not reached
events = 0;
assert (false);
break;
}
m_priv = new SimulatorPrivate (events);
}
TRACE_S ("priv " << m_priv);
return m_priv;
}
void
Simulator::destroy (void)
{
delete m_priv;
m_priv = 0;
delete m_priv;
m_priv = 0;
}
bool
Simulator::isFinished (void)
{
return getPriv ()->isFinished ();
return getPriv ()->isFinished ();
}
Time
Simulator::next (void)
{
return getPriv ()->next ();
return getPriv ()->next ();
}
void
Simulator::run (void)
{
getPriv ()->run ();
getPriv ()->run ();
}
void
Simulator::stop (void)
{
TRACE ("stop");
getPriv ()->stop ();
TRACE ("stop");
getPriv ()->stop ();
}
void
Simulator::stopAt (Time at)
{
getPriv ()->stopAt (at);
getPriv ()->stopAt (at);
}
Time
Simulator::now (void)
{
return getPriv ()->now ();
return getPriv ()->now ();
}
EventId
Simulator::schedule (Time time, EventImpl *ev)
{
return getPriv ()->schedule (time, ev);
return getPriv ()->schedule (time, ev);
}
void
Simulator::remove (EventId ev)
{
return getPriv ()->remove (ev);
return getPriv ()->remove (ev);
}
void
Simulator::cancel (EventId ev)
{
return getPriv ()->cancel (ev);
return getPriv ()->cancel (ev);
}
bool
Simulator::isExpired (EventId id)
{
return getPriv ()->isExpired (id);
return getPriv ()->isExpired (id);
}
}; // namespace ns3
@ -370,76 +370,76 @@ namespace ns3 {
class SimulatorTests : public Test {
public:
SimulatorTests ();
virtual ~SimulatorTests ();
virtual bool runTests (void);
SimulatorTests ();
virtual ~SimulatorTests ();
virtual bool runTests (void);
private:
void a (int a);
void b (int b);
void c (int c);
void d (int d);
bool m_b;
bool m_a;
bool m_c;
bool m_d;
EventId m_idC;
void a (int a);
void b (int b);
void c (int c);
void d (int d);
bool m_b;
bool m_a;
bool m_c;
bool m_d;
EventId m_idC;
};
SimulatorTests::SimulatorTests ()
: Test ("Simulator")
: Test ("Simulator")
{}
SimulatorTests::~SimulatorTests ()
{}
void
SimulatorTests::a (int a)
{
m_a = false;
m_a = false;
}
void
SimulatorTests::b (int b)
{
if (b != 2 || Simulator::now ().us () != 11) {
m_b = false;
} else {
m_b = true;
}
Simulator::remove (m_idC);
Simulator::schedule (Time::relUs (10), &SimulatorTests::d, this, 4);
if (b != 2 || Simulator::now ().us () != 11) {
m_b = false;
} else {
m_b = true;
}
Simulator::remove (m_idC);
Simulator::schedule (Time::relUs (10), &SimulatorTests::d, this, 4);
}
void
SimulatorTests::c (int c)
{
m_c = false;
m_c = false;
}
void
SimulatorTests::d (int d)
{
if (d != 4 || Simulator::now ().us () != (11+10)) {
m_d = false;
} else {
m_d = true;
}
if (d != 4 || Simulator::now ().us () != (11+10)) {
m_d = false;
} else {
m_d = true;
}
}
bool
SimulatorTests::runTests (void)
{
bool ok = true;
m_a = true;
m_b = false;
m_c = true;
m_d = false;
EventId a = Simulator::schedule (Time::absUs (10), &SimulatorTests::a, this, 1);
EventId b = Simulator::schedule (Time::absUs (11), &SimulatorTests::b, this, 2);
m_idC = Simulator::schedule (Time::absUs (12), &SimulatorTests::c, this, 3);
bool ok = true;
m_a = true;
m_b = false;
m_c = true;
m_d = false;
EventId a = Simulator::schedule (Time::absUs (10), &SimulatorTests::a, this, 1);
EventId b = Simulator::schedule (Time::absUs (11), &SimulatorTests::b, this, 2);
m_idC = Simulator::schedule (Time::absUs (12), &SimulatorTests::c, this, 3);
Simulator::cancel (a);
Simulator::run ();
Simulator::cancel (a);
Simulator::run ();
if (!m_a || !m_b || !m_c || !m_d) {
ok = false;
}
if (!m_a || !m_b || !m_c || !m_d) {
ok = false;
}
return ok;
return ok;
}
SimulatorTests gSimulatorTests;

868
src/simulator/simulator.h

@ -1,4 +1,4 @@
/* -*- Mode:C++; c-basic-offset:8; tab-width:8; indent-tabs-mode:t -*- */
/* -*- Mode:C++; c-basic-offset:4; tab-width:4; indent-tabs-mode:f -*- */
/*
* Copyright (c) 2005 INRIA
* All rights reserved.
@ -45,448 +45,448 @@ class SchedulerFactory;
*/
class Simulator {
public:
/**
* Force the use of an event scheduler based on a linked-list.
* This method must be invoked before any other method exported
* by the Simulator class.
* - insert: O(n)
* - remove: O(1)
*/
static void setLinkedList (void);
/**
* Force the use of an event scheduler based on a binary heap.
* This method must be invoked before any other method exported
* by the Simulator class.
* - insert: O(log(n))
* - remove: O(log(n))
*/
static void setBinaryHeap (void);
/**
* Force the use of an event scheduler based on a std::map.
* This method must be invoked before any other method exported
* by the Simulator class.
* - insert: O(log(n))
* - remove: O(log(n))
*/
static void setStdMap (void);
/**
* Force the use of an event scheduler based on a linked-list.
* This method must be invoked before any other method exported
* by the Simulator class.
* - insert: O(n)
* - remove: O(1)
*/
static void setLinkedList (void);
/**
* Force the use of an event scheduler based on a binary heap.
* This method must be invoked before any other method exported
* by the Simulator class.
* - insert: O(log(n))
* - remove: O(log(n))
*/
static void setBinaryHeap (void);
/**
* Force the use of an event scheduler based on a std::map.
* This method must be invoked before any other method exported
* by the Simulator class.
* - insert: O(log(n))
* - remove: O(log(n))
*/
static void setStdMap (void);
/**
* Force the use of a user-provided event scheduler.
* This method must be invoked before any other method exported
* by the Simulator class.
*/
static void setExternal (SchedulerFactory const*factory);
/**
* Force the use of a user-provided event scheduler.
* This method must be invoked before any other method exported
* by the Simulator class.
*/
static void setExternal (SchedulerFactory const*factory);
/**
* Enable logging to the file identified by filename. If the file
* does not exist, it is created. If it exists, it is destroyed and
* re-created. Every scheduling event is logged to this file in a
* simple text format which can be read back by the event replay
* utility. This allows you to record the scheduling behavior of
* a simulation, and measure the exact overhead related to
* event scheduling with the event replay utility. It is also possible
* to compare the performance of every scheduling algorithms on this
* specific scheduling load.
* This method must be invoked before any call to Simulator::run
* @param filename the name of the file to log to
*/
static void enableLogTo (char const *filename);
/**
* Enable logging to the file identified by filename. If the file
* does not exist, it is created. If it exists, it is destroyed and
* re-created. Every scheduling event is logged to this file in a
* simple text format which can be read back by the event replay
* utility. This allows you to record the scheduling behavior of
* a simulation, and measure the exact overhead related to
* event scheduling with the event replay utility. It is also possible
* to compare the performance of every scheduling algorithms on this
* specific scheduling load.
* This method must be invoked before any call to Simulator::run
* @param filename the name of the file to log to
*/
static void enableLogTo (char const *filename);
/**
* Every event scheduled by the Simulator::insertAtDestroy method is
* invoked. Then, we ensure that any memory allocated by the
* Simulator is freed.
* This method is typically invoked at the end of a simulation
* to avoid false-positive reports by a leak checker.
* After this method has been invoked, it is actually possible
* to restart a new simulation with a set of calls to Simulator::run
* and Simulator::insert_*.
*/
static void destroy (void);
/**
* Every event scheduled by the Simulator::insertAtDestroy method is
* invoked. Then, we ensure that any memory allocated by the
* Simulator is freed.
* This method is typically invoked at the end of a simulation
* to avoid false-positive reports by a leak checker.
* After this method has been invoked, it is actually possible
* to restart a new simulation with a set of calls to Simulator::run
* and Simulator::insert_*.
*/
static void destroy (void);
/**
* If there any any events lefts to be scheduled, return
* true. Return false otherwise.
*/
static bool isFinished (void);
/**
* If Simulator::isFinished returns true, the behavior of this
* method is undefined. Otherwise, it returns the microsecond-based
* time of the next event expected to be scheduled.
*/
static Time next (void);
/**
* If there any any events lefts to be scheduled, return
* true. Return false otherwise.
*/
static bool isFinished (void);
/**
* If Simulator::isFinished returns true, the behavior of this
* method is undefined. Otherwise, it returns the microsecond-based
* time of the next event expected to be scheduled.
*/
static Time next (void);
/**
* Run the simulation until one of:
* - no events are present anymore
* - the user called Simulator::stop
* - the user called Simulator::stopAtUs and the
* expiration time of the next event to be processed
* is greater than or equal to the stop time.
*/
static void run (void);
/**
* If an event invokes this method, it will be the last
* event scheduled by the Simulator::run method before
* returning to the caller.
*/
static void stop (void);
/**
* Force the Simulator::run method to return to the caller
* when the expiration time of the next event to be processed
* is greater than or equal to the stop time.
* @param at the stop time.
*/
static void stopAt (Time time);
/**
* Run the simulation until one of:
* - no events are present anymore
* - the user called Simulator::stop
* - the user called Simulator::stopAtUs and the
* expiration time of the next event to be processed
* is greater than or equal to the stop time.
*/
static void run (void);
/**
* If an event invokes this method, it will be the last
* event scheduled by the Simulator::run method before
* returning to the caller.
*/
static void stop (void);
/**
* Force the Simulator::run method to return to the caller
* when the expiration time of the next event to be processed
* is greater than or equal to the stop time.
* @param at the stop time.
*/
static void stopAt (Time time);
/**
* Schedule an event to expire at time.
*
* @param delta the expiration time of the event.
* @param event the event to schedule.
* @returns an id for the scheduled event.
*/
template <typename T>
static EventId schedule (Time time, void (T::*mem_ptr) (void), T *obj) {
// zero argument version
class EventMemberImpl0 : public EventImpl {
public:
typedef void (T::*F)(void);
EventMemberImpl0 (T *obj, F function)
: m_obj (obj),
m_function (function)
{}
virtual ~EventMemberImpl0 () {}
private:
virtual void notify (void) {
(m_obj->*m_function) ();
}
T* m_obj;
F m_function;
} *ev = new EventMemberImpl0 (obj, mem_ptr);
return schedule (time, ev);
}
template <typename T, typename T1>
static EventId schedule (Time time, void (T::*f) (T1), T* t, T1 a1) {
// one argument version
class EventMemberImpl1 : public EventImpl {
public:
typedef void (T::*F)(T1);
EventMemberImpl1 (T *obj, F function, T1 a1)
: m_obj (obj),
m_function (function),
m_a1 (a1)
{}
protected:
virtual ~EventMemberImpl1 () {}
private:
virtual void notify (void) {
(m_obj->*m_function) (m_a1);
}
T* m_obj;
F m_function;
T1 m_a1;
} *ev = new EventMemberImpl1 (t, f, a1);
return schedule (time, ev);
}
template <typename T, typename T1, typename T2>
static EventId schedule (Time time, void (T::*f) (T1), T* t, T1 a1, T2 a2) {
// two argument version
class EventMemberImpl2 : public EventImpl {
public:
typedef void (T::*F)(T1, T2);
EventMemberImpl2 (T *obj, F 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) {
(m_obj->*m_function) (m_a1, m_a2);
}
T* m_obj;
F m_function;
T1 m_a1;
T2 m_a2;
} *ev = new EventMemberImpl2 (t, f, a1, a2);
/**
* Schedule an event to expire at time.
*
* @param delta the expiration time of the event.
* @param event the event to schedule.
* @returns an id for the scheduled event.
*/
template <typename T>
static EventId schedule (Time time, void (T::*mem_ptr) (void), T *obj) {
// zero argument version
class EventMemberImpl0 : public EventImpl {
public:
typedef void (T::*F)(void);
EventMemberImpl0 (T *obj, F function)
: m_obj (obj),
m_function (function)
{}
virtual ~EventMemberImpl0 () {}
private:
virtual void notify (void) {
(m_obj->*m_function) ();
}
T* m_obj;
F m_function;
} *ev = new EventMemberImpl0 (obj, mem_ptr);
return schedule (time, ev);
}
template <typename T, typename T1>
static EventId schedule (Time time, void (T::*f) (T1), T* t, T1 a1) {
// one argument version
class EventMemberImpl1 : public EventImpl {
public:
typedef void (T::*F)(T1);
EventMemberImpl1 (T *obj, F function, T1 a1)
: m_obj (obj),
m_function (function),
m_a1 (a1)
{}
protected:
virtual ~EventMemberImpl1 () {}
private:
virtual void notify (void) {
(m_obj->*m_function) (m_a1);
}
T* m_obj;
F m_function;
T1 m_a1;
} *ev = new EventMemberImpl1 (t, f, a1);
return schedule (time, ev);
}
template <typename T, typename T1, typename T2>
static EventId schedule (Time time, void (T::*f) (T1), T* t, T1 a1, T2 a2) {
// two argument version
class EventMemberImpl2 : public EventImpl {
public:
typedef void (T::*F)(T1, T2);
EventMemberImpl2 (T *obj, F 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) {
(m_obj->*m_function) (m_a1, m_a2);
}
T* m_obj;
F m_function;
T1 m_a1;
T2 m_a2;
} *ev = new EventMemberImpl2 (t, f, a1, a2);
return schedule (time, ev);
}
template <typename T, typename T1, typename T2, typename T3>
static EventId schedule (Time time, void (T::*f) (T1), T* t, T1 a1, T2 a2, T3 a3) {
// three argument version
class EventMemberImpl3 : public EventImpl {
public:
typedef void (T::*F)(T1, T2, T3);
EventMemberImpl3 (T *obj, F 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) {
(m_obj->*m_function) (m_a1, m_a2, m_a3);
}
T* m_obj;
F m_function;
T1 m_a1;
T2 m_a2;
T3 m_a3;
} *ev = new EventMemberImpl3 (t, f, a1, a2, a3);
return schedule (time, ev);
}
template <typename T, typename T1, typename T2, typename T3, typename T4>
static EventId schedule (Time time, void (T::*f) (T1), T* t, T1 a1, T2 a2, T3 a3, T4 a4) {
// four argument version
class EventMemberImpl4 : public EventImpl {
public:
typedef void (T::*F)(T1, T2, T3, T4);
EventMemberImpl4 (T *obj, F 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) {
(m_obj->*m_function) (m_a1, m_a2, m_a3, m_a4);
}
T* m_obj;
F m_function;
T1 m_a1;
T2 m_a2;
T3 m_a3;
T4 m_a4;
} *ev = new EventMemberImpl4 (t, f, a1, a2, a3, a4);
return schedule (time, ev);
}
template <typename T, typename T1, typename T2, typename T3, typename T4, typename T5>
static EventId schedule (Time time, void (T::*f) (T1), T* t,
T1 a1, T2 a2, T3 a3, T4 a4, T5 a5) {
// five argument version
class EventMemberImpl5 : public EventImpl {
public:
typedef void (T::*F)(T1, T2, T3, T4, T5);
EventMemberImpl5 (T *obj, F 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) {
(m_obj->*m_function) (m_a1, m_a2, m_a3, m_a4, m_a5);
}
T* m_obj;
F m_function;
T1 m_a1;
T2 m_a2;
T3 m_a3;
T4 m_a4;
T5 m_a5;
} *ev = new EventMemberImpl5 (t, f, a1, a2, a3, a4, a5);
return schedule (time, ev);
}
static EventId schedule (Time time, void (*f) (void)) {
// zero arg version
class EventFunctionImpl0 : public EventImpl {
public:
typedef void (*F)(void);
EventFunctionImpl0 (F function)
: m_function (function)
{}
protected:
virtual void notify (void) {
(*m_function) ();
}
private:
virtual ~EventFunctionImpl0 () {}
F m_function;
} *ev = new EventFunctionImpl0 (f);
return schedule (time, ev);
}
template <typename T1>
static EventId schedule (Time time, void (*f) (T1), T1 a1) {
// one arg version
class EventFunctionImpl1 : public EventImpl {
public:
typedef void (*F)(T1);
EventFunctionImpl1 (F function, T1 a1)
: m_function (function),
m_a1 (a1)
{ }
protected:
virtual ~EventFunctionImpl1 () {}
private:
virtual void notify (void) {
(*m_function) (m_a1);
}
F m_function;
T1 m_a1;
} *ev = new EventFunctionImpl1(f, a1);
return schedule (time, ev);
}
template <typename T1, typename T2>
static EventId schedule (Time time, void (*f) (T1), T1 a1, T2 a2) {
// two arg version
class EventFunctionImpl2 : public EventImpl {
public:
typedef void (*F)(T1, T2);
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);
}
F m_function;
T1 m_a1;
T2 m_a2;
} *ev = new EventFunctionImpl2 (f, a1, a2);
return schedule (time, ev);
}
template <typename T1, typename T2, typename T3>
static EventId schedule (Time time, void (*f) (T1), T1 a1, T2 a2, T3 a3) {
// three arg version
class EventFunctionImpl3 : public EventImpl {
public:
typedef void (*F)(T1, T2, T3);
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);
}
F m_function;
T1 m_a1;
T2 m_a2;
T3 m_a3;
} *ev = new EventFunctionImpl3 (f, a1, a2, a3);
return schedule (time, ev);
}
template <typename T1, typename T2, typename T3, typename T4>
static EventId schedule (Time time, void (*f) (T1), T1 a1, T2 a2, T3 a3, T4 a4) {
// four arg version
class EventFunctionImpl4 : public EventImpl {
public:
typedef void (*F)(T1, T2, T3, T4);
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);
}
F m_function;
T1 m_a1;
T2 m_a2;
T3 m_a3;
T4 m_a4;
} *ev = new EventFunctionImpl4 (f, a1, a2, a3, a4);
return schedule (time, ev);
}
template <typename T1, typename T2, typename T3, typename T4, typename T5>
static EventId schedule (Time time, void (*f) (T1), T1 a1, T2 a2, T3 a3, T4 a4, T5 a5) {
// five arg version
class EventFunctionImpl5 : public EventImpl {
public:
typedef void (*F)(T1, T2, T3, T4, T5);
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);
}
F m_function;
T1 m_a1;
T2 m_a2;
T3 m_a3;
T4 m_a4;
T5 m_a5;
} *ev = new EventFunctionImpl5 (f, a1, a2, a3, a4, a5);
return schedule (time, ev);
}
/**
* Unschedule the event. i.e.: the removed event never expires.
* @param id the event to remove from the list of scheduled events.
*/
static void remove (EventId id);
/*
XXX
*/
static void cancel (EventId id);
/*
XXX
*/
static bool isExpired (EventId id);
/**
* Return the "current time".
*/
static Time now (void);
return schedule (time, ev);
}
template <typename T, typename T1, typename T2, typename T3>
static EventId schedule (Time time, void (T::*f) (T1), T* t, T1 a1, T2 a2, T3 a3) {
// three argument version
class EventMemberImpl3 : public EventImpl {
public:
typedef void (T::*F)(T1, T2, T3);
EventMemberImpl3 (T *obj, F 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) {
(m_obj->*m_function) (m_a1, m_a2, m_a3);
}
T* m_obj;
F m_function;
T1 m_a1;
T2 m_a2;
T3 m_a3;
} *ev = new EventMemberImpl3 (t, f, a1, a2, a3);
return schedule (time, ev);
}
template <typename T, typename T1, typename T2, typename T3, typename T4>
static EventId schedule (Time time, void (T::*f) (T1), T* t, T1 a1, T2 a2, T3 a3, T4 a4) {
// four argument version
class EventMemberImpl4 : public EventImpl {
public:
typedef void (T::*F)(T1, T2, T3, T4);
EventMemberImpl4 (T *obj, F 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) {
(m_obj->*m_function) (m_a1, m_a2, m_a3, m_a4);
}
T* m_obj;
F m_function;
T1 m_a1;
T2 m_a2;
T3 m_a3;
T4 m_a4;
} *ev = new EventMemberImpl4 (t, f, a1, a2, a3, a4);
return schedule (time, ev);
}
template <typename T, typename T1, typename T2, typename T3, typename T4, typename T5>
static EventId schedule (Time time, void (T::*f) (T1), T* t,
T1 a1, T2 a2, T3 a3, T4 a4, T5 a5) {
// five argument version
class EventMemberImpl5 : public EventImpl {
public:
typedef void (T::*F)(T1, T2, T3, T4, T5);
EventMemberImpl5 (T *obj, F 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) {
(m_obj->*m_function) (m_a1, m_a2, m_a3, m_a4, m_a5);
}
T* m_obj;
F m_function;
T1 m_a1;
T2 m_a2;
T3 m_a3;
T4 m_a4;
T5 m_a5;
} *ev = new EventMemberImpl5 (t, f, a1, a2, a3, a4, a5);
return schedule (time, ev);
}
static EventId schedule (Time time, void (*f) (void)) {
// zero arg version
class EventFunctionImpl0 : public EventImpl {
public:
typedef void (*F)(void);
EventFunctionImpl0 (F function)
: m_function (function)
{}
protected:
virtual void notify (void) {
(*m_function) ();
}
private:
virtual ~EventFunctionImpl0 () {}
F m_function;
} *ev = new EventFunctionImpl0 (f);
return schedule (time, ev);
}
template <typename T1>
static EventId schedule (Time time, void (*f) (T1), T1 a1) {
// one arg version
class EventFunctionImpl1 : public EventImpl {
public:
typedef void (*F)(T1);
EventFunctionImpl1 (F function, T1 a1)
: m_function (function),
m_a1 (a1)
{ }
protected:
virtual ~EventFunctionImpl1 () {}
private:
virtual void notify (void) {
(*m_function) (m_a1);
}
F m_function;
T1 m_a1;
} *ev = new EventFunctionImpl1(f, a1);
return schedule (time, ev);
}
template <typename T1, typename T2>
static EventId schedule (Time time, void (*f) (T1), T1 a1, T2 a2) {
// two arg version
class EventFunctionImpl2 : public EventImpl {
public:
typedef void (*F)(T1, T2);
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);
}
F m_function;
T1 m_a1;
T2 m_a2;
} *ev = new EventFunctionImpl2 (f, a1, a2);
return schedule (time, ev);
}
template <typename T1, typename T2, typename T3>
static EventId schedule (Time time, void (*f) (T1), T1 a1, T2 a2, T3 a3) {
// three arg version
class EventFunctionImpl3 : public EventImpl {
public:
typedef void (*F)(T1, T2, T3);
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);
}
F m_function;
T1 m_a1;
T2 m_a2;
T3 m_a3;
} *ev = new EventFunctionImpl3 (f, a1, a2, a3);
return schedule (time, ev);
}
template <typename T1, typename T2, typename T3, typename T4>
static EventId schedule (Time time, void (*f) (T1), T1 a1, T2 a2, T3 a3, T4 a4) {
// four arg version
class EventFunctionImpl4 : public EventImpl {
public:
typedef void (*F)(T1, T2, T3, T4);
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);
}
F m_function;
T1 m_a1;
T2 m_a2;
T3 m_a3;
T4 m_a4;
} *ev = new EventFunctionImpl4 (f, a1, a2, a3, a4);
return schedule (time, ev);
}
template <typename T1, typename T2, typename T3, typename T4, typename T5>
static EventId schedule (Time time, void (*f) (T1), T1 a1, T2 a2, T3 a3, T4 a4, T5 a5) {
// five arg version
class EventFunctionImpl5 : public EventImpl {
public:
typedef void (*F)(T1, T2, T3, T4, T5);
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);
}
F m_function;
T1 m_a1;
T2 m_a2;
T3 m_a3;
T4 m_a4;
T5 m_a5;
} *ev = new EventFunctionImpl5 (f, a1, a2, a3, a4, a5);
return schedule (time, ev);
}
/**
* Unschedule the event. i.e.: the removed event never expires.
* @param id the event to remove from the list of scheduled events.
*/
static void remove (EventId id);
/*
XXX
*/
static void cancel (EventId id);
/*
XXX
*/
static bool isExpired (EventId id);
/**
* Return the "current time".
*/
static Time now (void);
private:
Simulator ();
~Simulator ();
static SimulatorPrivate *getPriv (void);
static EventId schedule (Time time, EventImpl *event);
static SimulatorPrivate *m_priv;
static SchedulerFactory const*m_schedFactory;
static enum ListType {
LINKED_LIST,
BINARY_HEAP,
STD_MAP,
EXTERNAL
} m_listType;
Simulator ();
~Simulator ();
static SimulatorPrivate *getPriv (void);
static EventId schedule (Time time, EventImpl *event);
static SimulatorPrivate *m_priv;
static SchedulerFactory const*m_schedFactory;
static enum ListType {
LINKED_LIST,
BINARY_HEAP,
STD_MAP,
EXTERNAL
} m_listType;
};
}; // namespace ns3

80
src/simulator/time.cc

@ -1,4 +1,4 @@
/* -*- Mode:C++; c-basic-offset:8; tab-width:8; indent-tabs-mode:t -*- */
/* -*- Mode:C++; c-basic-offset:4; tab-width:4; indent-tabs-mode:f -*- */
/*
* Copyright (c) 2005,2006 INRIA
* All rights reserved.
@ -24,94 +24,94 @@
namespace ns3 {
Time::Time ()
: m_ns (0),
m_isDestroy (true)
: m_ns (0),
m_isDestroy (true)
{}
Time::Time (Time const &o)
: m_ns (o.m_ns),
m_isDestroy (o.m_isDestroy)
: m_ns (o.m_ns),
m_isDestroy (o.m_isDestroy)
{}
Time &
Time::operator = (Time const &o)
{
m_ns = o.m_ns;
m_isDestroy = o.m_isDestroy;
return *this;
m_ns = o.m_ns;
m_isDestroy = o.m_isDestroy;
return *this;
}
Time::Time (uint64_t ns)
: m_ns (ns),
m_isDestroy (false)
: m_ns (ns),
m_isDestroy (false)
{}
double
Time::s (void) const
{
double ns = m_ns;
ns /= 1000000000;
return ns;
double ns = m_ns;
ns /= 1000000000;
return ns;
}
uint64_t
Time::us (void) const
{
uint64_t us = m_ns / 1000;
return us;
uint64_t us = m_ns / 1000;
return us;
}
uint64_t
Time::ns (void) const
{
return m_ns;
return m_ns;
}
bool
Time::isDestroy (void) const
{
return m_isDestroy;
return m_isDestroy;
}
Time
Time::absS (double s)
{
int64_t ns = (int64_t)(s * 1000000000.0);
return Time (ns);
int64_t ns = (int64_t)(s * 1000000000.0);
return Time (ns);
}
Time
Time::absUs (uint64_t us)
{
int64_t ns = us * 1000;
return Time (ns);
int64_t ns = us * 1000;
return Time (ns);
}
Time
Time::absNs (uint64_t ns)
{
return Time (ns);
return Time (ns);
}
Time
Time::relS (double s)
{
int64_t ns = (int64_t)(s * 1000000000.0);
return Time (Simulator::now ().ns () + ns);
int64_t ns = (int64_t)(s * 1000000000.0);
return Time (Simulator::now ().ns () + ns);
}
Time
Time::relUs (uint64_t us)
{
return Time (Simulator::now ().ns () + us * 1000);
return Time (Simulator::now ().ns () + us * 1000);
}
Time
Time::relNs (uint64_t ns)
{
return Time (Simulator::now ().ns () + ns);
return Time (Simulator::now ().ns () + ns);
}
Time
Time::now (void)
{
return Time (Simulator::now ().ns ());
return Time (Simulator::now ().ns ());
}
Time
Time::destroy (void)
{
return Time ();
return Time ();
}
/***
@ -121,51 +121,51 @@ Time::destroy (void)
*/
class AbsTimeS : public Time {
public:
AbsTimeS (double s);
AbsTimeS (double s);
};
class AbsTimeUs : public Time {
public:
AbsTimeUs (uint64_t us);
AbsTimeUs (uint64_t us);
};
class RelTimeS : public Time {
public:
RelTimeS (double s);
RelTimeS (double s);
};
class RelTimeUs : public Time {
public:
RelTimeUs (uint64_t us);
RelTimeUs (uint64_t us);
};
class NowTime : public Time {
public:
NowTime ();
NowTime ();
};
class DestroyTime : public Time {
public:
DestroyTime ();
DestroyTime ();
};
AbsTimeS::AbsTimeS (double s)
: Time ((uint64_t)(int64_t)(s * 1000000000.0))
: Time ((uint64_t)(int64_t)(s * 1000000000.0))
{}
AbsTimeUs::AbsTimeUs (uint64_t us)
: Time (us*1000)
: Time (us*1000)
{}
RelTimeS::RelTimeS (double s)
: Time (Simulator::now ().ns () + (int64_t)(s * 1000000000.0))
: Time (Simulator::now ().ns () + (int64_t)(s * 1000000000.0))
{}
RelTimeUs::RelTimeUs (uint64_t us)
: Time (Simulator::now ().ns () + us*1000)
: Time (Simulator::now ().ns () + us*1000)
{}
NowTime::NowTime ()
: Time (Simulator::now ().ns ())
: Time (Simulator::now ().ns ())
{}
DestroyTime::DestroyTime ()
: Time ()
: Time ()
{}
}; // namespace ns3

38
src/simulator/time.h

@ -1,4 +1,4 @@
/* -*- Mode:C++; c-basic-offset:8; tab-width:8; indent-tabs-mode:t -*- */
/* -*- Mode:C++; c-basic-offset:4; tab-width:4; indent-tabs-mode:f -*- */
/*
* Copyright (c) 2005,2006 INRIA
* All rights reserved.
@ -27,26 +27,26 @@ namespace ns3 {
class Time {
public:
Time (Time const &o);
Time &operator = (Time const &o);
double s (void) const;
uint64_t us (void) const;
uint64_t ns (void) const;
bool isDestroy (void) const;
static Time absS (double s);
static Time absUs (uint64_t us);
static Time absNs (uint64_t ns);
static Time relS (double s);
static Time relUs (uint64_t us);
static Time relNs (uint64_t ns);
static Time now (void);
static Time destroy (void);
Time (Time const &o);
Time &operator = (Time const &o);
double s (void) const;
uint64_t us (void) const;
uint64_t ns (void) const;
bool isDestroy (void) const;
static Time absS (double s);
static Time absUs (uint64_t us);
static Time absNs (uint64_t ns);
static Time relS (double s);
static Time relUs (uint64_t us);
static Time relNs (uint64_t ns);
static Time now (void);
static Time destroy (void);
protected:
Time (uint64_t ns);
Time ();
Time (uint64_t ns);
Time ();
private:
uint64_t m_ns;
bool m_isDestroy;
uint64_t m_ns;
bool m_isDestroy;
};

134
utils/bench-packets.cc

@ -1,4 +1,4 @@
/* -*- Mode:C++; c-basic-offset:8; tab-width:8; indent-tabs-mode:t -*- */
/* -*- Mode:C++; c-basic-offset:4; tab-width:4; indent-tabs-mode:f -*- */
/*
* Copyright (c) 2006 INRIA
* All rights reserved.
@ -30,106 +30,106 @@ using namespace ns3;
static void
benchPtrA (uint32_t n)
{
ChunkConstantData data = ChunkConstantData (2000, 1);
ChunkUdp udp;
ChunkIpv4 ipv4;
ChunkConstantData data = ChunkConstantData (2000, 1);
ChunkUdp udp;
ChunkIpv4 ipv4;
for (uint32_t i = 0; i < n; i++) {
Packet p;
p.add (&data);
p.add (&udp);
p.add (&ipv4);
Packet o = p;
o.peek (&ipv4);
o.remove (&ipv4);
o.peek (&udp);
o.remove (&udp);
o.peek (&data);
o.remove (&data);
}
for (uint32_t i = 0; i < n; i++) {
Packet p;
p.add (&data);
p.add (&udp);
p.add (&ipv4);
Packet o = p;
o.peek (&ipv4);
o.remove (&ipv4);
o.peek (&udp);
o.remove (&udp);
o.peek (&data);
o.remove (&data);
}
}
static void
benchPtrB (uint32_t n)
{
ChunkConstantData data = ChunkConstantData (2000, 1);
ChunkUdp udp;
ChunkIpv4 ipv4;
ChunkConstantData data = ChunkConstantData (2000, 1);
ChunkUdp udp;
ChunkIpv4 ipv4;
for (uint32_t i = 0; i < n; i++) {
Packet p;
p.add (&data);
p.add (&udp);
p.add (&ipv4);
}
for (uint32_t i = 0; i < n; i++) {
Packet p;
p.add (&data);
p.add (&udp);
p.add (&ipv4);
}
}
static void
ptrC2 (Packet p)
{
ChunkConstantData data = ChunkConstantData (2000, 1);
ChunkUdp udp;
ChunkConstantData data = ChunkConstantData (2000, 1);
ChunkUdp udp;
p.peek (&udp);
p.remove (&udp);
p.peek (&data);
p.remove (&data);
p.peek (&udp);
p.remove (&udp);
p.peek (&data);
p.remove (&data);
}
static void
ptrC1 (Packet p)
{
ChunkIpv4 ipv4;
p.peek (&ipv4);
p.remove (&ipv4);
ptrC2 (p);
ChunkIpv4 ipv4;
p.peek (&ipv4);
p.remove (&ipv4);
ptrC2 (p);
}
static void
benchPtrC (uint32_t n)
{
ChunkConstantData data = ChunkConstantData (2000, 1);
ChunkUdp udp;
ChunkIpv4 ipv4;
ChunkConstantData data = ChunkConstantData (2000, 1);
ChunkUdp udp;
ChunkIpv4 ipv4;
for (uint32_t i = 0; i < n; i++) {
Packet p;
p.add (&data);
p.add (&udp);
p.add (&ipv4);
ptrC1 (p);
}
for (uint32_t i = 0; i < n; i++) {
Packet p;
p.add (&data);
p.add (&udp);
p.add (&ipv4);
ptrC1 (p);
}
}
static void
runBench (void (*bench) (uint32_t), uint32_t n, char const *name)
{
WallClockMs time;
time.start ();
(*bench) (n);
unsigned long long deltaMs = time.end ();
double ps = n;
ps *= 1000;
ps /= deltaMs;
std::cout << name<<"=" << ps << " packets/s" << std::endl;
WallClockMs time;
time.start ();
(*bench) (n);
unsigned long long deltaMs = time.end ();
double ps = n;
ps *= 1000;
ps /= deltaMs;
std::cout << name<<"=" << ps << " packets/s" << std::endl;
}
int main (int argc, char *argv[])
{
uint32_t n = 0;
while (argc > 0) {
if (strncmp ("--n=", argv[0],strlen ("--n=")) == 0) {
char const *nAscii = argv[0] + strlen ("--n=");
n = atoi (nAscii);
}
argc--;
argv++;
}
uint32_t n = 0;
while (argc > 0) {
if (strncmp ("--n=", argv[0],strlen ("--n=")) == 0) {
char const *nAscii = argv[0] + strlen ("--n=");
n = atoi (nAscii);
}
argc--;
argv++;
}
runBench (&benchPtrA, n, "a");
runBench (&benchPtrB, n, "b");
runBench (&benchPtrC, n, "c");
runBench (&benchPtrA, n, "a");
runBench (&benchPtrB, n, "b");
runBench (&benchPtrC, n, "c");
return 0;
return 0;
}

166
utils/bench-simulator.cc

@ -1,4 +1,4 @@
/* -*- Mode:C++; c-basic-offset:8; tab-width:8; indent-tabs-mode:t -*- */
/* -*- Mode:C++; c-basic-offset:4; tab-width:4; indent-tabs-mode:f -*- */
/*
* Copyright (c) 2006 INRIA
* All rights reserved.
@ -32,115 +32,115 @@ bool gDebug = false;
class Bench {
public:
void readDistribution (std::istream &istream);
void setTotal (uint32_t total);
void bench (void);
void readDistribution (std::istream &istream);
void setTotal (uint32_t total);
void bench (void);
private:
void cb (void);
std::vector<uint64_t> m_distribution;
std::vector<uint64_t>::const_iterator m_current;
uint32_t m_n;
uint32_t m_total;
void cb (void);
std::vector<uint64_t> m_distribution;
std::vector<uint64_t>::const_iterator m_current;
uint32_t m_n;
uint32_t m_total;
};
void
Bench::setTotal (uint32_t total)
{
m_total = total;
m_total = total;
}
void
Bench::readDistribution (std::istream &input)
{
double data;
while (!input.eof ()) {
if (input >> data) {
uint64_t ns = (uint64_t) (data * 1000000000);
m_distribution.push_back (ns);
} else {
input.clear ();
std::string line;
input >> line;
}
}
double data;
while (!input.eof ()) {
if (input >> data) {
uint64_t ns = (uint64_t) (data * 1000000000);
m_distribution.push_back (ns);
} else {
input.clear ();
std::string line;
input >> line;
}
}
}
void
Bench::bench (void)
{
SystemWallClockMs time;
double init, simu;
time.start ();
for (std::vector<uint64_t>::const_iterator i = m_distribution.begin ();
i != m_distribution.end (); i++) {
Simulator::schedule (Time::absNs (*i), &Bench::cb, this);
}
init = time.end ();
SystemWallClockMs time;
double init, simu;
time.start ();
for (std::vector<uint64_t>::const_iterator i = m_distribution.begin ();
i != m_distribution.end (); i++) {
Simulator::schedule (Time::absNs (*i), &Bench::cb, this);
}
init = time.end ();
m_current = m_distribution.begin ();
m_current = m_distribution.begin ();
time.start ();
Simulator::run ();
simu = time.end ();
time.start ();
Simulator::run ();
simu = time.end ();
std::cout <<
"init n=" << m_distribution.size () << ", time=" << init << "s" << std::endl <<
"simu n=" << m_n << ", time=" <<simu << "s" << std::endl <<
"init " << ((double)m_distribution.size ()) / init << " insert/s, avg insert=" <<
init / ((double)m_distribution.size ())<< "s" << std::endl <<
"simu " << ((double)m_n) / simu<< " hold/s, avg hold=" <<
simu / ((double)m_n) << "s" << std::endl
;
std::cout <<
"init n=" << m_distribution.size () << ", time=" << init << "s" << std::endl <<
"simu n=" << m_n << ", time=" <<simu << "s" << std::endl <<
"init " << ((double)m_distribution.size ()) / init << " insert/s, avg insert=" <<
init / ((double)m_distribution.size ())<< "s" << std::endl <<
"simu " << ((double)m_n) / simu<< " hold/s, avg hold=" <<
simu / ((double)m_n) << "s" << std::endl
;
}
void
Bench::cb (void)
{
if (m_n > m_total) {
return;
}
if (m_current == m_distribution.end ()) {
m_current = m_distribution.begin ();
}
if (gDebug) {
std::cerr << "event at " << Simulator::now ().s () << "s" << std::endl;
}
Simulator::schedule (Time::absNs (*m_current), &Bench::cb, this);
m_current++;
m_n++;
if (m_n > m_total) {
return;
}
if (m_current == m_distribution.end ()) {
m_current = m_distribution.begin ();
}
if (gDebug) {
std::cerr << "event at " << Simulator::now ().s () << "s" << std::endl;
}
Simulator::schedule (Time::absNs (*m_current), &Bench::cb, this);
m_current++;
m_n++;
}
int main (int argc, char *argv[])
{
char const *filename = argv[1];
std::istream *input;
argc-=2;
argv+= 2;
if (strcmp (filename, "-") == 0) {
input = &std::cin;
} else {
input = new std::ifstream (filename);
}
while (argc > 0) {
if (strcmp ("--list", argv[0]) == 0) {
Simulator::setLinkedList ();
} else if (strcmp ("--heap", argv[0]) == 0) {
Simulator::setBinaryHeap ();
} else if (strcmp ("--map", argv[0]) == 0) {
Simulator::setStdMap ();
} else if (strcmp ("--debug", argv[0]) == 0) {
gDebug = true;
} else if (strncmp ("--log=", argv[0],strlen ("--log=")) == 0) {
char const *filename = argv[0] + strlen ("--log=");
Simulator::enableLogTo (filename);
}
argc--;
argv++;
}
Bench *bench = new Bench ();
bench->readDistribution (*input);
bench->setTotal (20000);
bench->bench ();
char const *filename = argv[1];
std::istream *input;
argc-=2;
argv+= 2;
if (strcmp (filename, "-") == 0) {
input = &std::cin;
} else {
input = new std::ifstream (filename);
}
while (argc > 0) {
if (strcmp ("--list", argv[0]) == 0) {
Simulator::setLinkedList ();
} else if (strcmp ("--heap", argv[0]) == 0) {
Simulator::setBinaryHeap ();
} else if (strcmp ("--map", argv[0]) == 0) {
Simulator::setStdMap ();
} else if (strcmp ("--debug", argv[0]) == 0) {
gDebug = true;
} else if (strncmp ("--log=", argv[0],strlen ("--log=")) == 0) {
char const *filename = argv[0] + strlen ("--log=");
Simulator::enableLogTo (filename);
}
argc--;
argv++;
}
Bench *bench = new Bench ();
bench->readDistribution (*input);
bench->setTotal (20000);
bench->bench ();
return 0;
return 0;
}

400
utils/replay-simulation.cc

@ -1,4 +1,4 @@
/* -*- Mode:C++; c-basic-offset:8; tab-width:8; indent-tabs-mode:t -*- */
/* -*- Mode:C++; c-basic-offset:4; tab-width:4; indent-tabs-mode:f -*- */
/*
* Copyright (c) 2006 INRIA
* All rights reserved.
@ -32,45 +32,45 @@ using namespace ns3;
class LogReader {
public:
void readFrom_filename (char const *filename);
void run (void);
void printStats (void);
void readFrom_filename (char const *filename);
void run (void);
void printStats (void);
private:
struct Command {
enum {
REMOVE,
INSERT,
INSERT_LATER,
INSERT_REMOVE
} m_type;
// uid at which this command is supposed to be executed.
uint32_t m_uid;
union {
struct {
// time at which the event is supposed to expire
uint64_t m_evUs;
} insert;
struct {
// location in the array of events to remove where
// to insert this event once it is inserted in
// the scheduler.
uint32_t m_evLoc;
// time at which the event is supposed to expire
uint64_t m_evUs;
} insertRemove;
};
};
void executeLogCommands (uint32_t uid);
struct Command {
enum {
REMOVE,
INSERT,
INSERT_LATER,
INSERT_REMOVE
} m_type;
// uid at which this command is supposed to be executed.
uint32_t m_uid;
union {
struct {
// time at which the event is supposed to expire
uint64_t m_evUs;
} insert;
struct {
// location in the array of events to remove where
// to insert this event once it is inserted in
// the scheduler.
uint32_t m_evLoc;
// time at which the event is supposed to expire
uint64_t m_evUs;
} insertRemove;
};
};
void executeLogCommands (uint32_t uid);
typedef std::deque<struct Command> Commands;
typedef std::deque<struct Command>::iterator CommandsI;
typedef std::deque<Event > RemoveEvents;
typedef std::deque<struct Command> Commands;
typedef std::deque<struct Command>::iterator CommandsI;
typedef std::deque<Event > RemoveEvents;
Commands m_commands;
CommandsI m_command;
RemoveEvents m_removeEvents;
uint32_t m_uid;
Commands m_commands;
CommandsI m_command;
RemoveEvents m_removeEvents;
uint32_t m_uid;
};
typedef std::vector<std::pair<uint32_t, uint32_t> > Removes;
@ -79,187 +79,187 @@ typedef std::vector<std::pair<uint32_t, uint32_t> >::iterator RemovesI;
void
LogReader::readFrom_filename (char const *filename)
{
std::ifstream log;
std::cout << "read log..." << std::endl;
Removes removes;
log.open (filename);
while (!log.eof ()) {
std::string type;
log >> type;
if (type == "i") {
uint32_t nowUid, evUid;
uint64_t nowUs, evUs;
log >> nowUid >> nowUs >> evUid >> evUs;
struct Command cmd;
cmd.m_type = Command::INSERT;
cmd.m_uid = nowUid;
cmd.insert.m_evUs = evUs;
m_commands.push_back (cmd);
} else if (type == "r") {
uint32_t nowUid, evUid;
uint64_t nowUs, evUs;
log >> nowUid >> nowUs >> evUid >> evUs;
struct Command cmd;
cmd.m_type = Command::REMOVE;
cmd.m_uid = nowUid;
m_commands.push_back (cmd);
removes.push_back (std::make_pair (nowUid, evUid));
} else if (type == "il") {
uint32_t nowUid, evUid;
uint64_t nowUs, evUs;
log >> nowUid >> nowUs >> evUid >> evUs;
struct Command cmd;
cmd.m_type = Command::INSERT_LATER;
cmd.m_uid = nowUid;
m_commands.push_back (cmd);
}
}
log.close ();
std::ifstream log;
std::cout << "read log..." << std::endl;
Removes removes;
log.open (filename);
while (!log.eof ()) {
std::string type;
log >> type;
if (type == "i") {
uint32_t nowUid, evUid;
uint64_t nowUs, evUs;
log >> nowUid >> nowUs >> evUid >> evUs;
struct Command cmd;
cmd.m_type = Command::INSERT;
cmd.m_uid = nowUid;
cmd.insert.m_evUs = evUs;
m_commands.push_back (cmd);
} else if (type == "r") {
uint32_t nowUid, evUid;
uint64_t nowUs, evUs;
log >> nowUid >> nowUs >> evUid >> evUs;
struct Command cmd;
cmd.m_type = Command::REMOVE;
cmd.m_uid = nowUid;
m_commands.push_back (cmd);
removes.push_back (std::make_pair (nowUid, evUid));
} else if (type == "il") {
uint32_t nowUid, evUid;
uint64_t nowUs, evUs;
log >> nowUid >> nowUs >> evUid >> evUs;
struct Command cmd;
cmd.m_type = Command::INSERT_LATER;
cmd.m_uid = nowUid;
m_commands.push_back (cmd);
}
}
log.close ();
std::cout << "gather insert removes..." << std::endl;
for (CommandsI i = m_commands.begin (); i != m_commands.end (); i++) {
if (i->m_type == Command::INSERT) {
for (RemovesI j = removes.begin (); j != removes.end (); j++) {
if (j->second == i->m_uid) {
// this insert will be removed later.
uint64_t us = i->insert.m_evUs;
uint32_t uid = i->m_uid;
i->m_type = Command::INSERT_REMOVE;
i->m_uid = uid;
i->insertRemove.m_evUs = us;
i->insertRemove.m_evLoc = j->first;
break;
}
}
}
}
std::cout << "calculate remove locations..." << std::endl;
// calculate the final insert/remove location.
for (CommandsI i = m_commands.begin (); i != m_commands.end (); i++) {
if (i->m_type == Command::INSERT_REMOVE) {
uint32_t loc = 0;
for (CommandsI tmp = i; tmp != m_commands.end (); tmp++) {
if (tmp->m_type == Command::REMOVE &&
tmp->m_uid == i->insertRemove.m_evLoc) {
i->insertRemove.m_evLoc = loc;
break;
}
loc++;
}
}
}
std::cout << "gather insert removes..." << std::endl;
for (CommandsI i = m_commands.begin (); i != m_commands.end (); i++) {
if (i->m_type == Command::INSERT) {
for (RemovesI j = removes.begin (); j != removes.end (); j++) {
if (j->second == i->m_uid) {
// this insert will be removed later.
uint64_t us = i->insert.m_evUs;
uint32_t uid = i->m_uid;
i->m_type = Command::INSERT_REMOVE;
i->m_uid = uid;
i->insertRemove.m_evUs = us;
i->insertRemove.m_evLoc = j->first;
break;
}
}
}
}
std::cout << "calculate remove locations..." << std::endl;
// calculate the final insert/remove location.
for (CommandsI i = m_commands.begin (); i != m_commands.end (); i++) {
if (i->m_type == Command::INSERT_REMOVE) {
uint32_t loc = 0;
for (CommandsI tmp = i; tmp != m_commands.end (); tmp++) {
if (tmp->m_type == Command::REMOVE &&
tmp->m_uid == i->insertRemove.m_evLoc) {
i->insertRemove.m_evLoc = loc;
break;
}
loc++;
}
}
}
}
void
LogReader::executeLogCommands (uint32_t uid)
{
if (m_command == m_commands.end ()) {
return;
}
//std::cout << "one event, uid=" <<m_uid<< std::endl;
struct Command cmd = *m_command;
//std::cout << "cmd uid=" <<cmd.m_uid<< std::endl;
while (cmd.m_uid == uid) {
m_command++;
switch (cmd.m_type) {
case Command::INSERT:
//std::cout << "exec insert now=" << Simulator::nowUs ()
//<< ", time=" << cmd.insert.m_evUs << std::endl;
Simulator::scheduleAbsUs (cmd.insert.m_evUs,
makeEvent (&LogReader::executeLogCommands, this, m_uid));
m_uid++;
break;
case Command::INSERT_LATER:
//std::cout << "exec insert later" << std::endl;
Simulator::scheduleNow (makeEvent (&LogReader::executeLogCommands, this, m_uid));
m_uid++;
break;
case Command::REMOVE: {
//std::cout << "exec remove" << std::endl;
Event ev = m_removeEvents.front ();
m_removeEvents.pop_front ();
Simulator::remove (ev);
} break;
case Command::INSERT_REMOVE: {
//std::cout << "exec insert remove" << std::endl;
Event ev = makeEvent (&LogReader::executeLogCommands, this, m_uid);
Simulator::scheduleAbsUs (cmd.insertRemove.m_evUs, ev);
m_removeEvents[cmd.insertRemove.m_evLoc] = ev;
m_uid++;
} break;
}
cmd = *m_command;
}
if (m_command == m_commands.end ()) {
return;
}
//std::cout << "one event, uid=" <<m_uid<< std::endl;
struct Command cmd = *m_command;
//std::cout << "cmd uid=" <<cmd.m_uid<< std::endl;
while (cmd.m_uid == uid) {
m_command++;
switch (cmd.m_type) {
case Command::INSERT:
//std::cout << "exec insert now=" << Simulator::nowUs ()
//<< ", time=" << cmd.insert.m_evUs << std::endl;
Simulator::scheduleAbsUs (cmd.insert.m_evUs,
makeEvent (&LogReader::executeLogCommands, this, m_uid));
m_uid++;
break;
case Command::INSERT_LATER:
//std::cout << "exec insert later" << std::endl;
Simulator::scheduleNow (makeEvent (&LogReader::executeLogCommands, this, m_uid));
m_uid++;
break;
case Command::REMOVE: {
//std::cout << "exec remove" << std::endl;
Event ev = m_removeEvents.front ();
m_removeEvents.pop_front ();
Simulator::remove (ev);
} break;
case Command::INSERT_REMOVE: {
//std::cout << "exec insert remove" << std::endl;
Event ev = makeEvent (&LogReader::executeLogCommands, this, m_uid);
Simulator::scheduleAbsUs (cmd.insertRemove.m_evUs, ev);
m_removeEvents[cmd.insertRemove.m_evLoc] = ev;
m_uid++;
} break;
}
cmd = *m_command;
}
}
void
LogReader::printStats (void)
{
uint32_t nInserts = 0;
uint32_t nRemoves = 0;
for (CommandsI i = m_commands.begin (); i != m_commands.end (); i++) {
switch (i->m_type) {
case Command::INSERT:
nInserts++;
break;
case Command::INSERT_LATER:
nInserts++;
break;
case Command::INSERT_REMOVE:
nInserts++;
break;
case Command::REMOVE:
nRemoves++;
break;
}
}
std::cout << "inserts="<<nInserts<<", removes="<<nRemoves<<std::endl;
std::cout << "run simulation..."<<std::endl;
uint32_t nInserts = 0;
uint32_t nRemoves = 0;
for (CommandsI i = m_commands.begin (); i != m_commands.end (); i++) {
switch (i->m_type) {
case Command::INSERT:
nInserts++;
break;
case Command::INSERT_LATER:
nInserts++;
break;
case Command::INSERT_REMOVE:
nInserts++;
break;
case Command::REMOVE:
nRemoves++;
break;
}
}
std::cout << "inserts="<<nInserts<<", removes="<<nRemoves<<std::endl;
std::cout << "run simulation..."<<std::endl;
}
void
LogReader::run (void)
{
m_uid = 0;
WallClockMs time;
time.start ();
m_command = m_commands.begin ();
executeLogCommands (m_uid);
Simulator::run ();
unsigned long long delta = time.end ();
double delay = ((double)delta)/1000;
std::cout << "runtime="<<delay<<"s"<<std::endl;
m_uid = 0;
WallClockMs time;
time.start ();
m_command = m_commands.begin ();
executeLogCommands (m_uid);
Simulator::run ();
unsigned long long delta = time.end ();
double delay = ((double)delta)/1000;
std::cout << "runtime="<<delay<<"s"<<std::endl;
}
int main (int argc, char *argv[])
{
char const *input = 0;
uint32_t n = 1;
while (argc > 0) {
if (strcmp ("--list", argv[0]) == 0) {
Simulator::setLinkedList ();
} else if (strcmp ("--heap", argv[0]) == 0) {
Simulator::setBinaryHeap ();
} else if (strcmp ("--map", argv[0]) == 0) {
Simulator::setStdMap ();
} else if (strncmp ("--n=", argv[0], strlen("--n=")) == 0) {
n = atoi (argv[0]+strlen ("--n="));
} else if (strncmp ("--input=", argv[0],strlen ("--input=")) == 0) {
input = argv[0] + strlen ("--input=");
} else if (strncmp ("--log=", argv[0],strlen ("--log=")) == 0) {
char const *filename = argv[0] + strlen ("--log=");
Simulator::enableLogTo (filename);
}
argc--;
argv++;
}
if (input == 0) {
std::cerr << "need --input=[filename] option" << std::endl;
return 1;
}
LogReader log;
log.readFrom_filename (input);
for (uint32_t i = 0; i < n; i++) {
log.run ();
}
char const *input = 0;
uint32_t n = 1;
while (argc > 0) {
if (strcmp ("--list", argv[0]) == 0) {
Simulator::setLinkedList ();
} else if (strcmp ("--heap", argv[0]) == 0) {
Simulator::setBinaryHeap ();
} else if (strcmp ("--map", argv[0]) == 0) {
Simulator::setStdMap ();
} else if (strncmp ("--n=", argv[0], strlen("--n=")) == 0) {
n = atoi (argv[0]+strlen ("--n="));
} else if (strncmp ("--input=", argv[0],strlen ("--input=")) == 0) {
input = argv[0] + strlen ("--input=");
} else if (strncmp ("--log=", argv[0],strlen ("--log=")) == 0) {
char const *filename = argv[0] + strlen ("--log=");
Simulator::enableLogTo (filename);
}
argc--;
argv++;
}
if (input == 0) {
std::cerr << "need --input=[filename] option" << std::endl;
return 1;
}
LogReader log;
log.readFrom_filename (input);
for (uint32_t i = 0; i < n; i++) {
log.run ();
}
}

8
utils/run-tests.cc

@ -1,4 +1,4 @@
/* -*- Mode:C++; c-basic-offset:8; tab-width:8; indent-tabs-mode:t -*- */
/* -*- Mode:C++; c-basic-offset:4; tab-width:4; indent-tabs-mode:f -*- */
/*
* Copyright (c) 2005 INRIA
* All rights reserved.
@ -24,9 +24,9 @@
int main (int argc, char *argv[])
{
#ifdef RUN_SELF_TESTS
ns3::TestManager::enableVerbose ();
ns3::TestManager::runTests ();
ns3::TestManager::enableVerbose ();
ns3::TestManager::runTests ();
#endif /* RUN_SELF_TESTS */
return 0;
return 0;
}

Loading…
Cancel
Save