STL具有次配置能力的SGI空间适配器

空间适配器既是分配内存或者硬盘空间的组件,因为STL的操作对象都存放在容器里,容器是需要配置空间的。

SGI 版本的标准的空间配置器

SGI 版标准的空间配置器,基本只是通过 ::operator new 和 ::operator delete 的薄薄一层封装实现的,基本上没有效率上的强化。

::operator new 和 new 的区别:
new:new的昨天是分配内存+调用构造函数初始化。
::opetarot new:调用一个函数来完成必需的内存分配,它对构造函数一无所知,类似malloc();

类似:

void * operator new(size_t size);
SGI特殊的空间配置器
构造和析构的工具
//construct:
template <class T1, class T2>
inline void construct(T1 *p, const T2& value) {
	new (p) T1(value);
}

//destory
//destory 有两个版本,分别是 接收一个指针,和接收两个迭代器

//接收一个指针
template <class T1>
inline void destory(T1 *pointer) {
	pointer->~T();
}

//
template <class ForwardIterator>
inline void destory(ForwardIterator first, ForwardIterator last, T*) {
	/*利用typedef typename __type_traits<T>::has_trivial_destructor trivial_destructor, 
	判断类型T的析构是否存在特性,并调用__destroy_aux,传入trivial_destructor*/
	typedef typename __type_traits<T>::has_trivial_destructor trivial_destructor;
	/*
	若存在特性,则会调用到__destroy_aux(Iterator, Iterator, __false_type), 并逐一对[first, last)范围内的元素进行析构
	若不存在特性,则会调用到__destroy_aux(Iterator, Iterator, __true_type), 并什么都不做
	*/
	__destory_aux(first, last, trivial_destructor());
}
//
空间的配置与释放,std:alloc

__malloc_alloc_template 是第一级配置器,__default_alloc_template是第二级配置器。二级配置器维护了16个自由链表,负责小型区块的配置能力。当配置内存大于123bytes 或内存不足时,转调用一级配置器。

第一级配置器 __malloc_alloc_template
class__malloc_alloc_template {
private:
//以下都是函式指标,所代表的函式将用来处理内存不足的情况。
//oom : out of memory.
staticvoid *oom_malloc(size_t);
staticvoid *oom_realloc(void*, size_t);
staticvoid (* __malloc_alloc_oom_handler)();//内存不足处理例程,被上面的两个函数调用

public:
static void * allocate(size_t n)
{
    void  *result=malloc(n);//第一级配置器直接使用 malloc()
    //以下,无法满足需求时,改用 oom_malloc()
    if (0== result) result= oom_malloc(n);
    return  result;
}

staticvoid deallocate(void*p, size_t /* n */)
{
	free(p); //第一级配置器直接使用free()
}

staticvoid * reallocate(void*p, size_t /* old_sz */,size_t new_sz)
{
    void  *  result  =realloc(p, new_sz);//第一级配置器直接使用 rea
    //以下,无法满足需求时,改用 oom_realloc()
    if (0== result) result= oom_realloc(p, new_sz);
    return  result;

}

//以下模拟 C++的 set_new_handler(). 换句话说,你可以透过它,
//指定你自己的 out-of-memory handler
staticvoid (* set_malloc_handler(void (*f)()))()
{
    void  (*  old)()  =  __malloc_alloc_oom_handler;
	__malloc_alloc_oom_handler =f;
    return(old);
}

};//CLASS定义结束



//malloc_alloc out-of-memory handling
//初值为 0。有待客端设定。
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);
    }
}


//注意,以下直接将参数 inst指定为 0。
typedef__malloc_alloc_template<0> malloc_alloc;


第二级配置器 __default_alloc_template
enum {_ALIGN = 8};//小型区块的上调边界
enum {_MAX_BYTES = 128};//小型区块的上限
enum {_NFREELISTS = 16}; // _MAX_BYTES/_ALIGN,free-list的个数

template <bool threads, int inst>
class __default_alloc_template 
{
private:
	/*将__bytes上调至8的倍数*/
	static size_t ROUND_UP(size_t bytes) { 
		return (((bytes) + _ALIGN-1) & ~(_ALIGN - 1)); 
	}

  //free-list的节点构造
	union obj {
		union obj* free_list_link;
		char client_data[1];    /* The client sees this.*/
	};

private:    
	static obj* volatile free_list[__NFREELISTS];     
  
    //根据区块大小,决定使用哪个free-list
    static  size_t FREELIST_INDEX(size_t bytes) {    
		return (((bytes) + _ALIGN-1)/_ALIGN - 1);   
	}   

	static void* refill(size_t n);

	static char* chunk_alloc(size_t size, int& nobjs);
	
	// Chunk allocation state.
	static char* start_free;//内存池起始位置
	static char* end_free;//内存池结束位置
	static size_t heap_size;
public:
	/* n must be > 0 */  
	static void* allocate(size_t n)//申请空间
	{...}
	/* p may not be 0 */
	static void deallocate(void* p, size_t n)//释放空间
	{...}
	//重新配置空间
	static void* reallocate(void* p, size_t old_sz, size_t new_sz);
} ;

template <bool threads, int inst>
char* __default_alloc_template<threads, __inst>::_start_free = 0;

template <bool threads, int inst>
char* __default_alloc_template<threads, inst>::_end_free = 0;

template <bool threads, int inst>
size_t __default_alloc_template<threads, inst>::_heap_size = 0;

template <bool threads, int inst>
typename __default_alloc_template<threads, inst>::obj* volatile
__default_alloc_template<threads, inst> ::free_list[_NFREELISTS] = 
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, };

参见书记 p61或者
参考链接

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值