內存池的實現

基本的架構設計:

這里寫圖片描述

/*************************************************************************
        > 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閱讀 228,835評論 6 534
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,676評論 3 419
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,730評論 0 380
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,118評論 1 314
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,873評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,266評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,330評論 3 443
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,482評論 0 289
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,036評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,846評論 3 356
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,025評論 1 371
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,575評論 5 362
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,279評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,684評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,953評論 1 289
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,751評論 3 394
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,016評論 2 375

推薦閱讀更多精彩內容