SGI特殊的空间配置器,构成如下:
<memory> ---------------<stl_construct.h> 定义了全局函数construct()和destroy()
---------------<stl_alloc.h> 定义了一、二级空间配置器,alloc;
---------------<stl_uninitialized.h> 定义了全局函数,用来填充,复制内存数据。
构造和析构基本工具:
construct(T1*p, const T2& value)----------------------new(p) T1(value);//placement new
------------------<ForwardIterator,ForwardIterator> _destory()--------------destory(&*first);
--------------_true_type(_type_traits<>)
destroy() ------------------(char*,char*)
------------------(wchar_t*,wchar_t*)
------------------(T* pointer) pointer->~T();
空间的配置和释放:
SGI正是以malloc()和free()完成内存的配置和释放。考虑到内存破碎问题,SGI设计了双层级配置器,接口方式和。
第一级配置器直接使用malloc()和free();
第二级配置器采用不同策略,当配置区超过128字节时,调用第一级。否则采用内存池。
#ifdef _USE_MALLOC
typedef _malloc_alloc_template<0> malloc_alloc;
typedef malloc_alloc alloc;
#else
typedef _default_alloc_template<_NODE_ALLOCATOR_THREADS,0>alloc;
#endif
为了保证alloc满足STL规格:
template<class T, class Alloc>
class simple_alloc{
public:
static T* allocate(size_t n)
{return 0 == n? 0 : (T*)Alloc::allocate(n*sizeof(T));}
static T* allocate(void)
{return (T*)Alloc::allocate(sizeof(T));}
static void deallocate(T *p,size_t n)
{if(n !=0) Alloc::deallocate(p, n * sizeof(T));}
static void deallocate(T* p)
{Alloc::deallocate(p,sizeof(T));}
}
//第一级配置器
template<int inst>
class _malloc_alloc_template{
private:
static void *oom_malloc(size_t);
static void* oom_realloc(void* ,size_t);
static void (*_malloc_alloc_oom_handler)();
public:
static void* allocate(size_t n)
{
void* result = malloc(n);
if(null == result) result = oom_malloc(n);
return result;
}
static void deallocate(void* p,size_t /*n*/)
{
free(p);
}
static void* reallocate(void *p , size_t /*old_sz*/,size_t new_sz){
void *result = realloc(p,new_sz);
if(null == result )result = oom_realloc(p,new_sz);
return result;
}
static void (* set_malloc_handler)(void (*f)())))
{
void (* old)() = _malloc_alloc_oom_handler;
_malloc_alloc_oom_handler = f;
return old;
}
};
template<int inst>
void (* _malloc_alloc_template<inst>::_malloc_alloc_oom_handler)() = 0;
template<int inst>
void* _malloc_alloc_template<inst>::oom_malloc(size_t n)
{
void (* my_malloc_handler)();
void* result;
for(;;)
{
my_malloc_handler = _malloc_alloc_oom_handler;
if(0 == my_malloc_handler ){_THROW_BAD_ALLOC;}
(*my_malloc_handler)();
result = malloc(n);
if(result )return result;
}
}
template<int inst>
void* _malloc_alloc_template<inst>::oom_realloc(void* p, size_t n)
{
void (* my_malloc_handler)();
void* result;
for(;;)
{
my_malloc_handler = _malloc_alloc_oom_handler;
if(0 == my_malloc_handler ){_THROW_BAD_ALLOC;}
(*my_malloc_handler)();
result = realloc(p,n);
if(result )return result;
}
}
//第二级配置器精髓1:SGI第二级配置器会主动将任何小额区块的内存需求量上调至8的倍数,并维护16个free-lists,各自管理的大小分别为8,16,24,32......120,128bytes的小额区块。
精髓2:free-lists的节点结构如下://能够重复利用空间
union obj{
union obj * free_list_link;
char client_data[1];
}
精髓3:Round_up函数 ((bytes)+ 7)& (~7);
精髓4:空间配置函数allocate()
static void * allocate(size_t n)
{
obj * volatile *my_free_list;
obj * result;
if(n > (size_t) _MAX_BYTES){
return(malloc_alloc::allocate(n));
}
my_free_list = free_list + FREELIST_INDEX(n);
result = *my_free_list;
if(result == 0){
void * r = refill(ROUND_P(n));
return r;
}
*my_free_list = result->free_list_link;//相当于链表
return result;
}