常用内存池的实现 头文件 mem.h

本文介绍了一个实时内存分配接口的设计方案,包括MemBucket和MemPool两个核心组件。MemBucket为单个内存分配接口,可针对特定需求如内存池、消息队列等进行封装;MemPool为通用内存分配接口,能应对不同大小的内存需求。文章还提供了节点池(Node Pool)的实现案例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

头文件 mem.h

/*
 * Provide a realtime memory-allocating interface:
 *
 * MemBucket: individual memory-allocating interface that can be wrapped to satisfy 
 *           some special needs such as memory pool, message queue, etc.
 * MemPool: universal memory-allocating interface that can meet different kinds of
 *         memory size requirements.
 *
 */
#ifndef _MEM_H_
#define _MEM_H_


#include "include_pub.h"


typedef struct _memBlk
{
    struct _memBlk *m_prev;         /*ptr to previous memBlock*/
    ULONG          ulBlkSize;      /*size of this memory block*/
    UCHAR           data[0];        /*ptr to real data*/
} MEM_BLK;


typedef struct _memBucket
{
    MEM_BLK *m_memHd;               /*head of memory list*/
    MEM_BLK *m_curBlk;              /*ptr to current block of the bucket*/    
    ULONG   ulTotal;                /*total num of blocks in the bucket*/
    ULONG   ulFree;                 /*free num of blocks in the bucket*/
} MEM_BUCKET;


/* @pbucket : ptr to MEM_BUCKET(memory bucket)
 * @tpblk   : ptr to MEM_BLK used as temporary storage
 */
#define BUCKET_ALLOC(pbucket, tpblk) (((pbucket)->m_curBlk != NULL) ? \
(\
tpblk = (pbucket)->m_curBlk,\
((pbucket)->m_curBlk = (pbucket)->m_curBlk->m_prev), (pbucket)->ulFree -= 1, tpblk->data\
) : NULL)


/* @pbucket : ptr to MEM_BUCKET(memory bucket)
 * @pdata   : ptr to data member of struct _memBlk
 */
#define BUCKET_FREE(pbucket, pdata) do {\
MEM_BLK *_mp_ = mem_blk_entry(pdata, MEM_BLK, data);\
_mp_->m_prev = (pbucket)->m_curBlk;\
(pbucket)->m_curBlk = _mp_;\
(pbucket)->ulFree += 1;\
}while(0)


/* @pbucket : ptr to MEM_BUCKET(memory bucket)
 * @x :       size of memory block (32 /64 /.../256....)
 * @n :       number of malloced memory blocks
 */
#define BUCKET_INIT(pbucket, x, n) do { ULONG _i_ = 0;\
    char *_q_ = (char *)malloc((sizeof(MEM_BLK) + (x))*(n));\
    assert(_q_ != NULL);\
    (pbucket)->m_memHd = (MEM_BLK *)_q_;\
    memset((pbucket)->m_memHd, 0, (sizeof(MEM_BLK) + (x)));\
(pbucket)->m_memHd->m_prev = NULL;\
(pbucket)->m_memHd->ulBlkSize = (x);\
(pbucket)->m_curBlk = (pbucket)->m_memHd;\
                                         \
MEM_BLK *_p_ = NULL;\
for (_i_ = 1; _i_ < (n); _i_++) {\
        _q_ += (sizeof(MEM_BLK) + (x));\
    memset(_q_, 0, sizeof(MEM_BLK) + (x));\
    _p_ = (MEM_BLK *)_q_;\
    _p_->m_prev = (pbucket)->m_curBlk;\
    _p_->ulBlkSize = (x);\
    (pbucket)->m_curBlk = _p_;\
    } \
    (pbucket)->ulTotal = (n);\
    (pbucket)->ulFree = (n);\
}while(0)


/* @pbucket : ptr to MEM_BUCKET(memory bucket)
 */
#define BUCKET_CLEANUP(pbucket) do {\
    if((pbucket) != NULL) {\
        if((pbucket)->m_memHd != NULL) {\
       free((char *)((pbucket)->m_memHd));\
       (pbucket)->m_memHd = NULL;\
       (pbucket)->ulTotal = 0;\
       (pbucket)->ulFree = 0;\
        }\
    }\
}while (0)


/**
 * mem_blk_entry - get the struct for this entry
 * @ptr: the data pointer.
 * @type: the type of the struct this is embedded in.
 * @member: the name of the data within the struct.
 */
#define mem_blk_entry(ptr, type, member) \
((type *)((char *)(ptr)-(unsigned long)(&((type *)0)->member)))


/***************************Begin of Mem Pool Section********************************/
#define M_MEM_BLK32_SIZE    0x800   /*2048*/
#define M_MEM_BLK64_SIZE    0x800   /*2048*/
#define M_MEM_BLK96_SIZE    0x800   /*2048*/
#define M_MEM_BLK128_SIZE    0x800   /*2048*/
#define M_MEM_BLK160_SIZE    0x800   /*2048*/
#define M_MEM_BLK192_SIZE    0x800   /*2048*/
#define M_MEM_BLK224_SIZE    0x800   /*2048*/
#define M_MEM_BLK256_SIZE    0x800   /*2048*/




/*common use*/
typedef struct _memPool
{
    SEM_S      sem;                 /*mutex*/
    MEM_BUCKET m_bucket32;          /*32 bytes*/
    MEM_BUCKET m_bucket64;
    MEM_BUCKET m_bucket96;
MEM_BUCKET m_bucket128;
    MEM_BUCKET m_bucket160;
MEM_BUCKET m_bucket192;
    MEM_BUCKET m_bucket224;
    MEM_BUCKET m_bucket256;         /*256 bytes*/

    ULONG      ulTotalSize;         /*size of bytes malloced*/
} MEM_POOL;


/***************************End of Mem Pool Section********************************/


/***************************Begin of Node Pool Section********************************/
/*Usage(How to implement special use memory pool):
 *  1.define one variable of NODE_POOL type.
 *  2.Encapsulate NODE_POOL_INIT with defined pool variable, node type and number of nodes.
 *  3.Encapsulate NODE_POOL_CLEANUP with defined pool variable.
 *  4.Implement myMalloc and myFree by encapsulating  BUCKET_ALLOC and BUCKET_FREE respectively.
 *  5.Examples: make reference to sdb.c
 */
typedef struct _Node_Pool
{
    MEM_BUCKET  stBucket;
    SEM_S       mutex;
    ULONG       ulTotalSize;         /*size of bytes malloced*/
} NODE_POOL;


#define NODE_POOL_INIT(pool, type, n)   do {\
    memset((pool), 0, sizeof(NODE_POOL));\
    SEM_INIT(&(pool)->mutex);\
    SEM_LOCK(&(pool)->mutex);\
    BUCKET_INIT(&(pool)->stBucket, sizeof(type), (n));\
    (pool)->ulTotalSize += ((n))*(sizeof(type));\
    SEM_UNLOCK(&(pool)->mutex);\
}while(0)


#define NODE_POOL_CLEANUP(pool) {\
    BUCKET_CLEANUP(&(pool)->stBucket);\
    (pool)->ulTotalSize = 0;\
}


static inline UCHAR *node_pool_alloc(NODE_POOL *pool)
{
    MEM_BLK *blk = NULL;


    SEM_LOCK(&(pool->mutex));
    UCHAR *buff = BUCKET_ALLOC(&(pool->stBucket), blk);
    SEM_UNLOCK(&(pool->mutex));


    return buff;
}


static inline void node_pool_free(NODE_POOL *pool, UCHAR *pdata)
{
    SEM_LOCK(&(pool->mutex));
    BUCKET_FREE(&(pool->stBucket),pdata);
    SEM_UNLOCK(&(pool->mutex));


    return;
}
/***************************End of Node Pool Section********************************/


/****************************PROTOTYPES****************************/
ULONG MemPoolInit();
void MemPoolCleanup();
void *MemAlloc(ULONG ulSize);
void MemFree(void *p);


#endif


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值