use a free list for tag buffers
authorMathieu Lacage <mathieu.lacage@sophia.inria.fr>
Tue May 06 14:44:09 2008 -0700 (21 months ago)
changeset 30434a1ab06f0d63
parent 3042 d0a9677d5452
child 3044 2887b34f4769
use a free list for tag buffers
src/common/tag-list.cc
src/common/tag-list.h
     1.1 --- a/src/common/tag-list.cc	Tue May 06 14:18:05 2008 -0700
     1.2 +++ b/src/common/tag-list.cc	Tue May 06 14:44:09 2008 -0700
     1.3 @@ -1,7 +1,37 @@
     1.4  #include "tag-list.h"
     1.5 +#include <vector>
     1.6 +
     1.7 +#define USE_FREE_LIST 1
     1.8 +#define FREE_LIST_SIZE 1000
     1.9  
    1.10  namespace ns3 {
    1.11  
    1.12 +struct TagListData {
    1.13 +  uint32_t size;
    1.14 +  uint32_t count;
    1.15 +  uint32_t dirty;
    1.16 +  uint8_t data[4];
    1.17 +};
    1.18 +
    1.19 +#ifdef USE_FREE_LIST
    1.20 +static class TagListDataFreeList : public std::vector<struct TagListData *>
    1.21 +{
    1.22 +public:
    1.23 +  ~TagListDataFreeList ();
    1.24 +} g_freeList;
    1.25 +static uint32_t g_maxSize = 0;
    1.26 +
    1.27 +TagListDataFreeList::~TagListDataFreeList ()
    1.28 +{
    1.29 +  for (TagListDataFreeList::iterator i = begin ();
    1.30 +       i != end (); i++)
    1.31 +    {
    1.32 +      uint8_t *buffer = (uint8_t *)(*i);
    1.33 +      delete [] buffer;
    1.34 +    }
    1.35 +}
    1.36 +#endif /* USE_FREE_LIST */
    1.37 +
    1.38  TagList::Iterator::Item::Item (TagBuffer buf_)
    1.39      : buf (buf_)
    1.40  {}
    1.41 @@ -113,7 +143,7 @@
    1.42    else if (m_data->size < spaceNeeded ||
    1.43  	   (m_data->count != 1 && m_data->dirty != m_used))
    1.44      {
    1.45 -      struct TagList::Data *newData = Allocate (spaceNeeded);
    1.46 +      struct TagListData *newData = Allocate (spaceNeeded);
    1.47        memcpy (&newData->data, &m_data->data, m_used);
    1.48        Deallocate (m_data);
    1.49        m_data = newData;
    1.50 @@ -144,7 +174,11 @@
    1.51  void 
    1.52  TagList::Remove (const Iterator &i)
    1.53  {
    1.54 -  // XXX: more complex to implement.
    1.55 +  if (m_data == 0)
    1.56 +    {
    1.57 +      return;
    1.58 +    } 
    1.59 +  // XXX
    1.60  }
    1.61  
    1.62  void 
    1.63 @@ -264,12 +298,27 @@
    1.64    *this = list;    
    1.65  }
    1.66  
    1.67 +#ifdef USE_FREE_LIST
    1.68  
    1.69 -struct TagList::Data *
    1.70 +struct TagListData *
    1.71  TagList::Allocate (uint32_t size)
    1.72  {
    1.73 -  uint8_t *buffer = new uint8_t [size + sizeof (struct TagList::Data) - 4];
    1.74 -  struct Data *data = (struct Data *)buffer;
    1.75 +  while (!g_freeList.empty ())
    1.76 +    {
    1.77 +      struct TagListData *data = g_freeList.back ();
    1.78 +      g_freeList.pop_back ();
    1.79 +      NS_ASSERT (data != 0);
    1.80 +      if (data->size >= size)
    1.81 +	{
    1.82 +	  data->count = 1;
    1.83 +	  data->dirty = 0;
    1.84 +	  return data;
    1.85 +	}
    1.86 +      uint8_t *buffer = (uint8_t *)data;
    1.87 +      delete [] buffer;
    1.88 +    }
    1.89 +  uint8_t *buffer = new uint8_t [std::max (size, g_maxSize) + sizeof (struct TagListData) - 4];
    1.90 +  struct TagListData *data = (struct TagListData *)buffer;
    1.91    data->count = 1;
    1.92    data->size = size;
    1.93    data->dirty = 0;
    1.94 @@ -277,7 +326,44 @@
    1.95  }
    1.96  
    1.97  void 
    1.98 -TagList::Deallocate (struct Data *data)
    1.99 +TagList::Deallocate (struct TagListData *data)
   1.100 +{
   1.101 +  if (data == 0)
   1.102 +    {
   1.103 +      return;
   1.104 +    }
   1.105 +  g_maxSize = std::max (g_maxSize, data->size);
   1.106 +  data->count--;
   1.107 +  if (data->count == 0)
   1.108 +    {
   1.109 +      if (g_freeList.size () > FREE_LIST_SIZE ||
   1.110 +	  data->size < g_maxSize)
   1.111 +	{
   1.112 +	  uint8_t *buffer = (uint8_t *)data;
   1.113 +	  delete [] buffer;
   1.114 +	}
   1.115 +      else
   1.116 +	{
   1.117 +	  g_freeList.push_back (data);
   1.118 +	}
   1.119 +    }
   1.120 +}
   1.121 +
   1.122 +#else /* USE_FREE_LIST */
   1.123 +
   1.124 +struct TagListData *
   1.125 +TagList::Allocate (uint32_t size)
   1.126 +{
   1.127 +  uint8_t *buffer = new uint8_t [size + sizeof (struct TagListData) - 4];
   1.128 +  struct TagListData *data = (struct TagListData *)buffer;
   1.129 +  data->count = 1;
   1.130 +  data->size = size;
   1.131 +  data->dirty = 0;
   1.132 +  return data;
   1.133 +}
   1.134 +
   1.135 +void 
   1.136 +TagList::Deallocate (struct TagListData *data)
   1.137  {
   1.138    if (data == 0)
   1.139      {
   1.140 @@ -291,5 +377,7 @@
   1.141      }
   1.142  }
   1.143  
   1.144 +#endif /* USE_FREE_LIST */
   1.145 +
   1.146  
   1.147  } // namespace ns3
     2.1 --- a/src/common/tag-list.h	Tue May 06 14:18:05 2008 -0700
     2.2 +++ b/src/common/tag-list.h	Tue May 06 14:44:09 2008 -0700
     2.3 @@ -7,6 +7,8 @@
     2.4  
     2.5  namespace ns3 {
     2.6  
     2.7 +struct TagListData;
     2.8 +
     2.9  class TagList
    2.10  {
    2.11  public:
    2.12 @@ -59,17 +61,11 @@
    2.13    bool IsDirtyAtEnd (uint32_t appendOffset);
    2.14    bool IsDirtyAtStart (uint32_t prependOffset);
    2.15  
    2.16 -  struct Data {
    2.17 -    uint32_t size;
    2.18 -    uint32_t count;
    2.19 -    uint32_t dirty;
    2.20 -    uint8_t data[4];
    2.21 -  };
    2.22 -  struct TagList::Data *Allocate (uint32_t size);
    2.23 -  void Deallocate (struct Data *data);
    2.24 +  struct TagListData *Allocate (uint32_t size);
    2.25 +  void Deallocate (struct TagListData *data);
    2.26  
    2.27    uint16_t m_used;
    2.28 -  struct Data *m_data;
    2.29 +  struct TagListData *m_data;
    2.30  };
    2.31  
    2.32  } // namespace ns3