zoukankan      html  css  js  c++  java
  • C 内存池的实现

      总体的设计思路:

          首先按照内存块的大小申请N*块大小的连续内存区域。

          构造内存块的双向链表,有2种,一种是空闲链表;另外一种为已经使用的链表。该双向链表也是一块固定大小的内存区域,每个链表节点存储了当前内存块的地址、该节点上一个节点以及下一个节点。

         

    #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;

          内存池中存储链表的起始地址、内存块的起始地址、空闲链表的节点数、空闲链表的开始节点以及结束节点、已使用链表的节点的开始节点以及结束节点。

    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 <stdio.h>
    #include <stdlib.h>
    #include <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
    ");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)*unitSize*blockCount);
        memset(mp->pDataHead,'',sizeof(char)*unitSize*blockCount);
        mp->blockCount=blockCount;
        mp->freeSize=sizeof(char)*unitSize*blockCount;
        block *bk=NULL;
        for(;i<blockCount;i++)
        {
          bk=(block *)mp->pBlockHead+(sizeof(block)*i);
          char *data=mp->pDataHead+(sizeof(char)*unitSize*i);
          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)--------------
    ",unitSize,blockCount);
        printf("        mp->freeH : %p,mp->freeH->base.prev : %p
    ",mp->freeH,mp->freeH->base.prev);
        printf("        mp->freeT : %p,mp->freeT->base.next : %p
    ",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("	 execute pool_init() 
    ");
        }
        if((allocSize%(mp->blockSize))==0)
        {
           allocCount=allocSize/(mp->blockSize);
        }
        else
        {
            allocCount=allocSize/(mp->blockSize)+1;
        }
        block *bk=mp->freeT;
        for(;i<allocCount;i++)
        {
            block *prev=mp->freeT->base.prev;
            bk->base.prev=NULL;
            bk->base.next=NULL;
            memset(bk->data,'',mp->blockSize);
           // printf(" %d,mp->freeT : %p,mp->freeT->base.prev :%p
    ",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
    ",bk,bk->base.prev,bk->base.next);
            }
            //memset(mp->usedT->data,'',mp->blockSize);
            mp->freeT=prev;
            //printf("mp->freeT : %p
    ",mp->freeT);
            bk=mp->freeT;
            //printf(" %d,mp->freeT : %p
    ",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,'',allocCount);
        printf(" --------pool_alloc(size_t allocSize=%d)--------
    ",allocSize); 
        printf("        mp->freeH = %p,mp->freeT = %p
    ",mp->freeH,mp->freeT);
        printf("        mp->usedH = %p,mp->usedT = %p
    ",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(" 	***********free list->
    ");
        while(fr!=NULL)
        {
            printf("	(current  = %p,data=%p)",fr,fr->data);
            printf(",prev = %p",fr->base.prev);
            printf(",next = %p
    ",fr->base.next);
           // printf("	  ## :current->data =%p",fr->data);
           // printf(",prev->data = %p",fr->base.prev->data);
           // printf(",next->data = %p
    ",fr->base.next->data);
            fr=fr->base.next;
            i++;
        }
        printf(" 	freelist length = %d
    ",i);
        i=0;
        printf(" 	 p->freeH = %p,p->freeT = %p
    ",p->freeH,p->freeT);
        printf(" 	**********used list->
    ");
        while(us!=NULL)
        {   
           printf("	(current  = %p,data=%p",us,us->data);
           printf(",prev = %p",us->base.prev);
           printf(",next = %p
    ",us->base.next);
          // printf("	  ## :current->data =%p",us->data);
           //printf(",prev->data = %p",us->base.prev->data);
           //printf(",next->data = %p
    ",us->base.next->data);
           us=us->base.next;
           i++;
        } 
        printf(" 	usedlist length = %d
    ",i);
        printf(" 	p->usedH  = %p,p->usedT = %p
    ",p->usedH,p->usedT);
        printf("
    ");
    }
    void pool_free()
    {
        mem_pool *p=&pool;
        free(p->pBlockHead);
        free(p->pDataHead);
        p->pBlockHead=NULL;
        p->pDataHead=NULL;
        printf("	 mem_pool free 
    ");
    }
    int pool_recyc(size_t freeSize)
    {
        mem_pool *mp=&pool;
        int cyc=0,i=0;
        if(freeSize>(mp->blockSize*mp->blockCount))
        {
            fprintf(stderr," freeSize is over all memory size in memory pool
    ");
            return 1;
        }
        if((freeSize%mp->blockSize)==0)
        {
            cyc=freeSize/(mp->blockSize);
        }
        else
        {
            cyc=(freeSize/mp->blockSize)+1;
        }
        printf(" --------pool_recyc(size_t freeize=%d)--------
    ",freeSize);
        printf("        recyc block count = %d
    ",cyc);
        printf("        begin: mp->freeH = %p,mp->freeT = %p
    ",mp->freeH,mp->freeT);
        printf("        begin: mp->usedH = %p,mp->usedT = %p
    ",mp->usedH,mp->usedT);
        printf("        begin: mp->freeCount = %d,mp->freeSize = %d
    ",mp->freeCount,mp->freeSize);
        if(mp->usedH==NULL)
        {
            fprintf(stderr," all block is not used in memory pool
    ");
            return 1;
        }
        block *cur=mp->usedT;
        for(;i<cyc;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,'',mp->blockSize);
             mp->freeT=cur;
             //mp->usedT=mp->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==mp->usedH)
            {
                mp->usedH->base.prev=NULL;
                mp->usedT->base.next=NULL;
            }
        }
        mp->freeT->base.next=NULL;
        mp->freeCount=mp->freeCount+cyc;
        mp->freeSize=mp->freeSize+(mp->blockSize*cyc);
        printf("        end: mp->freeH = %p,mp->freeT = %p
    ",mp->freeH,mp->freeT);
        printf("        end: mp->usedH = %p,mp->usedT = %p
    ",mp->usedH,mp->usedT);
        printf("        end: mp->freeCount = %d,mp->freeSize = %d
    ",mp->freeCount,mp->freeSize);
        return 0;
    }
    int main(void)
    {
        printf(" pool_init(%d,%d) = %d
    ",4,100,pool_init(5,10));
        pool_prt();
        char *p=pool_alloc(14);
        memset(p,'1',13);
        printf(" char *p =%s
    ",p);
        pool_prt();
        pool_recyc(12);
        pool_prt();
        char *p1=pool_alloc(6);
        memset(p1,'8',5);
        printf("char *p1 = %s
    ",p1);
        pool_prt();
        pool_recyc(3);
        printf(" char *p =%s
    ",p);
        pool_prt();
        pool_free();
        return 0;
    }
  • 相关阅读:
    uwsgi+nginx+django
    uwsgi怎么启动停止
    centos7 命令
    django 配置静态文件
    centos7 安装node
    python 字符串拼接
    Python 编码
    python 文件夹递归
    ArcGIS二次开发的几种方式
    集合的操作
  • 原文地址:https://www.cnblogs.com/innobase/p/4565363.html
Copyright © 2011-2022 走看看