现在的位置: 首页 > 综合 > 正文

SGI STL 内存池(转)

2013年08月29日 ⁄ 综合 ⁄ 共 3558字 ⁄ 字号 评论关闭

将SGI STL的内存池抠了出来,win32平台

// mem_pool.h

#ifndef mem_pool_h
#define mem_pool_h

#pragma once

#define ALIGN     512
#define MAX_BLOCK_SIZE   20 * 1024
#define BLOCK_LIST_NUM   MAX_BLOCK_SIZE / ALIGN

class mem_pool
{
CRITICAL_SECTION alloc_lock;
union obj{
union obj* free_list_link;
char client_data[1];
};
obj* free_list [BLOCK_LIST_NUM];

static inline size_t round_up(size_t bytes){
return (bytes + ALIGN - 1) & ~(ALIGN - 1);
}

static inline size_t free_list_index(size_t bytes){
return (bytes + ALIGN - 1) / ALIGN - 1;
}

char* start_free;
char* end_free;
size_t heap_size;

char* chunk_alloc(size_t size, int& nobjs);
void* refill(size_t n);
public:
mem_pool(void);
~mem_pool(void);

void* allocate(size_t n);
void deallocate(void* p, size_t n);
inline size_t mem_size(){return heap_size;}
};

#endif

// mem_pool.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include "mem_pool.h"

mem_pool::mem_pool(void){
InitializeCriticalSection(&alloc_lock);
heap_size = 0;
start_free = 0;
end_free = 0;
memset(free_list, 0, sizeof(free_list));
}

mem_pool::~mem_pool(void){
DeleteCriticalSection(&alloc_lock);
}

char* mem_pool::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;
}

if(bytes_left >= size){
nobjs = bytes_left / size;
total_bytes = size * nobjs;
result = start_free;
start_free += total_bytes;
return result;
}

if(bytes_left > 0){
obj **my_free_list = free_list + free_list_index(bytes_left);
((obj*) start_free)->free_list_link = *my_free_list;
*my_free_list = (obj*) start_free;
}

size_t bytes_to_get = 2 * total_bytes + round_up(heap_size >> 4);
start_free = (char *) malloc(bytes_to_get);

if(start_free != 0){
heap_size += bytes_to_get;
end_free = start_free + bytes_to_get;
return chunk_alloc(size, nobjs);
}

int i = free_list_index(size) + 1;
obj **my_free_list, *p;
for(; i < BLOCK_LIST_NUM; ++i){
my_free_list = free_list + i;
p = *my_free_list;

if(0 != p){
   *my_free_list = p->free_list_link;
   start_free = (char *) p;
   end_free = start_free + (i + 1) * ALIGN;
   return chunk_alloc(size, nobjs);
}
}

end_free = 0;
return 0;
}

void* mem_pool::refill(size_t n){
int nobjs = 20;
char* chunk = chunk_alloc(n, nobjs);
obj** my_free_list;
obj* result;
obj *current_obj, *next_obj;
int i;

if(1 == nobjs) return chunk;
my_free_list = free_list + free_list_index(n);

result = (obj *) chunk;
-- nobjs;
*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 == i){
   current_obj->free_list_link = 0;
   break;
}
current_obj->free_list_link = next_obj;
}

return result;
}

void* mem_pool::allocate(size_t n){
obj** my_free_list;
obj* result;

if(n <= 0) return 0;
if(n > MAX_BLOCK_SIZE)
return malloc(n);

EnterCriticalSection(&alloc_lock);
try{
my_free_list = free_list + free_list_index(n);
result = *my_free_list;
if(result == 0){
   result = (obj *) refill(round_up(n));
}else{
   *my_free_list = result->free_list_link;
}
}catch(...){
result = 0;
}
LeaveCriticalSection(&alloc_lock);

return result;
}

void mem_pool::deallocate(void* p, size_t n){
obj *q = (obj *)p;
obj** my_free_list;

if(n > MAX_BLOCK_SIZE){
free(p);
return;
}

my_free_list = free_list + free_list_index(n);

EnterCriticalSection(&alloc_lock);
q->free_list_link = *my_free_list;
*my_free_list = q;
LeaveCriticalSection(&alloc_lock);
}

~~~~~

为C++标准库容器写自己的内存分配程序

http://dev.yesky.com/422/3146922.shtml

根据sgi 的STL源码的二级分配算法改写的内存池分配程序,只要稍微修改就可以实现共享内存方式管理,使用C++标准库容器中的map,set,multimap,multiset测试通过,vector测试通不过,原因是在内存回收的时候考虑的比较简单,vector每次分配内存个数不固定,回收也不固定,这样的话,程序还需要继续完善。

~~~~~~

类STL的内存分配,释放接口

近几日一直在开发偶的 EasyCode Windows 版(EasyCode Pro),不过,对于内存管理,自己写了一套,不用借助任何的 include 文件。

由于时间关系,没有写自己的 set_handler 代码,不过有时间会加上去的 :)
该代码您可以任意使用,但是如果出现意外,如硬盘烧毁,无故断电,光驱飞盘等等现象,DarkSpy一律不负任何责任 :-)
有一部分代码没有很完善,不过90%可以正常使用。
代码全部遵循是ISO C++98标准,如果您的编译器无法通过,则是编译器不支持,而不是代码问题。
http://www.4oa.com/Article/html/5/379/386/2005/9329.html

抱歉!评论已关闭.