Remove free list from PacketTagList.
This commit is contained in:
@@ -34,66 +34,6 @@ NS_LOG_COMPONENT_DEFINE ("PacketTagList");
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
#ifndef USE_FREE_LIST
|
||||
#define USE_FREE_LIST 0
|
||||
#endif
|
||||
|
||||
#if USE_FREE_LIST
|
||||
|
||||
struct PacketTagList::TagData * PacketTagList::g_free = 0;
|
||||
uint32_t PacketTagList::g_nfree = 0;
|
||||
|
||||
struct PacketTagList::TagData *
|
||||
PacketTagList::AllocData (void) const
|
||||
{
|
||||
NS_LOG_FUNCTION (g_nfree);
|
||||
struct TagData * retval;
|
||||
if (g_free != 0)
|
||||
{
|
||||
retval = g_free;
|
||||
g_free = g_free->next;
|
||||
g_nfree--;
|
||||
}
|
||||
else
|
||||
{
|
||||
retval = new struct TagData ();
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
void
|
||||
PacketTagList::FreeData (struct TagData *data) const
|
||||
{
|
||||
NS_LOG_FUNCTION (g_nfree << data);
|
||||
if (g_nfree > FREE_LIST_MAX)
|
||||
{
|
||||
delete data;
|
||||
return;
|
||||
}
|
||||
g_nfree++;
|
||||
data->next = g_free;
|
||||
g_free = data;
|
||||
memset (data->data, 0, TagData::MAX_SIZE);
|
||||
data->tid = TypeId ();
|
||||
data->count = 0;
|
||||
}
|
||||
#else // if USE_FREE_LIST
|
||||
|
||||
struct PacketTagList::TagData *
|
||||
PacketTagList::AllocData (void) const
|
||||
{
|
||||
NS_LOG_FUNCTION_NOARGS ();
|
||||
return new struct TagData ();
|
||||
}
|
||||
|
||||
void
|
||||
PacketTagList::FreeData (struct TagData *data) const
|
||||
{
|
||||
NS_LOG_FUNCTION (data);
|
||||
delete data;
|
||||
}
|
||||
#endif // if USE_FREE_LIST
|
||||
|
||||
bool
|
||||
PacketTagList::COWTraverse (Tag & tag, PacketTagList::COWWriter_fp Writer)
|
||||
{
|
||||
@@ -193,7 +133,7 @@ PacketTagList::COWTraverse (Tag & tag, PacketTagList::COWWriter_fp Writer)
|
||||
NS_ASSERT (cur != 0);
|
||||
NS_ASSERT (cur->count > 1);
|
||||
cur->count--; // unmerge cur
|
||||
struct TagData * copy = AllocData ();
|
||||
struct TagData * copy = new struct TagData ();
|
||||
copy->tid = cur->tid;
|
||||
copy->count = 1;
|
||||
memcpy (copy->data, cur->data, TagData::MAX_SIZE);
|
||||
@@ -237,7 +177,7 @@ PacketTagList::RemoveWriter (Tag & tag, bool preMerge,
|
||||
if (preMerge)
|
||||
{
|
||||
// found tid before first merge, so delete cur
|
||||
FreeData (cur);
|
||||
delete cur;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -285,7 +225,7 @@ PacketTagList::ReplaceWriter (Tag & tag, bool preMerge,
|
||||
// cur is always a merge at this point
|
||||
// need to copy, replace, and link past cur
|
||||
cur->count--; // unmerge cur
|
||||
struct TagData * copy = AllocData ();
|
||||
struct TagData * copy = new struct TagData ();
|
||||
copy->tid = tag.GetInstanceTypeId ();
|
||||
copy->count = 1;
|
||||
tag.Serialize (TagBuffer (copy->data,
|
||||
@@ -309,7 +249,7 @@ PacketTagList::Add (const Tag &tag) const
|
||||
{
|
||||
NS_ASSERT (cur->tid != tag.GetInstanceTypeId ());
|
||||
}
|
||||
struct TagData * head = AllocData ();
|
||||
struct TagData * head = new struct TagData ();
|
||||
head->count = 1;
|
||||
head->next = 0;
|
||||
head->tid = tag.GetInstanceTypeId ();
|
||||
|
||||
@@ -123,12 +123,6 @@ class Tag;
|
||||
*
|
||||
* \par <b> Memory Management: </b>
|
||||
* \n
|
||||
* If the preprocessor symbol \link packet-tag-list.cc#USE_FREE_LIST
|
||||
* \c USE_FREE_LIST \endlink is true, #FreeData'd #TagData's
|
||||
* are added to the static free list #g_free. The free list size is bounded.
|
||||
* Using the free list avoids \c new'ing and \c delete'ing #TagData's
|
||||
* every time a tag is added/removed from a PacketTagList.
|
||||
* \n\n
|
||||
* Packet tags must serialize to a finite maximum size, see #TagData
|
||||
*
|
||||
* This documentation entitles the original author to a free beer.
|
||||
@@ -153,8 +147,7 @@ public:
|
||||
* in this constant.
|
||||
*
|
||||
* \intern
|
||||
* Ideally, #TagData would be 32 bytes in size, so they
|
||||
* can be added/removed from a single free list, and require
|
||||
* Ideally, #TagData would be 32 bytes in size, so they require
|
||||
* no padding on 64-bit architectures. (The architecture
|
||||
* affects the size because of the \c #next pointer.)
|
||||
* This would leave 18 bytes for \c #data. However,
|
||||
@@ -185,7 +178,7 @@ public:
|
||||
* \param [in] o The PacketTagList to copy.
|
||||
*
|
||||
* This makes a light-weight copy by #RemoveAll, then
|
||||
* pointing to the same #TagData as \pname{o}.
|
||||
* pointing to the same #struct TagData as \pname{o}.
|
||||
*/
|
||||
inline PacketTagList (PacketTagList const &o);
|
||||
/**
|
||||
@@ -194,7 +187,7 @@ public:
|
||||
* \param [in] o The PacketTagList to copy.
|
||||
*
|
||||
* This makes a light-weight copy by #RemoveAll, then
|
||||
* pointing to the same #TagData as \pname{o}.
|
||||
* pointing to the same #struct TagData as \pname{o}.
|
||||
*/
|
||||
inline PacketTagList &operator = (PacketTagList const &o);
|
||||
/**
|
||||
@@ -246,15 +239,6 @@ public:
|
||||
const struct PacketTagList::TagData *Head (void) const;
|
||||
|
||||
private:
|
||||
/**
|
||||
* \returns A pointer to a new #TagData
|
||||
*/
|
||||
struct TagData * AllocData (void) const;
|
||||
/**
|
||||
* Free a #TagData, adding it to the free list.
|
||||
*/
|
||||
void FreeData (struct TagData * data) const;
|
||||
|
||||
/**
|
||||
* Typedef of method function pointer for copy-on-write operations
|
||||
*
|
||||
@@ -303,15 +287,10 @@ private:
|
||||
*/
|
||||
bool ReplaceWriter (Tag & tag, bool preMerge, struct TagData * cur, struct TagData ** prevNext);
|
||||
|
||||
enum PacketTagList_e
|
||||
{
|
||||
FREE_LIST_MAX = 1000 /**< Maximum size of free list */
|
||||
};
|
||||
|
||||
static struct TagData * g_free; /**< Head of #TagData free list */
|
||||
static uint32_t g_nfree; /**< Number of #TagData's on the free list */
|
||||
|
||||
struct TagData * m_next; /**< Pointer to first #TagData on the list */
|
||||
/**
|
||||
* Pointer to first #struct TagData on the list
|
||||
*/
|
||||
struct TagData *m_next;
|
||||
};
|
||||
|
||||
} // namespace ns3
|
||||
@@ -371,13 +350,13 @@ PacketTagList::RemoveAll (void)
|
||||
}
|
||||
if (prev != 0)
|
||||
{
|
||||
FreeData (prev);
|
||||
delete prev;
|
||||
}
|
||||
prev = cur;
|
||||
}
|
||||
if (prev != 0)
|
||||
{
|
||||
FreeData (prev);
|
||||
delete prev;
|
||||
}
|
||||
m_next = 0;
|
||||
}
|
||||
|
||||
@@ -630,7 +630,9 @@ PacketTagListTest::DoRun (void)
|
||||
ReplaceCheck (7);
|
||||
|
||||
std::cout << GetName () << "freelist timing" << std::endl;
|
||||
for (int i = 0; i < 100; ++i) {
|
||||
AddRemoveTime ();
|
||||
}
|
||||
|
||||
std::cout << GetName () << "remove timing" << std::endl;
|
||||
RemoveTime (ref, t7, "t7");
|
||||
|
||||
Reference in New Issue
Block a user