ACE_Cached_Allocator和ACE_Dynamic_Cached_Allocator分配器的底层实现机制都是一样的,内部都有一个由
ACE_Locked_Free_List维护的空闲内存节点链表,我们来看看这2个分配器的构造函数实现
template <class T, class ACE_LOCK>
ACE_Cached_Allocator<T, ACE_LOCK>::ACE_Cached_Allocator (size_t n_chunks)
: pool_ (0),
free_list_ (ACE_PURE_FREE_LIST)
//指定底层的链表类型为ACE_PURE_FREE_LIST
{
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>);
}
}
//分配函数,从链表节中返回一个节点
template <class T, class ACE_LOCK> void *
ACE_Cached_Allocator<T, ACE_LOCK>::malloc (size_t nbytes)
{
if (nbytes > sizeof (T))
return 0;
return this->free_list_.remove ()->addr ();
}
同理ACE_Dynamic_Cached_Allocator的实现如下
template <class ACE_LOCK>
ACE_Dynamic_Cached_Allocator<ACE_LOCK>::ACE_Dynamic_Cached_Allocator
(size_t n_chunks, size_t chunk_size)
: pool_ (0),
free_list_ (ACE_PURE_FREE_LIST),
chunk_size_(chunk_size)
{
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<char>);
}
}
template <class ACE_LOCK> void *
ACE_Dynamic_Cached_Allocator<ACE_LOCK>::malloc (size_t nbytes)
{
if (nbytes > chunk_size_)
return 0;
return this->free_list_.remove ()->addr ();
}
可见实现都是很简单的,没什么难懂的地方,可以根据实际情形,自己对实现进行修改。
利用ACE的分配器,我们很容易就可以实现一个像SGI STL 内存池一样的东东来。。也可以根据需要自己进行扩展。