STL之__default_alloc_template

template <bool threads , int inst>
class __default_alloc_template{
private:
	enum {_ALIGN = 8};
	enum {_MAX_BYTES = 128};
	enum {_NFREELISTS = 16};

	union Obj {
		union Obj *free_list_link;
		char  client_data[1];
	};

	static Obj* volatile free_list[_NFREELISTS];
	static size_t FREELIST_INDEX(size_t bytes) {
		return ( (bytes + _ALIGN - 1) / _ALIGN - 1) ;
	}
	static size_t ROUND_UP(size_t n){
		return ((n + _ALIGN - 1) & ~(_ALIGN - 1));
	}
	static void *refill(size_t n);
	static char *chunk_alloc(size_t size , int &nobjs);

	static char *start_free;
	static char *end_free;
	static size_t heap_size;

public:
	static void *allocate(size_t n);
	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>
char * __default_alloc_template<threads , inst> ::heap_size = 0;

template <bool threads , int inst>
char * __default_alloc_template<threads , inst> :: free_list[] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};

template <bool threads , int inst>
static void * __default_alloc_template<threads , inst> :: allocate(size_t n)
{
	if (n > _MAX_BYTES){
		return malloc_alloc::allocate(n);
	}

	Obj *volatile *my_free_list;
	Obj * result;

	my_free_list = free_list + FREELIST_INDEX(n);
	result = *my_free_list;
	if (result == 0) {
		void *r = refill(ROUND_UP(n));
		return r;
	}
	*my_free_list = result -> free_list_link;
	return result;
}

template <bool threads , int inst>
void __default_alloc_template<threads , inst> :: deallocate(void *p , size_t n)
{
	if ( n > _MAX_BYTES) {
		malloc_alloc::deallocate(p , n)
		return ;
	}

	Obj *q = (Obj *)p;
	Obj *volatile *my_free_list = free_list + FREELIST_INDEX(n);
	q->free_list_link = *my_free_list;
	*my_free_list->free_list_link = q;
}

template <bool threads , int inst>
void *__default_alloc_template<threads , inst>::refill(size_t n)
{
	int nobjs = 20;
	char *chunk = chunk_alloc(n , nobjs)
	Obj * volatile *my_free_list;
	Obj * result;
	Obj * current_obj , *next_obj;
	int i;

	if( nobjs == 1)
		return chunk;
	my_free_list = free_list + FREELIST_INDEX(n);
	result = (Obj *)chunk;
	*my_free_list = next_obj = (Obj *)(chunk + n);
	for (i = 1 ; ; ++i ) {
		current_obj = next_obj;
		if (nobjs - 1 == i){
			current_obj -> free_list_link = 0;
			break;
		}
		else {
			current_obj->free_list_link = next_obj;
		}
	}
}

template <bool threads , int inst>
char *__default_alloc_template<threads , inst>::chunk_alloc(size_t size , int &nobjs)
{
	char *result;
	size_t total_bytes = size * nobjs;
	size_t bytes_left = end_free - start_free;
	if (bytes_left >= total_bytes) {
		result = start_free;
		start_free += total_bytes;
		return result;
	}
	else if ( bytes_left >= size ) {
		nobjs = bytes_left / size;
		total_bytes = size * nobjs;
		result = start_free;
		start_free += total_bytes;
		return result;
	} 
	else {
		size_t bytes_to_get = 2 * total_bytes + ROUND_UP(heap_size >> 4);
		if (bytes_left > 0) {
			Obj* volatile *my_free_list = free_list + FREELIST_INDEX(bytes_left);
			((Obj*)start_free)->free_list_link = *my_free_list;
			*my_free_list = (Obj*) start_free;
		}
		start_free = (char *) malloc(bytes_to_get);
		if (start_free == 0){
			int i;
			Obj *volatile *my_free_list , *p;
			for( i = size ; i <= _MAX_BYTES ; i += _ALIGN){
				my_free_list = free_list + FREELIST_INDEX(i);
				p = *my_free_list;
				if (p != 0){
					*my_free_list = p->free_list_link;
					start_free = (char *)p;
					end_free   = start_free + i;
					return chunk_alloc(size , nobjs);
				}
			}
			end_free = 0;
			start_free = (char *) malloc_alloc::allocate(bytes_to_get);
		}
		heap_size += bytes_to_get;
		end_free = start_free + bytes_to_get;
		return chunk_alloc(size , nobjs);
	}
}

阅读更多
个人分类: STL源码分析
上一篇LeetCode 63. Unique Path II
下一篇STL之二级适配器
想对作者说点什么? 我来说一句

stl的学习:c++ STL

2009年09月07日 537KB 下载

走进STL走进STL走进STL

2011年06月04日 68KB 下载

stl源码剖析 stl源码剖析

2010年08月05日 7.03MB 下载

STL 例题.RAR

2011年07月21日 1.32MB 下载

没有更多推荐了,返回首页

关闭
关闭