二级配置器的实现部分源码剖析

xiaoxiao2021-02-27  92

有关内存池的分配本人在此未剖析,还请读者自行考虑

//一级配置器

template<int inst> class _malloc_alloc_one { 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(result==0) { result=oom_malloc(n); return result; } } static void *deallocate(void *p,size_t) { free(p); } static void *reallocate(void *p,size_t old_size,size_t new_size) { void *result=reallocate(p,mew_size); if (0==result) { result=oom_realloc(p,new_size); return result; } } }; //二级配置器 enum{_ALIGN=8};//小型区块的上调边界 enum{_MAX_BYTES=128};//小型区块的边界 enum{_NFREELISTS=_MAX_BYTES/_ALIGN};//个数 template<bool threads,int ints> class alloc { private: static size_t ROUND_UP(size_t bytes)//将bytes上调至8的倍数 { return (((bytes)+_ALIGN-1)&~(_ALIGN-1)); } private; union obj//freelist节点构造 { 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)); }//返回一个大小为n的对象,并可能加入大小为n的其他区块到freelist static void *refill(size_t n)//配置一大块空间,客容纳大小为size的qukuai { int obj=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; next_obj=(obj*)((char*)next_obj+n); if (nobjs-1==i) { current_obj->free_list_link=0; break; } else { current_obj->free_list_link=next_obj; } } return (result); } static char* chunk_alloc(size_t size,int &nobjs) { char *result; size_t total_bytes=size*nobjs; size_t 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 byte_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; } //配置heap空间,用来补充内存池 start_free=(char *)malloc(byte_to_get); if (0==start_free) { 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 (0!=p) { *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(byte_to_get); heap_size+=byte_to_get; end_free=start_free+byte_to_get; retrun (chunk_alloc(size,nobjs)); } } } static char *start_free; static char *end_free; static size_t heap_size; public: static void *allocate(size_t n)//空间配置函数 { obj void *volatile my_free_list; obj *result; if (n>(size_t)_MAX_BYTES)//大于128bytes就是使用以及配置器 { return (malloc_alloc::allocate(n)); } //寻找16个freelist中适当的一个 my_free_list =free_list+FREELIST_INDEX(n); result=*my_free_list; if(result==0)//没找到可用的freelist,准备重新填充新的freelist { void *r=refill(ROUND_UP(n)); return r; } //调整freelist *my_free_list=result->free_list_link; return (result); } static void deallocate(void *p,size_t n)//空间释放函数 { obj *q=(obj *)p; obj * volatile *my_free_liist; if (n>(size_t)_MAX_BYTES) { malloc_alloc::deallocate(p,n); q->free_list_link=*my_free_liist; *my_free_liist=q; } }     static void *reallocate(void *p,size_t old_size,size_t new_size); };
转载请注明原文地址: https://www.6miu.com/read-16306.html

最新回复(0)