|
发表于 2010-7-6 16:40:38
|
显示全部楼层
兄弟,你运气真好,刚好昨天我把这段代码改完!
有两种办法,1直接修改ACE_Cached_Allocator的源代码。
2.像我下面提供的办法一样将ACE_Cached_Allocator扣出来,改完了放在自己的命名空间里。
这样也不会与原来的代码冲突了。
别害怕,看蓝色字的部分就成了。
注意中间有一处delete必须被注释掉,否则会重复delete导致崩溃
namespace MY
{
template <class T, class ACE_LOCK>
class ACE_Locked_Free_List_Ex :public ACE_Locked_Free_List<T,ACE_LOCK>
{
public:
ACE_Locked_Free_List_Ex (int mode = ACE_FREE_LIST_WITH_POOL,
size_t prealloc = ACE_DEFAULT_FREE_LIST_PREALLOC,
size_t lwm = ACE_DEFAULT_FREE_LIST_LWM,
size_t hwm = ACE_DEFAULT_FREE_LIST_HWM,
size_t inc = ACE_DEFAULT_FREE_LIST_INC):
ACE_Locked_Free_List<T,ACE_LOCK>(mode,prealloc,lwm,hwm,inc)
{
}
virtual void alloc (size_t n,size_t nObjSize)
{
for (; n > 0; n--)
{
char *ta = new char[nObjSize];
T *temp = 0;
temp = new (ta) T;
//ACE_NEW (temp, T);
temp->set_next (this->free_list_);
this->free_list_ = temp;
this->size_++;
}
}
virtual T *remove (size_t nObjSize)
{
ACE_MT (ACE_GUARD_RETURN (ACE_LOCK, ace_mon, this->mutex_, 0));
// If we are at the low water mark, add some nodes
if (this->mode_ != ACE_PURE_FREE_LIST && this->size_ <= this->lwm_)
this->alloc (this->inc_,nObjSize);
// Remove a node
T *temp = this->free_list_;
if (temp != 0)
{
this->free_list_ = this->free_list_->get_next ();
this->size_--;
}
return temp;
}
};
template <class T, class ACE_LOCK>
class ACE_Cached_Allocator : public ACE_New_Allocator
{
public:
/// Create a cached memory pool with @a n_chunks chunks
/// each with sizeof (TYPE) size.
ACE_Cached_Allocator (size_t n_chunks,const int nPoolType = ACE_FREE_LIST_WITH_POOL);
/// Clear things up.
~ACE_Cached_Allocator (void);
/**
* Get a chunk of memory from free list cache. Note that @a nbytes is
* only checked to make sure that it's less or equal to sizeof T, and is
* otherwise ignored since @c malloc() always returns a pointer to an
* item of sizeof (T).
*/
void *malloc (size_t nbytes = sizeof (T));
/**
* Get a chunk of memory from free list cache, giving them
* @a initial_value. Note that @a nbytes is only checked to make sure
* that it's less or equal to sizeof T, and is otherwise ignored since
* calloc() always returns a pointer to an item of sizeof (T).
*/
virtual void *calloc (size_t nbytes,
char initial_value = '\0');
/// This method is a no-op and just returns 0 since the free list
/// only works with fixed sized entities.
virtual void *calloc (size_t n_elem,
size_t elem_size,
char initial_value = '\0');
/// Return a chunk of memory back to free list cache.
void free (void *);
/// Return the number of chunks available in the cache.
size_t pool_depth (void);
private:
/// Remember how we allocate the memory in the first place so
/// we can clear things up later.
char *pool_;
/// Maintain a cached memory free list.
ACE_Locked_Free_List_Ex<ACE_Cached_Mem_Pool_Node<T>, ACE_LOCK> free_list_;
};
template <class T, class ACE_LOCK>
ACE_Cached_Allocator<T, ACE_LOCK>::ACE_Cached_Allocator (size_t n_chunks,const int nPoolType)
: pool_ (0),
free_list_ (nPoolType)
{
// To maintain alignment requirements, make sure that each element
// inserted into the free list is aligned properly for the platform.
// Since the memory is allocated as a char[], the compiler won't help.
// To make sure enough room is allocated, round up the size so that
// each element starts aligned.
//
// NOTE - this would probably be easier by defining pool_ as a pointer
// to T and allocating an array of them (the compiler would probably
// take care of the alignment for us), but then the ACE_NEW below would
// require a default constructor on T - a requirement that is not in
// previous versions of ACE
size_t chunk_size = sizeof (T);
chunk_size = ACE_MALLOC_ROUNDUP (chunk_size, ACE_MALLOC_ALIGN);
ACE_NEW (this->pool_,
char[n_chunks * chunk_size]);
for (size_t c = 0;
c < n_chunks;
c++)
{
void* placement = this->pool_ + c * chunk_size;
this->free_list_.add (new (placement) ACE_Cached_Mem_Pool_Node<T>);
}
// Put into free list using placement contructor, no real memory
// allocation in the above <new>.
}
template <class T, class ACE_LOCK>
ACE_Cached_Allocator<T, ACE_LOCK>::~ACE_Cached_Allocator (void)
{
//delete [] this->pool_;
}
template <class T, class ACE_LOCK> void *
ACE_Cached_Allocator<T, ACE_LOCK>::malloc (size_t nbytes)
{
// Check if size requested fits within pre-determined size.
if (nbytes > sizeof (T))
return 0;
// addr() call is really not absolutely necessary because of the way
// ACE_Cached_Mem_Pool_Node's internal structure arranged.
return this->free_list_.remove (obj_size)->addr ();
}
template <class T, class ACE_LOCK> void *
ACE_Cached_Allocator<T, ACE_LOCK>::calloc (size_t nbytes,
char initial_value)
{
// Check if size requested fits within pre-determined size.
if (nbytes > sizeof (T))
return 0;
// addr() call is really not absolutely necessary because of the way
// ACE_Cached_Mem_Pool_Node's internal structure arranged.
void *ptr = this->free_list_.remove (obj_size)->addr ();
if (ptr != 0)
ACE_OS::memset (ptr, initial_value, sizeof (T));
return ptr;
}
template <class T, class ACE_LOCK> void *
ACE_Cached_Allocator<T, ACE_LOCK>::calloc (size_t,
size_t,
char)
{
ACE_NOTSUP_RETURN (0);
}
template <class T, class ACE_LOCK> void
ACE_Cached_Allocator<T, ACE_LOCK>::free (void * ptr)
{
if (ptr != 0)
this->free_list_.add ((ACE_Cached_Mem_Pool_Node<T> *) ptr) ;
}
}
用法
typedef char MEMORY_DATA[1024];
typedef MY::ACE_Cached_Allocator<MEMORY_DATA,ACE_SYNCH_MUTEX> MyDataAlloc;
MyDataAllocEx aa(100);
[ 本帖最后由 modern 于 2010-7-8 13:03 编辑 ] |
|