内存池的实现

基本的架构设计:

这里写图片描述

/*************************************************************************
        > File Name: mem_pool.h
        > Author: perrynzhou
        > Mail: 715169549@qq.com
        > Created Time: Wed 21 Sep 2016 02:51:56 AM HKT
 ************************************************************************/

#ifndef _MEM_POOL_H
#define _MEM_POOL_H
#include <stdint.h>
typedef struct _MemPool MemPool;
MemPool *CreatedMemPool ();
void *AllocMem (uint32_t size, MemPool * mp);
void FreeMem (void *ptr, MemPool * mp);
void DestroyMemPool (MemPool * mp);
#endif
/*************************************************************************
        > File Name: mem_pool.c
        > Author: perrynzhou
        > Mail: 715169549@qq.com
        > Created Time: Wed 21 Sep 2016 02:59:39 AM HKT
 ************************************************************************/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "mem_pool.h"
typedef struct _MemNode
{
        struct _MemNode *Next;
        uint32_t Size;
        char Buf[];
} __attribute__ ((__packed__)) MemNode;
struct _MemPool
{
        MemNode **FreeBlocks;           //the array of used blocks in this pool
        MemNode **UsedBlocks;
} __attribute__ ((__packed__));

//define max type 
#define MAXTYPE 64
//align 8 byte
#define ALIGN_SIZE 8
//------avoid using -> 
#define FreeBlocks(T)    ((T)->FreeBlocks)
#define UsedBlocks(T)    ((T)->UsedBlocks)
//MemNode 
#define Next(T)        ((T)->Next)
#define Size(T)        ((T)->Size)
#define Buf(T)         ((T)->Buf)
inline uint32_t RoundUp (uint32_t size)
{
        return ((size + (ALIGN_SIZE - 1)) & ~(ALIGN_SIZE - 1));
}

//memory aligin whit 8 byte
inline uint32_t Index (uint32_t size)
{
        return ((RoundUp (size) / ALIGN_SIZE) - 1);
}

//remove link of target memnode
static void _Relink (MemNode * first, MemNode * mn)
{
        if (mn != NULL)
        {
                while (first != NULL)
                {
                        MemNode *prev = NULL;
                        if (first == mn)
                        {
                                if (Next (first) == NULL)
                                {
                                        prev = NULL;
                                }
                                else
                                {
                                        prev = Next (first);
                                }
                                break;
                        }
                        else
                        {
                                prev = first;
                        }
                        first = Next (first);
                }
        }
}

//check memory block is exists in usedblocks list
static int _IsUsed (MemNode * mn, uint32_t index, MemPool * mp)
{
        if (mp == NULL || mn == NULL)
        {
                return -1;
        }
        MemNode *free = FreeBlocks (mp)[index];
        if (free == NULL)
        {
                return 0;
        }
        while (free != NULL)
        {
                if (free == mn)
                {
                        return -1;
                }
                free = Next (free);
        }
        return 0;
}

static void *_Alloc (uint32_t size, MemPool * mp)
{
        if (mp == NULL)
        {
                return NULL;
        }
        uint32_t curSize = RoundUp (size);
        uint32_t iIndex = (curSize / ALIGN_SIZE) - 1;
        MemNode *mn = malloc (sizeof (*mn) + curSize);
        char *ptr = NULL;
        if (mn != NULL)
        {
                Next (mn) = NULL;
                Size (mn) = curSize;
                Next (mn) = UsedBlocks (mp)[iIndex];
                UsedBlocks (mp)[iIndex] = mn;
                ptr = Buf (mn);
                memset (ptr, 0, curSize);
                fprintf (stdout, "......index =%d,system malloc sizeof(memnode) =%d,size=%d,next=%p,buf=%p\n", iIndex, sizeof (*mn), Size (mn), Next (mn), Buf (mn));
        }
        return (char *) ptr;
}

MemPool *CreateMemPool ()
{
        MemPool *mp = (MemPool *) malloc (sizeof (*mp));
        if (mp != NULL)
        {
                UsedBlocks (mp) = (MemNode **) malloc (sizeof (MemNode *) * MAXTYPE);
                FreeBlocks (mp) = (MemNode **) malloc (sizeof (MemNode *) * MAXTYPE);
                int iIndex = 0;
                for (iIndex = 0; iIndex < MAXTYPE; iIndex++)
                {
                        UsedBlocks (mp)[iIndex] = FreeBlocks (mp)[iIndex] = NULL;
                        fprintf (stdout, "...UseBlocks[%d] =%p,FreeBlocks[%d] =%p\n", iIndex, UsedBlocks (mp)[iIndex], iIndex, FreeBlocks (mp)[iIndex]);
                }
                fprintf (stdout, "...init memory pool\n");
        }
        return mp;
}

//malloc memory from memory pool
void *AllocMem (uint32_t size, MemPool * mp)
{
        if (mp == NULL)
        {
                return NULL;
        }
        MemNode *target = NULL;
        char *ptr = NULL;
        uint32_t index = Index (size);
        if (index >= MAXTYPE)
        {
                return NULL;
        }
        if (FreeBlocks (mp)[index] == NULL)
        {
                ptr = _Alloc (size, mp);
        }
        else
        {
                target = FreeBlocks (mp)[index];
                FreeBlocks (mp)[index] = Next (target);
                Next (target) = NULL;
                Next (target) = UsedBlocks (mp)[index];
                UsedBlocks (mp)[index] = target;
                ptr = Buf (target);
                fprintf (stdout, "index=%d...malloc from pool MemNode =%p,next=%p,size=%d\n", index, target, Next (target), Size (target));
        }
        return ptr;
}

//put unused block to memory pool
void FreeMem (void *block, MemPool * mp)
{
        if (mp != NULL && block != NULL)
        {
                MemNode *mn = (MemNode *) (block - sizeof (*mn));
                uint32_t index = (Size (mn) / ALIGN_SIZE) - 1;
                if (_IsUsed (mn, index, mp) != -1)
                {
                        MemNode *first = UsedBlocks (mp)[index];
                        if (first == mn)
                        {
                                UsedBlocks (mp)[index] = Next (first);
                        }
                        else
                        {
                                _Relink (first, mn);
                        }
                        Next (mn) = NULL;
                        memset (Buf (mn), 0, Size (mn));

                        Next (mn) = FreeBlocks (mp)[index];
                        FreeBlocks (mp)[index] = mn;
                        fprintf (stdout, "......put unused block to pool,MemNode =%p,size=%d\n", mn, Size (mn));
                }
        }
}

void PtrMemPoolUsed (MemPool * mp)
{
        int i = 0;
        for (; i < MAXTYPE; i++)
        {
                MemNode *used = UsedBlocks (mp)[i];
                while (used != NULL)
                {
                        fprintf (stdout, "     %d.....Used MemNode =%p,Size=%d,Next=%p\n", i, used, Size (used), Next (used));
                        used = Next (used);
                }
        }
}

void PtrMemPoolFree (MemPool * mp)
{
        int i = 0;
        for (; i < MAXTYPE; i++)
        {
                MemNode *free = FreeBlocks (mp)[i];
                while (free != NULL)
                {
                        fprintf (stdout, "     %d.....Free MemNode =%p,Size=%d,Next=%p\n", i, free, Size (free), Next (free));
                        free = Next (free);
                }
        }
}

void DestroyMemPool (MemPool * mp)
{
        if (mp != NULL)
        {
                MemNode *usedMemNode = UsedBlocks (mp)[0];
                MemNode *freeMemNode = FreeBlocks (mp)[0];
                while (usedMemNode != NULL)
                {
                        MemNode *next = Next (usedMemNode);
                        free (usedMemNode);
                        usedMemNode = next;
                }
                while (freeMemNode != NULL)
                {
                        MemNode *next = Next (freeMemNode);
                        free (freeMemNode);
                        freeMemNode = next;
                }
                if (usedMemNode != NULL)
                {
                        usedMemNode = NULL;
                }
                if (freeMemNode != NULL)
                {
                        freeMemNode = NULL;
                }
                //my_log(p,"...free all blocks from pool %s","");
        }
        if (mp != NULL)
        {
                fprintf (stdout, "...free all blocks from pool %p\n", mp);
                free (mp);
                mp = NULL;
        }
}
/*************************************************************************
        > File Name: mem_pool_test.c
        > Author: perrynzhou
        > Mail: 715169549@qq.com
        > Created Time: Thu 22 Sep 2016 01:37:31 AM HKT
 ************************************************************************/

#include <stdio.h>
#include <unistd.h>
#include "mem_pool.h"
int main (void)
{
        MemPool *mp = (MemPool *) CreateMemPool ();
        int max = 20, i;
        void *target[20] = { NULL };
        for (i = 0; i < max; i++)
        {

                target[i] = AllocMem ((i + 1) * (rand () % 20) + 7, mp);
                if (i % 5 == 0)
                {

                        FreeMem (target[i], mp);

                }
        }
        PtrMemPoolUsed (mp);
        PtrMemPoolFree (mp);
        fprintf (stdout, "------------------------------------split-------------------------\n");
        for (i = 0; i < max; i++)
        {
                if (i % 4 == 0)
                {
                        fprintf (stdout, "*********************freemem********************************\n");
                        FreeMem (target[6], mp);
                        PtrMemPoolUsed (mp);
                        PtrMemPoolFree (mp);

                }
        }
        fprintf (stdout, "----------------------end--------------------\n");
        DestroyMemPool (mp);
        return 0;
}

测试结果:

$ ./a.out
...UseBlocks[0] =(nil),FreeBlocks[0] =(nil)   -- (0+1)*8 byte
..........................
...UseBlocks[63] =(nil),FreeBlocks[63] =(nil)  --(63+1) * 8 byte
...init memory pool
......index =0,system malloc sizeof(memnode) =12,size=8,next=(nil),buf=0x1b4b45c
......put unused block to pool,MemNode =0x1b4b450,size=8
......index =1,system malloc sizeof(memnode) =12,size=16,next=(nil),buf=0x1b4b47c
......index =2,system malloc sizeof(memnode) =12,size=24,next=(nil),buf=0x1b4b4ac
......put unused block to pool,MemNode =0x1b4b4a0,size=24
index=2...malloc from pool MemNode =0x1b4b4a0,next=(nil),size=24
......index =2,system malloc sizeof(memnode) =12,size=24,next=0x1b4b4a0,buf=0x1b4b4dc
......put unused block to pool,MemNode =0x1b4b4d0,size=24
index=0...malloc from pool MemNode =0x1b4b450,next=(nil),size=8
......index =1,system malloc sizeof(memnode) =12,size=16,next=0x1b4b470,buf=0x1b4b50c
......put unused block to pool,MemNode =0x1b4b500,size=16
index=1...malloc from pool MemNode =0x1b4b500,next=0x1b4b470,size=16
......index =4,system malloc sizeof(memnode) =12,size=40,next=(nil),buf=0x1b4b53c
......put unused block to pool,MemNode =0x1b4b530,size=40
......index =1,system malloc sizeof(memnode) =12,size=16,next=0x1b4b500,buf=0x1b4b57c
......index =0,system malloc sizeof(memnode) =12,size=8,next=0x1b4b450,buf=0x1b4b5ac
......put unused block to pool,MemNode =0x1b4b5a0,size=8
......index =1,system malloc sizeof(memnode) =12,size=16,next=0x1b4b570,buf=0x1b4b5cc
index=0...malloc from pool MemNode =0x1b4b5a0,next=0x1b4b450,size=8
......put unused block to pool,MemNode =0x1b4b5a0,size=8
index=4...malloc from pool MemNode =0x1b4b530,next=(nil),size=40
index=2...malloc from pool MemNode =0x1b4b4d0,next=0x1b4b4a0,size=24
......put unused block to pool,MemNode =0x1b4b4d0,size=24
index=0...malloc from pool MemNode =0x1b4b5a0,next=0x1b4b450,size=8
......index =0,system malloc sizeof(memnode) =12,size=8,next=0x1b4b5a0,buf=0x1b4b5fc
......put unused block to pool,MemNode =0x1b4b5f0,size=8
index=2...malloc from pool MemNode =0x1b4b4d0,next=0x1b4b4a0,size=24
......index =1,system malloc sizeof(memnode) =12,size=16,next=0x1b4b5c0,buf=0x1b4b61c
......put unused block to pool,MemNode =0x1b4b610,size=16
......index =3,system malloc sizeof(memnode) =12,size=32,next=(nil),buf=0x1b4b64c
     0.....Used MemNode =0x1b4b5a0,Size=8,Next=0x1b4b450
     0.....Used MemNode =0x1b4b450,Size=8,Next=(nil)
     1.....Used MemNode =0x1b4b5c0,Size=16,Next=0x1b4b570
     1.....Used MemNode =0x1b4b570,Size=16,Next=0x1b4b500
     1.....Used MemNode =0x1b4b500,Size=16,Next=0x1b4b470
     1.....Used MemNode =0x1b4b470,Size=16,Next=(nil)
     2.....Used MemNode =0x1b4b4d0,Size=24,Next=0x1b4b4a0
     2.....Used MemNode =0x1b4b4a0,Size=24,Next=(nil)
     3.....Used MemNode =0x1b4b640,Size=32,Next=(nil)
     4.....Used MemNode =0x1b4b530,Size=40,Next=(nil)
     0.....Free MemNode =0x1b4b5f0,Size=8,Next=(nil)
     1.....Free MemNode =0x1b4b610,Size=16,Next=(nil)
------------------------------------split-------------------------
*********************freemem********************************
......put unused block to pool,MemNode =0x1b4b500,size=16
     0.....Used MemNode =0x1b4b5a0,Size=8,Next=0x1b4b450
     0.....Used MemNode =0x1b4b450,Size=8,Next=(nil)
     1.....Used MemNode =0x1b4b5c0,Size=16,Next=0x1b4b570
     1.....Used MemNode =0x1b4b570,Size=16,Next=0x1b4b500
     1.....Used MemNode =0x1b4b500,Size=16,Next=0x1b4b610
     1.....Used MemNode =0x1b4b610,Size=16,Next=(nil)
     2.....Used MemNode =0x1b4b4d0,Size=24,Next=0x1b4b4a0
     2.....Used MemNode =0x1b4b4a0,Size=24,Next=(nil)
     3.....Used MemNode =0x1b4b640,Size=32,Next=(nil)
     4.....Used MemNode =0x1b4b530,Size=40,Next=(nil)
     0.....Free MemNode =0x1b4b5f0,Size=8,Next=(nil)
     1.....Free MemNode =0x1b4b500,Size=16,Next=0x1b4b610
     1.....Free MemNode =0x1b4b610,Size=16,Next=(nil)
*********************freemem********************************
     0.....Used MemNode =0x1b4b5a0,Size=8,Next=0x1b4b450
     0.....Used MemNode =0x1b4b450,Size=8,Next=(nil)
     1.....Used MemNode =0x1b4b5c0,Size=16,Next=0x1b4b570
     1.....Used MemNode =0x1b4b570,Size=16,Next=0x1b4b500
     1.....Used MemNode =0x1b4b500,Size=16,Next=0x1b4b610
     1.....Used MemNode =0x1b4b610,Size=16,Next=(nil)
     2.....Used MemNode =0x1b4b4d0,Size=24,Next=0x1b4b4a0
     2.....Used MemNode =0x1b4b4a0,Size=24,Next=(nil)
     3.....Used MemNode =0x1b4b640,Size=32,Next=(nil)
     4.....Used MemNode =0x1b4b530,Size=40,Next=(nil)
     0.....Free MemNode =0x1b4b5f0,Size=8,Next=(nil)
     1.....Free MemNode =0x1b4b500,Size=16,Next=0x1b4b610
     1.....Free MemNode =0x1b4b610,Size=16,Next=(nil)
*********************freemem********************************
     0.....Used MemNode =0x1b4b5a0,Size=8,Next=0x1b4b450
     0.....Used MemNode =0x1b4b450,Size=8,Next=(nil)
     1.....Used MemNode =0x1b4b5c0,Size=16,Next=0x1b4b570
     1.....Used MemNode =0x1b4b570,Size=16,Next=0x1b4b500
     1.....Used MemNode =0x1b4b500,Size=16,Next=0x1b4b610
     1.....Used MemNode =0x1b4b610,Size=16,Next=(nil)
     2.....Used MemNode =0x1b4b4d0,Size=24,Next=0x1b4b4a0
     2.....Used MemNode =0x1b4b4a0,Size=24,Next=(nil)
     3.....Used MemNode =0x1b4b640,Size=32,Next=(nil)
     4.....Used MemNode =0x1b4b530,Size=40,Next=(nil)
     0.....Free MemNode =0x1b4b5f0,Size=8,Next=(nil)
     1.....Free MemNode =0x1b4b500,Size=16,Next=0x1b4b610
     1.....Free MemNode =0x1b4b610,Size=16,Next=(nil)
*********************freemem********************************
     0.....Used MemNode =0x1b4b5a0,Size=8,Next=0x1b4b450
     0.....Used MemNode =0x1b4b450,Size=8,Next=(nil)
     1.....Used MemNode =0x1b4b5c0,Size=16,Next=0x1b4b570
     1.....Used MemNode =0x1b4b570,Size=16,Next=0x1b4b500
     1.....Used MemNode =0x1b4b500,Size=16,Next=0x1b4b610
     1.....Used MemNode =0x1b4b610,Size=16,Next=(nil)
     2.....Used MemNode =0x1b4b4d0,Size=24,Next=0x1b4b4a0
     2.....Used MemNode =0x1b4b4a0,Size=24,Next=(nil)
     3.....Used MemNode =0x1b4b640,Size=32,Next=(nil)
     4.....Used MemNode =0x1b4b530,Size=40,Next=(nil)
     0.....Free MemNode =0x1b4b5f0,Size=8,Next=(nil)
     1.....Free MemNode =0x1b4b500,Size=16,Next=0x1b4b610
     1.....Free MemNode =0x1b4b610,Size=16,Next=(nil)
*********************freemem********************************
     0.....Used MemNode =0x1b4b5a0,Size=8,Next=0x1b4b450
     0.....Used MemNode =0x1b4b450,Size=8,Next=(nil)
     1.....Used MemNode =0x1b4b5c0,Size=16,Next=0x1b4b570
     1.....Used MemNode =0x1b4b570,Size=16,Next=0x1b4b500
     1.....Used MemNode =0x1b4b500,Size=16,Next=0x1b4b610
     1.....Used MemNode =0x1b4b610,Size=16,Next=(nil)
     2.....Used MemNode =0x1b4b4d0,Size=24,Next=0x1b4b4a0
     2.....Used MemNode =0x1b4b4a0,Size=24,Next=(nil)
     3.....Used MemNode =0x1b4b640,Size=32,Next=(nil)
     4.....Used MemNode =0x1b4b530,Size=40,Next=(nil)
     0.....Free MemNode =0x1b4b5f0,Size=8,Next=(nil)
     1.....Free MemNode =0x1b4b500,Size=16,Next=0x1b4b610
     1.....Free MemNode =0x1b4b610,Size=16,Next=(nil)
----------------------end--------------------
...free all blocks from pool 0x1b4b010

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,524评论 5 460
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,869评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,813评论 0 320
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,210评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,085评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,117评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,533评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,219评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,487评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,582评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,362评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,218评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,589评论 3 299
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,899评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,176评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,503评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,707评论 2 335

推荐阅读更多精彩内容