总体的设计思路:
首先按照内存块的大小申请N块大小的连续内存区域。
构造内存块的双向链表,有2种,一种是空闲链表;另外一种为已经使用的链表。该双向链表也是一块固定大小的内存区域,每个链表节点存储了当前内存块的地址、该节点上一个节点以及下一个节点。
#define ut_base(TYPE) \
struct { \
TYPE next; \
TYPE prev; \
}attribute((packed))
/**
define memory block struct _block
**//代码效果参考:http://www.jhylw.com.cn/542727747.html
**/typedef struct _block{
char data;
ut_base(struct _block) base;
}attribute((packed)) block;
内存池中存储链表的起始地址、内存块的起始地址、空闲链表的节点数、空闲链表的开始节点以及结束节点、已使用链表的节点的开始节点以及结束节点。
typedef struct _mem_pool
{
unsigned int blockCount;
unsigned int blockSize;
unsigned int freeSize;
unsigned int freeCount;
struct _block freeH;
struct _block freeT;
struct _block usedH;
struct _block usedT;
struct _block pBlockHead;
char pDataHead;
}attribute((packed)) mem_pool;
mem_pool.h
#define increment 64
/**
define base list
**/
#define ut_base(TYPE) \
struct { \
TYPE next; \
TYPE prev; \
}attribute((packed))
/**
define memory block struct _block
*/
typedef struct _block{
char data;
ut_base(struct _block) base;
}attribute((packed)) block;
/**
define memory pool
**/
typedef struct _mem_pool
{
unsigned int blockCount;
unsigned int blockSize;
unsigned int freeSize;
unsigned int freeCount;
struct _block freeH;
struct _block freeT;
struct _block usedH;
struct _block usedT;
struct _block pBlockHead;
char pDataHead;
}attribute((packed)) mem_pool;
/*
init a memory pool
*/
int pool_init(int blockSize,int blockCount);
/*
add block to mem_pool
**/
int pool_block(size_t unitSize,int blockCount);
/**
alloc memory from memory pool
**/
char pool_alloc(size_t allocSize);
/**
recyc memory from memory pool
**/
int pool_recyc();
/**
free all memory to operation system
**/
void pool_free();
/*
prt all list of memory pool
**/
void pool_prt();
mem_pool.c
#include
#include
#include [span style="color: rgba(0, 0, 255, 1)">string.h>
#include "mem_pool.h"
static mem_pool pool;
int pool_init(int blockSize,int blockCount)
{
mem_pool mp=&pool;
int flag=0;
mp->blockCount=mp->freeCount=blockCount;
mp->blockSize=blockSize;
mp->freeH=mp->freeT=NULL;
mp->usedH=mp->usedT=NULL;
flag=pool_block(blockSize,blockCount);
if(flag>0){fprintf(stderr," pool_init error\n");return 1;}
return 0;
}
int pool_block(size_t unitSize,int blockCount)
{
mem_pool mp=&pool;
int i=0;
mp->pBlockHead=(block )malloc(sizeof(block)blockCount);
mp->pDataHead=(char )malloc(sizeof(char)unitSizeblockCount);
memset(mp->pDataHead,'\0',sizeof(char)unitSizeblockCount);
mp->blockCount=blockCount;
mp->freeSize=sizeof(char)unitSizeblockCount;
block bk=NULL;
for(;i
{
bk=(block )mp->pBlockHead+(sizeof(block)i);
char data=mp->pDataHead+(sizeof(char)unitSizei);
bk->base.next=NULL;
bk->base.prev=mp->freeT;
if(mp->freeH==NULL)
{
mp->freeH=mp->freeT=bk;
}
else
{
mp->freeT->base.next=bk;
mp->freeT=bk;
}
bk->data=data;
}
printf(" ---------------pool_block(size_t unitSize=%d,int blockCount=%d)--------------\n",unitSize,blockCount);
printf(" mp->freeH : %p,mp->freeH->base.prev : %p\n",mp->freeH,mp->freeH->base.prev);
printf(" mp->freeT : %p,mp->freeT->base.next : %p\n",mp->freeT,mp->freeT->base.next);
return 0;
}
char pool_alloc(size_t allocSize)
{
mem_pool mp=&pool;
int allocCount=0;
int i=0;
if(mp->freeT==NULL)
{
pool_init(mp->blockSize,mp->blockCount);
printf("\t execute pool_init() \n");
}
if((allocSize%(mp->blockSize))==0)
{
allocCount=allocSize/(mp->blockSize);
}
else
{
allocCount=allocSize/(mp->blockSize)+1;
}
block bk=mp->freeT;
for(;ifreeT->base.prev;
bk->base.prev=NULL;
bk->base.next=NULL;
memset(bk->data,'\0',mp->blockSize);
// printf(" %d,mp->freeT : %p,mp->freeT->base.prev :%p\n",i,mp->freeT,mp->freeT->base.prev);
if(mp->usedH==NULL)
{
mp->usedH=mp->usedT=bk;
mp->usedH->base.prev=NULL;
}
else
{
bk->base.prev=mp->usedT;
mp->usedT->base.next=bk;
mp->usedT=bk;
//printf("bk :%p,bk->base.prev :%p,bk->base.next :%p\n",bk,bk->base.prev,bk->base.next);
}
//memset(mp->usedT->data,'\0',mp->blockSize);
mp->freeT=prev;
//printf("mp->freeT : %p\n",mp->freeT);
bk=mp->freeT;
//printf(" %d,mp->freeT : %p\n",i,mp->freeT);
}
mp->freeT->base.next=NULL;
//mp->freeT=mp->pBlockHead+(sizeof(block)(mp->blockCount-allocCount));
mp->freeCount=mp->freeCount-allocCount;
mp->freeSize=(mp->blockSize)(mp->blockCount-allocCount);
//memset(mp->pDataHead+mp->freeSize,'\0',allocCount);
printf(" --------pool_alloc(size_t allocSize=%d)--------\n",allocSize);
printf(" mp->freeH = %p,mp->freeT = %p\n",mp->freeH,mp->freeT);
printf(" mp->usedH = %p,mp->usedT = %p\n",mp->usedH,mp->usedT);
return mp->pDataHead+(mp->freeSize);
}
void pool_prt()
{
mem_pool p=&pool;
block fr=p->freeH;
block us=p->usedH;
int i=0;
printf(" \t**free list->\n");
while(fr!=NULL)
{
printf("\t(current = %p,data=%p)",fr,fr->data);
printf(",prev = %p",fr->base.prev);
printf(",next = %p\n",fr->base.next);
// printf("\t ## :current->data =%p",fr->data);
// printf(",prev->data = %p",fr->base.prev->data);
// printf(",next->data = %p\n",fr->base.next->data);
fr=fr->base.next;
i++;
}
printf(" \tfreelist length = %d\n",i);
i=0;
printf(" \t p->freeH = %p,p->freeT = %p\n",p->freeH,p->freeT);
printf(" \t**used list->\n");
while(us!=NULL)
{
printf("\t(current = %p,data=%p",us,us->data);
printf(",prev = %p",us->base.prev);
printf(",next = %p\n",us->base.next);
// printf("\t ## :current->data =%p",us->data);
//printf(",prev->data = %p",us->base.prev->data);
//printf(",next->data = %p\n",us->base.next->data);
us=us->base.next;
i++;
}
printf(" \tusedlist length = %d\n",i);
printf(" \tp->usedH = %p,p->usedT = %p\n",p->usedH,p->usedT);
printf("\n");
}
void pool_free()
{
mem_pool p=&pool;
free(p->pBlockHead);
free(p->pDataHead);
p->pBlockHead=NULL;
p->pDataHead=NULL;
printf("\t mem_pool free \n");
}
int pool_recyc(size_t freeSize)
{
mem_pool mp=&pool;
int cyc=0,i=0;
if(freeSize>(mp->blockSizemp->blockCount))
{
fprintf(stderr," freeSize is over all memory size in memory pool\n");
return 1;
}
if((freeSize%mp->blockSize)==0)
{
cyc=freeSize/(mp->blockSize);
}
else
{
cyc=(freeSize/mp->blockSize)+1;
}
printf(" --------pool_recyc(size_t freeize=%d)--------\n",freeSize);
printf(" recyc block count = %d\n",cyc);
printf(" begin: mp->freeH = %p,mp->freeT = %p\n",mp->freeH,mp->freeT);
printf(" begin: mp->usedH = %p,mp->usedT = %p\n",mp->usedH,mp->usedT);
printf(" begin: mp->freeCount = %d,mp->freeSize = %d\n",mp->freeCount,mp->freeSize);
if(mp->usedH==NULL)
{
fprintf(stderr," all block is not used in memory pool\n");
return 1;
}
block cur=mp->usedT;
for(;i
{
//link a block to free list
block *prev=cur->base.prev;
mp->freeT->base.next=cur;
cur->base.prev=mp->freeT;
memset(cur->data,'\0',mp->blockSize);
mp->freeT=cur;
//mp->usedT=mp->//代码效果参考:http://www.jhylw.com.cn/091324271.html
usedT->base.prev;cur=prev;
mp->usedT=prev;
//remove a block from used
}
if(cyc==(mp->blockCount-mp->freeCount))
{
mp->usedH=mp->usedT=NULL;
}
if(mp->usedT!=NULL)
{
if(mp->usedT==m