allow --check --valgrind to pass again

This commit is contained in:
Mathieu Lacage
2009-09-26 16:55:06 +02:00
parent 04e650f6f1
commit f60e34c899

View File

@@ -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);