头文件 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
常用内存池的实现 头文件 mem.h
最新推荐文章于 2025-03-02 09:05:11 发布