a bunch of optimizations
parent
a6c8a11881
commit
a4f727f68d
|
@ -22,10 +22,15 @@
|
||||||
#include <list>
|
#include <list>
|
||||||
#include "ns3/assert.h"
|
#include "ns3/assert.h"
|
||||||
#include "ns3/fatal-error.h"
|
#include "ns3/fatal-error.h"
|
||||||
|
#include "ns3/debug.h"
|
||||||
#include "packet-history.h"
|
#include "packet-history.h"
|
||||||
#include "chunk.h"
|
#include "chunk.h"
|
||||||
#include "buffer.h"
|
#include "buffer.h"
|
||||||
|
|
||||||
|
NS_DEBUG_COMPONENT_DEFINE ("PacketHistory");
|
||||||
|
|
||||||
|
#define noUSE_ULEB 1
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
class ItemList
|
class ItemList
|
||||||
|
@ -278,6 +283,44 @@ namespace ns3 {
|
||||||
bool PacketHistory::m_enable = false;
|
bool PacketHistory::m_enable = false;
|
||||||
uint32_t PacketHistory::m_maxSize = 0;
|
uint32_t PacketHistory::m_maxSize = 0;
|
||||||
PacketHistory::DataFreeList PacketHistory::m_freeList;
|
PacketHistory::DataFreeList PacketHistory::m_freeList;
|
||||||
|
uint32_t g_nAllocs = 0;
|
||||||
|
uint32_t g_nDeAllocs = 0;
|
||||||
|
uint32_t g_nRecycle = 0;
|
||||||
|
uint32_t g_nCreate = 0;
|
||||||
|
uint32_t g_one = 0;
|
||||||
|
uint32_t g_two = 0;
|
||||||
|
uint32_t g_three = 0;
|
||||||
|
uint32_t g_four = 0;
|
||||||
|
uint32_t g_five = 0;
|
||||||
|
|
||||||
|
void
|
||||||
|
PacketHistory::PrintStats (void)
|
||||||
|
{
|
||||||
|
std::cout << "allocs="<<g_nAllocs<<", deallocs="<<g_nDeAllocs
|
||||||
|
<<", recycle="<<g_nRecycle<<", create="<<g_nCreate<<std::endl;
|
||||||
|
std::cout << "one="<<g_one<<", two="<<g_two<<", three="<<g_three<<std::endl;
|
||||||
|
//std::cout << "four="<<g_four<<", five="<<g_five<<std::endl;
|
||||||
|
g_nAllocs = 0;
|
||||||
|
g_nDeAllocs = 0;
|
||||||
|
g_nRecycle = 0;
|
||||||
|
g_nCreate = 0;
|
||||||
|
g_one = 0;
|
||||||
|
g_two = 0;
|
||||||
|
g_three = 0;
|
||||||
|
g_four = 0;
|
||||||
|
g_five = 0;
|
||||||
|
#if 0
|
||||||
|
PacketHistory h (0, 0);
|
||||||
|
for (uint32_t i = 0; i < 0xffffff; i++)
|
||||||
|
{
|
||||||
|
if (h.GetUleb128Size (i) == 4)
|
||||||
|
{
|
||||||
|
std::cout << i << std::endl;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
PacketHistory::Enable (void)
|
PacketHistory::Enable (void)
|
||||||
|
@ -285,86 +328,11 @@ PacketHistory::Enable (void)
|
||||||
m_enable = true;
|
m_enable = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
PacketHistory::PacketHistory ()
|
|
||||||
: m_data (0),
|
|
||||||
m_end (0),
|
|
||||||
m_n (0),
|
|
||||||
m_aggregated (false)
|
|
||||||
{
|
|
||||||
Construct (0, 0);
|
|
||||||
}
|
|
||||||
PacketHistory::PacketHistory (uint32_t uid, uint32_t size)
|
|
||||||
: m_data (0),
|
|
||||||
m_end (0),
|
|
||||||
m_n (0),
|
|
||||||
m_aggregated (false)
|
|
||||||
{
|
|
||||||
Construct (uid, size);
|
|
||||||
}
|
|
||||||
void
|
|
||||||
PacketHistory::Construct (uint32_t uid, uint32_t size)
|
|
||||||
{
|
|
||||||
if (m_enable)
|
|
||||||
{
|
|
||||||
m_data = PacketHistory::Create (size);
|
|
||||||
AppendOneCommand (PacketHistory::INIT,
|
|
||||||
size, uid);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
PacketHistory::PacketHistory (PacketHistory const &o)
|
|
||||||
: m_data (o.m_data),
|
|
||||||
m_end (o.m_end),
|
|
||||||
m_n (o.m_n),
|
|
||||||
m_aggregated (o.m_aggregated)
|
|
||||||
{
|
|
||||||
if (m_data != 0)
|
|
||||||
{
|
|
||||||
m_data->m_count++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
PacketHistory &
|
|
||||||
PacketHistory::operator = (PacketHistory const& o)
|
|
||||||
{
|
|
||||||
if (m_data == o.m_data)
|
|
||||||
{
|
|
||||||
// self assignment
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
if (m_data != 0)
|
|
||||||
{
|
|
||||||
m_data->m_count--;
|
|
||||||
if (m_data->m_count == 0)
|
|
||||||
{
|
|
||||||
PacketHistory::Recycle (m_data);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
m_data = o.m_data;
|
|
||||||
m_end = o.m_end;
|
|
||||||
m_n = o.m_n;
|
|
||||||
m_aggregated = o.m_aggregated;
|
|
||||||
if (m_data != 0)
|
|
||||||
{
|
|
||||||
m_data->m_count++;
|
|
||||||
}
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
PacketHistory::~PacketHistory ()
|
|
||||||
{
|
|
||||||
if (m_data != 0)
|
|
||||||
{
|
|
||||||
m_data->m_count--;
|
|
||||||
if (m_data->m_count == 0)
|
|
||||||
{
|
|
||||||
PacketHistory::Recycle (m_data);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
struct PacketHistory::CommandData *
|
struct PacketHistory::CommandData *
|
||||||
PacketHistory::Create (uint32_t size)
|
PacketHistory::Create (uint32_t size)
|
||||||
{
|
{
|
||||||
|
g_nCreate++;
|
||||||
|
NS_DEBUG ("create size="<<size<<", max="<<m_maxSize);
|
||||||
if (size > m_maxSize)
|
if (size > m_maxSize)
|
||||||
{
|
{
|
||||||
m_maxSize = size;
|
m_maxSize = size;
|
||||||
|
@ -375,17 +343,22 @@ PacketHistory::Create (uint32_t size)
|
||||||
m_freeList.pop_back ();
|
m_freeList.pop_back ();
|
||||||
if (data->m_size >= size)
|
if (data->m_size >= size)
|
||||||
{
|
{
|
||||||
|
NS_DEBUG ("create found size="<<data->m_size);
|
||||||
data->m_count = 1;
|
data->m_count = 1;
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
PacketHistory::Deallocate (data);
|
PacketHistory::Deallocate (data);
|
||||||
|
NS_DEBUG ("create dealloc size="<<data->m_size);
|
||||||
}
|
}
|
||||||
return PacketHistory::Allocate (size);
|
NS_DEBUG ("create alloc size="<<m_maxSize);
|
||||||
|
return PacketHistory::Allocate (m_maxSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
PacketHistory::Recycle (struct CommandData *data)
|
PacketHistory::Recycle (struct CommandData *data)
|
||||||
{
|
{
|
||||||
|
g_nRecycle++;
|
||||||
|
NS_DEBUG ("recycle size="<<data->m_size<<", list="<<m_freeList.size ());
|
||||||
NS_ASSERT (data->m_count == 0);
|
NS_ASSERT (data->m_count == 0);
|
||||||
if (m_freeList.size () > 1000 ||
|
if (m_freeList.size () > 1000 ||
|
||||||
data->m_size < m_maxSize)
|
data->m_size < m_maxSize)
|
||||||
|
@ -401,6 +374,7 @@ PacketHistory::Recycle (struct CommandData *data)
|
||||||
struct PacketHistory::CommandData *
|
struct PacketHistory::CommandData *
|
||||||
PacketHistory::Allocate (uint32_t n)
|
PacketHistory::Allocate (uint32_t n)
|
||||||
{
|
{
|
||||||
|
g_nAllocs++;
|
||||||
uint32_t size = sizeof (struct CommandData);
|
uint32_t size = sizeof (struct CommandData);
|
||||||
if (n <= 4)
|
if (n <= 4)
|
||||||
{
|
{
|
||||||
|
@ -416,118 +390,98 @@ PacketHistory::Allocate (uint32_t n)
|
||||||
void
|
void
|
||||||
PacketHistory::Deallocate (struct CommandData *data)
|
PacketHistory::Deallocate (struct CommandData *data)
|
||||||
{
|
{
|
||||||
|
g_nDeAllocs++;
|
||||||
uint8_t *buf = (uint8_t *)data;
|
uint8_t *buf = (uint8_t *)data;
|
||||||
delete [] buf;
|
delete [] buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
bool
|
||||||
PacketHistory::AppendOneCommand (uint32_t type, uint32_t data0, uint32_t data1)
|
PacketHistory::TryToAppendSmallValue (uint32_t value, uint8_t **buffer)
|
||||||
{
|
{
|
||||||
NS_ASSERT (m_data != 0);
|
uint8_t *start = *buffer;
|
||||||
uint32_t n = GetUleb128Size (type);
|
uint8_t *end = &m_data->m_data[m_data->m_size];
|
||||||
n += GetUleb128Size (data0);
|
if (value < 0x80 && start < end)
|
||||||
n += GetUleb128Size (data1);
|
|
||||||
|
|
||||||
if (m_data->m_size > m_end + n)
|
|
||||||
{
|
{
|
||||||
if (m_data->m_count == 1 ||
|
start[0] = value;
|
||||||
m_data->m_dirtyEnd == m_end)
|
*buffer = start + 1;
|
||||||
{
|
return true;
|
||||||
AppendValue (type);
|
|
||||||
AppendValue (data0);
|
|
||||||
AppendValue (data1);
|
|
||||||
m_n++;
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
else
|
if (value < 0x4000 && start + 1 < end)
|
||||||
{
|
{
|
||||||
uint8_t *buffer = &(m_data->m_data[m_end]);
|
uint8_t byte = value & (~0x80);
|
||||||
uint32_t lastType = ReadForwardValue (&buffer);
|
start[0] = 0x80 | byte;
|
||||||
if (lastType == type)
|
value >>= 7;
|
||||||
|
start[1] = value;
|
||||||
|
*buffer = start + 2;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
bool
|
||||||
|
PacketHistory::TryToAppendValue (uint32_t value, uint8_t **buffer)
|
||||||
{
|
{
|
||||||
uint32_t lastData = ReadForwardValue (&buffer);
|
uint8_t *start = *buffer;
|
||||||
if (lastData == data0)
|
uint8_t *end = &m_data->m_data[m_data->m_size];
|
||||||
|
if (value < 0x80 && start < end)
|
||||||
{
|
{
|
||||||
lastData = ReadForwardValue (&buffer);
|
start[0] = value;
|
||||||
if (lastData == data1)
|
*buffer = start + 1;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (value < 0x4000 && start + 1 < end)
|
||||||
{
|
{
|
||||||
return;
|
uint8_t byte = value & (~0x80);
|
||||||
|
start[0] = 0x80 | byte;
|
||||||
|
value >>= 7;
|
||||||
|
start[1] = value;
|
||||||
|
*buffer = start + 2;
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
}
|
if (value < 0x200000 && start + 2 < end)
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Reserve (n);
|
|
||||||
AppendValue (type);
|
|
||||||
AppendValue (data0);
|
|
||||||
AppendValue (data1);
|
|
||||||
m_n++;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
PacketHistory::AppendOneCommand (uint32_t type, uint32_t data)
|
|
||||||
{
|
{
|
||||||
NS_ASSERT (m_data != 0);
|
uint8_t byte = value & (~0x80);
|
||||||
uint32_t n = GetUleb128Size (data);
|
start[0] = 0x80 | byte;
|
||||||
n += GetUleb128Size (type);
|
value >>= 7;
|
||||||
|
start[1] = 0x80 | byte;
|
||||||
if (m_data->m_size > m_end + n)
|
value >>= 7;
|
||||||
{
|
start[2] = value;
|
||||||
if (m_data->m_count == 1 ||
|
*buffer = start + 3;
|
||||||
m_data->m_dirtyEnd == m_end)
|
return true;
|
||||||
{
|
|
||||||
AppendValue (type);
|
|
||||||
AppendValue (data);
|
|
||||||
m_n++;
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
else
|
if (start + 3 < end)
|
||||||
{
|
{
|
||||||
uint8_t *buffer = &(m_data->m_data[m_end]);
|
uint8_t byte = value & (~0x80);
|
||||||
uint32_t lastType = ReadForwardValue (&buffer);
|
start[0] = 0x80 | byte;
|
||||||
if (lastType == type)
|
value >>= 7;
|
||||||
|
start[1] = 0x80 | byte;
|
||||||
|
value >>= 7;
|
||||||
|
start[2] = 0x80 | byte;
|
||||||
|
value >>= 7;
|
||||||
|
start[3] = value;
|
||||||
|
*buffer = start + 4;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
#if 0
|
||||||
|
// more generic version of the above.
|
||||||
|
do {
|
||||||
|
uint8_t byte = value & (~0x80);
|
||||||
|
value >>= 7;
|
||||||
|
if (value != 0)
|
||||||
{
|
{
|
||||||
uint32_t lastData = ReadForwardValue (&buffer);
|
/* more bytes to come */
|
||||||
if (lastData == data)
|
byte |= 0x80;
|
||||||
|
}
|
||||||
|
*current = byte;
|
||||||
|
current++;
|
||||||
|
} while (value != 0 && current != end);
|
||||||
|
if (value != 0 && current == end)
|
||||||
{
|
{
|
||||||
return;
|
return false;
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Reserve (n);
|
|
||||||
AppendValue (type);
|
|
||||||
AppendValue (data);
|
|
||||||
m_n++;
|
|
||||||
}
|
|
||||||
void
|
|
||||||
PacketHistory::ReserveCopy (uint32_t size)
|
|
||||||
{
|
|
||||||
struct CommandData *newData = PacketHistory::Create (m_end + size);
|
|
||||||
memcpy (newData->m_data, m_data->m_data, m_end);
|
|
||||||
newData->m_dirtyEnd = m_end;
|
|
||||||
m_data->m_count--;
|
|
||||||
if (m_data->m_count == 0)
|
|
||||||
{
|
|
||||||
PacketHistory::Recycle (m_data);
|
|
||||||
}
|
|
||||||
m_data = newData;
|
|
||||||
}
|
|
||||||
void
|
|
||||||
PacketHistory::Reserve (uint32_t size)
|
|
||||||
{
|
|
||||||
NS_ASSERT (m_data != 0);
|
|
||||||
if (m_data->m_size > m_end + size &&
|
|
||||||
(m_data->m_count == 1 ||
|
|
||||||
m_data->m_dirtyEnd == m_end))
|
|
||||||
{
|
|
||||||
/* enough room, not dirty. */
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* (enough room and dirty) or (not enough room) */
|
|
||||||
ReserveCopy (size);
|
|
||||||
}
|
}
|
||||||
|
*buffer = current;
|
||||||
|
return true;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t
|
uint32_t
|
||||||
|
@ -542,25 +496,6 @@ PacketHistory::GetUleb128Size (uint32_t value) const
|
||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t
|
|
||||||
PacketHistory::GetReverseUleb128Size (uint8_t *buffer) const
|
|
||||||
{
|
|
||||||
uint8_t *cur = buffer;
|
|
||||||
uint8_t byte = *cur;
|
|
||||||
if (byte & 0x80)
|
|
||||||
{
|
|
||||||
NS_FATAL_ERROR ("The last byte should have a zero high bit");
|
|
||||||
}
|
|
||||||
cur--;
|
|
||||||
while ((byte & 0x80) && (buffer - cur) < 5)
|
|
||||||
{
|
|
||||||
cur--;
|
|
||||||
byte = *cur;
|
|
||||||
}
|
|
||||||
uint32_t n = buffer - cur;
|
|
||||||
return n;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
PacketHistory::AppendValue (uint32_t value)
|
PacketHistory::AppendValue (uint32_t value)
|
||||||
{
|
{
|
||||||
|
@ -588,6 +523,7 @@ PacketHistory::AppendValue (uint32_t value)
|
||||||
uint32_t
|
uint32_t
|
||||||
PacketHistory::ReadValue (uint8_t *buffer, uint32_t *n) const
|
PacketHistory::ReadValue (uint8_t *buffer, uint32_t *n) const
|
||||||
{
|
{
|
||||||
|
#ifdef USE_ULEB
|
||||||
uint32_t result = 0;
|
uint32_t result = 0;
|
||||||
uint8_t shift, byte;
|
uint8_t shift, byte;
|
||||||
result = 0;
|
result = 0;
|
||||||
|
@ -609,6 +545,154 @@ PacketHistory::ReadValue (uint8_t *buffer, uint32_t *n) const
|
||||||
result = 0xffffffff;
|
result = 0xffffffff;
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
|
#else
|
||||||
|
uint32_t *start = (uint32_t *)buffer;
|
||||||
|
*n = *n + 4;
|
||||||
|
return *start;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
PacketHistory::AppendOneCommand (uint32_t type, uint32_t data0, uint32_t data1)
|
||||||
|
{
|
||||||
|
NS_ASSERT (m_data != 0);
|
||||||
|
#ifdef USE_ULEB
|
||||||
|
if (m_data->m_count == 1 ||
|
||||||
|
m_data->m_dirtyEnd == m_end)
|
||||||
|
{
|
||||||
|
uint8_t *start = &m_data->m_data[m_end];
|
||||||
|
uint8_t *current = start;
|
||||||
|
if (TryToAppendSmallValue (type, ¤t) &&
|
||||||
|
TryToAppendSmallValue (data0, ¤t) &&
|
||||||
|
TryToAppendValue (data1, ¤t))
|
||||||
|
{
|
||||||
|
uintptr_t written = current - start;
|
||||||
|
m_end += written;
|
||||||
|
m_data->m_dirtyEnd = m_end;
|
||||||
|
m_n++;
|
||||||
|
g_one++;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
g_two++;
|
||||||
|
uint32_t n = GetUleb128Size (type);
|
||||||
|
n += GetUleb128Size (data0);
|
||||||
|
n += GetUleb128Size (data1);
|
||||||
|
Reserve (n);
|
||||||
|
AppendValue (type);
|
||||||
|
AppendValue (data0);
|
||||||
|
AppendValue (data1);
|
||||||
|
m_n++;
|
||||||
|
|
||||||
|
#else
|
||||||
|
restart:
|
||||||
|
if (m_data->m_count == 1 ||
|
||||||
|
m_data->m_dirtyEnd == m_end)
|
||||||
|
{
|
||||||
|
uint32_t *start = (uint32_t *)&m_data->m_data[m_end];
|
||||||
|
uint32_t *end = (uint32_t *)&m_data->m_data[m_data->m_size];
|
||||||
|
if (start + 2 < end)
|
||||||
|
{
|
||||||
|
start[0] = type;
|
||||||
|
start[1] = data0;
|
||||||
|
start[2] = data1;
|
||||||
|
m_end += 12;
|
||||||
|
m_data->m_dirtyEnd = m_end;
|
||||||
|
m_n++;
|
||||||
|
g_one++;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
g_two++;
|
||||||
|
Reserve (12);
|
||||||
|
goto restart;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
PacketHistory::AppendOneCommand (uint32_t type, uint32_t data)
|
||||||
|
{
|
||||||
|
NS_ASSERT (m_data != 0);
|
||||||
|
#ifdef USE_ULEB
|
||||||
|
if (m_data->m_count == 1 ||
|
||||||
|
m_data->m_dirtyEnd == m_end)
|
||||||
|
{
|
||||||
|
uint8_t *start = &m_data->m_data[m_end];
|
||||||
|
uint8_t *current = start;
|
||||||
|
if (TryToAppendSmallValue (type, ¤t) &&
|
||||||
|
TryToAppendSmallValue (data, ¤t))
|
||||||
|
{
|
||||||
|
uintptr_t written = current - start;
|
||||||
|
m_end += written;
|
||||||
|
m_data->m_dirtyEnd = m_end;
|
||||||
|
m_n++;
|
||||||
|
g_one++;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
g_two++;
|
||||||
|
uint32_t n = GetUleb128Size (data);
|
||||||
|
n += GetUleb128Size (type);
|
||||||
|
Reserve (n);
|
||||||
|
AppendValue (type);
|
||||||
|
AppendValue (data);
|
||||||
|
m_n++;
|
||||||
|
#else
|
||||||
|
restart:
|
||||||
|
if (m_data->m_count == 1 ||
|
||||||
|
m_data->m_dirtyEnd == m_end)
|
||||||
|
{
|
||||||
|
uint32_t *start = (uint32_t *)&m_data->m_data[m_end];
|
||||||
|
uint32_t *end = (uint32_t *)&m_data->m_data[m_data->m_size];
|
||||||
|
if (start + 1 < end)
|
||||||
|
{
|
||||||
|
start[0] = type;
|
||||||
|
start[1] = data;
|
||||||
|
m_end += 8;
|
||||||
|
m_data->m_dirtyEnd = m_end;
|
||||||
|
m_n++;
|
||||||
|
g_one++;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
g_two++;
|
||||||
|
Reserve (8);
|
||||||
|
goto restart;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
void
|
||||||
|
PacketHistory::ReserveCopy (uint32_t size)
|
||||||
|
{
|
||||||
|
struct CommandData *newData = PacketHistory::Create (m_end + size);
|
||||||
|
memcpy (newData->m_data, m_data->m_data, m_end);
|
||||||
|
newData->m_dirtyEnd = m_end;
|
||||||
|
m_data->m_count--;
|
||||||
|
if (m_data->m_count == 0)
|
||||||
|
{
|
||||||
|
PacketHistory::Recycle (m_data);
|
||||||
|
}
|
||||||
|
m_data = newData;
|
||||||
|
}
|
||||||
|
void
|
||||||
|
PacketHistory::Reserve (uint32_t size)
|
||||||
|
{
|
||||||
|
NS_ASSERT (m_data != 0);
|
||||||
|
if (m_data->m_size >= m_end + size &&
|
||||||
|
(m_data->m_count == 1 ||
|
||||||
|
m_data->m_dirtyEnd == m_end))
|
||||||
|
{
|
||||||
|
/* enough room, not dirty. */
|
||||||
|
g_four++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* (enough room and dirty) or (not enough room) */
|
||||||
|
ReserveCopy (size);
|
||||||
|
g_five++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t
|
uint32_t
|
||||||
|
@ -666,7 +750,6 @@ PacketHistory::AddAtEnd (PacketHistory const&o)
|
||||||
{
|
{
|
||||||
if (m_enable)
|
if (m_enable)
|
||||||
{
|
{
|
||||||
m_aggregated = true;
|
|
||||||
uint32_t n = GetUleb128Size (PacketHistory::ADD_AT_END);
|
uint32_t n = GetUleb128Size (PacketHistory::ADD_AT_END);
|
||||||
n += GetUleb128Size (o.m_end);
|
n += GetUleb128Size (o.m_end);
|
||||||
n += GetUleb128Size (o.m_n);
|
n += GetUleb128Size (o.m_n);
|
||||||
|
|
|
@ -39,10 +39,10 @@ class PacketHistory {
|
||||||
public:
|
public:
|
||||||
static void Enable (void);
|
static void Enable (void);
|
||||||
|
|
||||||
PacketHistory (uint32_t uid, uint32_t size);
|
inline PacketHistory (uint32_t uid, uint32_t size);
|
||||||
PacketHistory (PacketHistory const &o);
|
inline PacketHistory (PacketHistory const &o);
|
||||||
PacketHistory &operator = (PacketHistory const& o);
|
inline PacketHistory &operator = (PacketHistory const& o);
|
||||||
~PacketHistory ();
|
inline ~PacketHistory ();
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
void AddHeader (T const &header, uint32_t size);
|
void AddHeader (T const &header, uint32_t size);
|
||||||
|
@ -63,6 +63,8 @@ public:
|
||||||
void PrintDefault (std::ostream &os, Buffer buffer) const;
|
void PrintDefault (std::ostream &os, Buffer buffer) const;
|
||||||
void Print (std::ostream &os, Buffer buffer, PacketPrinter const &printer) const;
|
void Print (std::ostream &os, Buffer buffer, PacketPrinter const &printer) const;
|
||||||
|
|
||||||
|
static void PrintStats (void);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
enum CommandType {
|
enum CommandType {
|
||||||
INIT = 0,
|
INIT = 0,
|
||||||
|
@ -88,9 +90,8 @@ private:
|
||||||
|
|
||||||
PacketHistory ();
|
PacketHistory ();
|
||||||
void Reserve (uint32_t n);
|
void Reserve (uint32_t n);
|
||||||
void Construct (uint32_t uid, uint32_t size);
|
inline void Construct (uint32_t uid, uint32_t size);
|
||||||
uint32_t GetUleb128Size (uint32_t value) const;
|
uint32_t GetUleb128Size (uint32_t value) const;
|
||||||
uint32_t GetReverseUleb128Size (uint8_t *buffer) const;
|
|
||||||
void AppendValue (uint32_t value);
|
void AppendValue (uint32_t value);
|
||||||
uint32_t ReadForwardValue (uint8_t **pBuffer) const;
|
uint32_t ReadForwardValue (uint8_t **pBuffer) const;
|
||||||
uint32_t ReadValue (uint8_t *buffer, uint32_t *n) const;
|
uint32_t ReadValue (uint8_t *buffer, uint32_t *n) const;
|
||||||
|
@ -103,6 +104,8 @@ private:
|
||||||
void RemoveTrailer (uint32_t uid, Chunk const & trailer, uint32_t size);
|
void RemoveTrailer (uint32_t uid, Chunk const & trailer, uint32_t size);
|
||||||
void PrintComplex (std::ostream &os, Buffer buffer, const PacketPrinter &printer) const;
|
void PrintComplex (std::ostream &os, Buffer buffer, const PacketPrinter &printer) const;
|
||||||
void BuildItemList (ItemList *list, uint8_t **buffer, uint32_t size, uint32_t n) const;
|
void BuildItemList (ItemList *list, uint8_t **buffer, uint32_t size, uint32_t n) const;
|
||||||
|
inline bool TryToAppendValue (uint32_t value, uint8_t **buffer);
|
||||||
|
inline bool TryToAppendSmallValue (uint32_t value, uint8_t **buffer);
|
||||||
|
|
||||||
static struct PacketHistory::CommandData *Create (uint32_t size);
|
static struct PacketHistory::CommandData *Create (uint32_t size);
|
||||||
static void Recycle (struct CommandData *data);
|
static void Recycle (struct CommandData *data);
|
||||||
|
@ -116,7 +119,6 @@ private:
|
||||||
struct CommandData *m_data;
|
struct CommandData *m_data;
|
||||||
uint32_t m_end;
|
uint32_t m_end;
|
||||||
uint32_t m_n;
|
uint32_t m_n;
|
||||||
bool m_aggregated;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}; // namespace ns3
|
}; // namespace ns3
|
||||||
|
@ -149,6 +151,72 @@ PacketHistory::RemoveTrailer (T const &trailer, uint32_t size)
|
||||||
RemoveTrailer (PacketPrinter::GetUid<T> (), trailer, size);
|
RemoveTrailer (PacketPrinter::GetUid<T> (), trailer, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PacketHistory::PacketHistory (uint32_t uid, uint32_t size)
|
||||||
|
: m_data (0),
|
||||||
|
m_end (0),
|
||||||
|
m_n (0)
|
||||||
|
{
|
||||||
|
Construct (uid, size);
|
||||||
|
}
|
||||||
|
void
|
||||||
|
PacketHistory::Construct (uint32_t uid, uint32_t size)
|
||||||
|
{
|
||||||
|
if (m_enable)
|
||||||
|
{
|
||||||
|
m_data = PacketHistory::Create (0);
|
||||||
|
AppendOneCommand (PacketHistory::INIT,
|
||||||
|
size, uid);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
PacketHistory::PacketHistory (PacketHistory const &o)
|
||||||
|
: m_data (o.m_data),
|
||||||
|
m_end (o.m_end),
|
||||||
|
m_n (o.m_n)
|
||||||
|
{
|
||||||
|
if (m_data != 0)
|
||||||
|
{
|
||||||
|
m_data->m_count++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
PacketHistory &
|
||||||
|
PacketHistory::operator = (PacketHistory const& o)
|
||||||
|
{
|
||||||
|
if (m_data == o.m_data)
|
||||||
|
{
|
||||||
|
// self assignment
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
if (m_data != 0)
|
||||||
|
{
|
||||||
|
m_data->m_count--;
|
||||||
|
if (m_data->m_count == 0)
|
||||||
|
{
|
||||||
|
PacketHistory::Recycle (m_data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
m_data = o.m_data;
|
||||||
|
m_end = o.m_end;
|
||||||
|
m_n = o.m_n;
|
||||||
|
if (m_data != 0)
|
||||||
|
{
|
||||||
|
m_data->m_count++;
|
||||||
|
}
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
PacketHistory::~PacketHistory ()
|
||||||
|
{
|
||||||
|
if (m_data != 0)
|
||||||
|
{
|
||||||
|
m_data->m_count--;
|
||||||
|
if (m_data->m_count == 0)
|
||||||
|
{
|
||||||
|
PacketHistory::Recycle (m_data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}; // namespace ns3
|
}; // namespace ns3
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
*/
|
*/
|
||||||
#include "ns3/system-wall-clock-ms.h"
|
#include "ns3/system-wall-clock-ms.h"
|
||||||
#include "ns3/packet.h"
|
#include "ns3/packet.h"
|
||||||
|
#include "ns3/packet-history.h"
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
|
||||||
|
@ -173,17 +174,27 @@ int main (int argc, char *argv[])
|
||||||
{
|
{
|
||||||
uint32_t n = 0;
|
uint32_t n = 0;
|
||||||
while (argc > 0) {
|
while (argc > 0) {
|
||||||
if (strncmp ("--n=", argv[0],strlen ("--n=")) == 0) {
|
if (strncmp ("--n=", argv[0],strlen ("--n=")) == 0)
|
||||||
|
{
|
||||||
char const *nAscii = argv[0] + strlen ("--n=");
|
char const *nAscii = argv[0] + strlen ("--n=");
|
||||||
n = atoi (nAscii);
|
n = atoi (nAscii);
|
||||||
}
|
}
|
||||||
|
if (strncmp ("--enable-history", argv[0], strlen ("--enable-history")) == 0)
|
||||||
|
{
|
||||||
|
PacketHistory::Enable ();
|
||||||
|
}
|
||||||
argc--;
|
argc--;
|
||||||
argv++;
|
argv++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
runBench (&benchPtrA, n, "a");
|
runBench (&benchPtrA, n, "a");
|
||||||
|
PacketHistory::PrintStats ();
|
||||||
runBench (&benchPtrB, n, "b");
|
runBench (&benchPtrB, n, "b");
|
||||||
|
PacketHistory::PrintStats ();
|
||||||
runBench (&benchPtrC, n, "c");
|
runBench (&benchPtrC, n, "c");
|
||||||
|
PacketHistory::PrintStats ();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue