C语言内存池
如果您使用我的代码,请您注明出处。
最近手机项目中设计一个服务器,服务器使用了epoll加线程池的方式,当然也少不了内存池,结合实际和网络设计一个内存池。
内存池基本要求:
1, 支持多线程
2, 支持各种大小内存分配
3, 接口直接操作内存
4, 一个进程只内含一个内存池,可以对池任意扩充。
整体设计:
设计基本思想:
1, 内存等级划分,超过等级直接分配。
2, 每个等级存在二条队列(未没有的内存、已经使用过多内存)
接口说明:
// ///
/// @Introduce
/// initialize memory pool,initialize queue
/// @Retunrs
// natural
// ///
int initmempool();
// ///
/// @Introduce
/// distribute memory pool memory
/// @Param size--distribute memory size
///
/// @Retunrs
// memory address
// ///
void* allocmempool(size_t size);
// ///
/// @Introduce
/// free distribute memory
/// @Param src--distribute memory
///
// ///
void freemempool(void** src);
// ///
/// @Introduce
/// destory memory pool
// ///
void destorymempool();
代码说明:
1, 内存等级划分
//round up 256
static size_t roundup(int size)
{
return (size + 255) >> 8;
}
//find index
static size_t listindex(int size)
{
return roundup(size) - 1;
}
2、 结构体
typedef struct mempool
{
queue use[MAX_MEMORY_POOL_CLASS];
queue nouse[MAX_MEMORY_POOL_CLASS];
}mempool;
3,辅助代码
#define NODE_HEADER_SIZE 4 //node header bite size
#define MAX_MEMORY_POOL_CLASS 4096 //memroy pool class
typedef unsigned long int uint32;
typedef union i32
{
char str[4];
uint32 num;
}i32;
static mempool gs_mempool;
static void i32toa(char* buf, uint32 num)
{
i32 un;
un.num = num;
memcpy((void*)buf, (const void*)un.str, (size_t)4);
}
static uint32 atoi32(char* buf)
{
i32 un;
memcpy(un.str, buf, 4);
return un.num;
}
4,主要实现代码
// ///
/// @Introduce
/// initialize memory pool,initialize queue
/// @Retunrs
// natural
// ///
int initmempool()
{
int i = 0;
for(i = 0; i < MAX_MEMORY_POOL_CLASS; i++)
{
initqueue(&gs_mempool.nouse[i]);
initqueue(&gs_mempool.use[i]);
}
return 0;
}
// ///
/// @Introduce
/// distribute memory pool memory
/// @Param size--distribute memory size
///
/// @Retunrs
// memory address
// ///
void* allocmempool(size_t size)
{
void* buf = NULL;
qnode* node = NULL;
int index = 0;
index = listindex(size);
if(index < MAX_MEMORY_POOL_CLASS)
{
if(lengthqueue(&gs_mempool.nouse[index]) > 0)
node = popqueue(&gs_mempool.nouse[index]);
else
{
buf = malloc(size + NODE_HEADER_SIZE);
node = allocnode(buf);
}
pushqueue(&gs_mempool.use[index], node);
buf = datanode(node);
}
else
{
buf = malloc(size + NODE_HEADER_SIZE);
}
i32toa((char*)buf, size);
return (char*)buf + NODE_HEADER_SIZE;
}
// ///
/// @Introduce
/// free distribute memory
/// @Param src--distribute memory
///
// ///
void freemempool(void** src)
{
qnode* node = NULL;
int index = 0, size = 0;
size = atoi32((char*)*src - NODE_HEADER_SIZE);
index = listindex(size);
if(index < MAX_MEMORY_POOL_CLASS)
{
node = popqueueindex(&gs_mempool.use[index], *src);
pushqueue(&gs_mempool.nouse[index], node);
}
else
{
free(((char*)*src - NODE_HEADER_SIZE));
*src = NULL;
}
}
// ///
/// @Introduce
/// destory memory pool
// ///
void destorymempool()
{
int i = 0;
for(i = 0; i < MAX_MEMORY_POOL_CLASS; i++)
{
clearqueue(&gs_mempool.nouse[i]);
clearqueue(&gs_mempool.use[i]);
}
}