allow --check --valgrind to pass again
This commit is contained in:
@@ -75,11 +75,7 @@ struct BufferData {
|
||||
*/
|
||||
uint8_t m_data[1];
|
||||
};
|
||||
class BufferDataList : public std::vector<struct BufferData*>
|
||||
{
|
||||
public:
|
||||
~BufferDataList ();
|
||||
};
|
||||
typedef std::vector<struct BufferData*> BufferDataList;
|
||||
|
||||
static struct BufferData *BufferAllocate (uint32_t reqSize);
|
||||
|
||||
@@ -91,39 +87,69 @@ static void BufferDeallocate (struct BufferData *data);
|
||||
namespace ns3 {
|
||||
|
||||
#ifdef BUFFER_HEURISTICS
|
||||
/* The following macros are pretty evil but they are needed to allow us to
|
||||
* keep track of 3 possible states for the g_freeList variable:
|
||||
* - uninitialized means that no one has created a buffer yet
|
||||
* so no one has created the associated free list (it is created
|
||||
* on-demand when the first buffer is created)
|
||||
* - initialized means that the free list exists and is valid
|
||||
* - destroyed means that the static destructors of this compilation unit
|
||||
* have run so, the free list has been cleared from its content
|
||||
* The key is that in destroyed state, we are careful not re-create it
|
||||
* which is a typical weakness of lazy evaluation schemes which use
|
||||
* '0' as a special value to indicate both un-initialized and destroyed.
|
||||
* Note that it is important to use '0' as the marker for un-initialized state
|
||||
* because the variable holding this state information is initialized to zero
|
||||
* which the compiler assigns to zero-memory which is initialized to _zero_
|
||||
* before the constructors run so this ensures perfect handling of crazy
|
||||
* constructor orderings.
|
||||
*/
|
||||
#define MAGIC_DESTROYED (~(long) 0)
|
||||
#define IS_UNINITIALIZED(x) (x == (BufferDataList*)0)
|
||||
#define IS_DESTROYED(x) (x == (BufferDataList*)MAGIC_DESTROYED)
|
||||
#define IS_INITIALIZED(x) (!IS_UNINITIALIZED(x) && !IS_DESTROYED(x))
|
||||
#define DESTROYED ((BufferDataList*)MAGIC_DESTROYED)
|
||||
#define UNINITIALIZED ((BufferDataList*)0)
|
||||
static uint32_t g_recommendedStart = 0;
|
||||
static uint64_t g_nAddNoRealloc = 0;
|
||||
static uint64_t g_nAddRealloc = 0;
|
||||
static BufferDataList g_freeList;
|
||||
static BufferDataList *g_freeList = 0;
|
||||
static uint32_t g_maxSize = 0;
|
||||
static uint64_t g_nAllocs = 0;
|
||||
static uint64_t g_nCreates = 0;
|
||||
#endif /* BUFFER_HEURISTICS */
|
||||
|
||||
BufferDataList::~BufferDataList ()
|
||||
{
|
||||
static struct LocalStaticDestructor {
|
||||
LocalStaticDestructor(void)
|
||||
{
|
||||
#ifdef PRINT_STATS
|
||||
#ifdef BUFFER_HEURISTICS
|
||||
double efficiency;
|
||||
efficiency = g_nAllocs;
|
||||
efficiency /= g_nCreates;
|
||||
std::cout <<"buffer free list efficiency="<<efficiency<<" (lower is better)" << std::endl;
|
||||
std::cout <<"buffer free list max size="<<g_maxSize<<std::endl;
|
||||
std::cout <<"buffer free list recommended start="<<g_recommendedStart<<std::endl;
|
||||
double addEfficiency;
|
||||
addEfficiency = g_nAddRealloc;
|
||||
addEfficiency /= g_nAddNoRealloc;
|
||||
std::cout <<"buffer add efficiency=" << addEfficiency << " (lower is better)"<<std::endl;
|
||||
//std::cout <<"n add reallocs="<< g_nAddRealloc << std::endl;
|
||||
//std::cout <<"n add no reallocs="<< g_nAddNoRealloc << std::endl;
|
||||
double efficiency;
|
||||
efficiency = g_nAllocs;
|
||||
efficiency /= g_nCreates;
|
||||
std::cout <<"buffer free list efficiency="<<efficiency<<" (lower is better)" << std::endl;
|
||||
std::cout <<"buffer free list max size="<<g_maxSize<<std::endl;
|
||||
std::cout <<"buffer free list recommended start="<<g_recommendedStart<<std::endl;
|
||||
double addEfficiency;
|
||||
addEfficiency = g_nAddRealloc;
|
||||
addEfficiency /= g_nAddNoRealloc;
|
||||
std::cout <<"buffer add efficiency=" << addEfficiency << " (lower is better)"<<std::endl;
|
||||
//std::cout <<"n add reallocs="<< g_nAddRealloc << std::endl;
|
||||
//std::cout <<"n add no reallocs="<< g_nAddNoRealloc << std::endl;
|
||||
#endif /* BUFFER_HEURISTICS */
|
||||
#endif /* PRINT_STATS */
|
||||
for (BufferDataList::iterator i = begin ();
|
||||
i != end (); i++)
|
||||
{
|
||||
BufferDeallocate (*i);
|
||||
}
|
||||
}
|
||||
if (IS_INITIALIZED(g_freeList))
|
||||
{
|
||||
for (BufferDataList::iterator i = g_freeList->begin ();
|
||||
i != g_freeList->end (); i++)
|
||||
{
|
||||
BufferDeallocate (*i);
|
||||
}
|
||||
delete g_freeList;
|
||||
g_freeList = DESTROYED;
|
||||
}
|
||||
}
|
||||
} g_localStaticDestructor;
|
||||
|
||||
struct BufferData *
|
||||
BufferAllocate (uint32_t reqSize)
|
||||
@@ -153,16 +179,19 @@ void
|
||||
Buffer::Recycle (struct BufferData *data)
|
||||
{
|
||||
NS_ASSERT (data->m_count == 0);
|
||||
NS_ASSERT (!IS_UNINITIALIZED(g_freeList));
|
||||
g_maxSize = std::max (g_maxSize, data->m_size);
|
||||
/* feed into free list */
|
||||
if (data->m_size < g_maxSize ||
|
||||
g_freeList.size () > 1000)
|
||||
IS_DESTROYED(g_freeList) ||
|
||||
g_freeList->size () > 1000)
|
||||
{
|
||||
BufferDeallocate (data);
|
||||
}
|
||||
else
|
||||
{
|
||||
g_freeList.push_back (data);
|
||||
NS_ASSERT (IS_INITIALIZED(g_freeList));
|
||||
g_freeList->push_back (data);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -171,16 +200,23 @@ Buffer::Create (uint32_t dataSize)
|
||||
{
|
||||
/* try to find a buffer correctly sized. */
|
||||
g_nCreates++;
|
||||
while (!g_freeList.empty ())
|
||||
if (IS_UNINITIALIZED(g_freeList))
|
||||
{
|
||||
struct BufferData *data = g_freeList.back ();
|
||||
g_freeList.pop_back ();
|
||||
if (data->m_size >= dataSize)
|
||||
g_freeList = new BufferDataList ();
|
||||
}
|
||||
else if (IS_INITIALIZED(g_freeList))
|
||||
{
|
||||
while (!g_freeList->empty ())
|
||||
{
|
||||
data->m_count = 1;
|
||||
return data;
|
||||
struct BufferData *data = g_freeList->back ();
|
||||
g_freeList->pop_back ();
|
||||
if (data->m_size >= dataSize)
|
||||
{
|
||||
data->m_count = 1;
|
||||
return data;
|
||||
}
|
||||
BufferDeallocate (data);
|
||||
}
|
||||
BufferDeallocate (data);
|
||||
}
|
||||
g_nAllocs++;
|
||||
struct BufferData *data = BufferAllocate (dataSize);
|
||||
|
||||
Reference in New Issue
Block a user