我写了一个内存管理函数请各位指点

970361 2002-07-27 05:31:42
目的是为了统一管理动态内存申请
算法设计如下:
1 申请一个很大的内存块
2 每次用户申请就从其中划出一小块固定大小(32,64,128,256字节)内存出来
3 当使用完毕是回收这一小块以备下次使用
4 当所有的小块都回收完毕则释放一整块

请帮忙看看算法或者设计思想是否有不妥的地方

原代码:
头文件

#ifndef APMM1_H_
#define APMM1_H_

#define MM_TEST // for test mm model

#define MEMSET(a,b,c) memset(a,b,c)

typedef unsigned short INT16U;
typedef unsigned long INT32U;

/* define struct of mm info
*/
typedef struct _mm_slab
{
char *pStart ; //This slab start adress
struct _mm_slab *next; //pionter to next

INT16U nPiece ; //how many piece the slab include
INT16U nPieceSize; //size of piece
INT32U lUserInfo; //which piece are used (record by bit,0 can not use, 1 can using)
}sMM_slab;

typedef enum {
EMM_SIZE32 = 0, //分配 32 字节 内存单元
EMM_SIZE64, //分配 64 字节 内存单元
EMM_SIZE128, //分配 128 字节 内存单元
EMM_SIZE256 //分配 256 字节 内存单元
}eMm_size ;

int mm_init(void) ;
char *AP_Malloc(eMm_size etype) ;
void AP_Free(char *p,eMm_size etype) ;

#ifdef MM_TEST
int mm_test(void);
#endif

#endif
...全文
63 点赞 收藏 3
写回复
3 条回复
切换为时间正序
请发表友善的回复…
发表回复
970361 2002-07-27
/*************************************************
memory_malloc() : allocate mem ,this memory offer
to user
parameter : psMMslab mem info
return value : mem start address
*************************************************/
static char* memory_malloc(sMM_slab *psMMslab)
{
assert(psMMslab) ;

psMMslab->pStart = (char*)malloc(psMMslab->nPiece * psMMslab->nPieceSize) ;
if(!psMMslab->pStart)
{
return NULL ;
}
MEMSET(psMMslab->pStart,0,(psMMslab->nPiece * psMMslab->nPieceSize) );
return psMMslab->pStart ;
}
/*************************************************
slab_list_insert() insert a slab to list
parameter :
etype type of slab
psMMslab address of slab you want insert
*************************************************/
static int slab_list_insert(sMM_slab *psMMslab,eMm_size etype)
{
assert(psMMslab) ;
if(!_lpMm_slab_address[etype]) //list is null
{
_lpMm_slab_address[etype] = psMMslab ;
psMMslab->next = NULL ;
}
else
{
psMMslab->next = _lpMm_slab_address[etype] ;
_lpMm_slab_address[etype] = psMMslab ;
}
return 0;
}
/*************************************************
slab_list_delete() delete a slab to list
parameter :
etype type of slab
psMMslab address of slab you want delete
*************************************************/
static int slab_list_delete(sMM_slab *psMMslab,eMm_size etype)
{
int nRev ;
sMM_slab *psmm ,*psnext;

psmm = NULL ;
nRev = 0 ;

psmm = _lpMm_slab_address[etype] ;

if(psMMslab == _lpMm_slab_address[etype] )
{
_lpMm_slab_address[etype] = (sMM_slab*)psmm->next ;
nRev = 1 ;
}
else
{
while(psmm)
{
psnext = (sMM_slab*)psmm->next ;
if(psnext == psMMslab)
{
psmm->next = psnext->next ;
nRev = 1;
break ;
}
psmm = psnext;
}
}
if(1==nRev)
{
slab_free(psMMslab) ; //slab_free function can't complete!!!!!
}
return nRev ;
}
/*************************************
slab_free() free the memory of psMMslab
*************************************/
static int slab_free(sMM_slab *psMMslab)
{
assert(psMMslab);
if(psMMslab)
{
if(psMMslab->pStart)
{
free(psMMslab->pStart) ;
}
free(psMMslab) ;
}
return 0 ;
}

/*********************************************
set_mm_useinfo() set the map bit of memory block
is used or unused

patameter : psMMslab memory info
nBit map bit index
return value : on error return -1
else return 0
*********************************************/
static int set_mm_useinfo(sMM_slab *psMMslab,INT16U nBit )
{
assert(psMMslab) ;
assert(nBit <MM_MAX_PIECE );

if(psMMslab)
{
if(nBit < MM_MAX_PIECE)
{
psMMslab->lUserInfo ^= ((INT32U)0x00000001 << nBit ) & 0xffffffff ;
return 0 ;
}
}
return -1 ;
}


/***************************************************
find_block() find a piece of empty memory block
return index of the memory block in slab
if error return -1
***************************************************/
static int find_block(sMM_slab *psMMslab)
{
int nResult ;
int i ;
INT32U lMapInfo ;

nResult = -1 ;
lMapInfo ^= lMapInfo ;
assert(psMMslab) ;

lMapInfo = psMMslab->lUserInfo ;
for(i=0; i<MM_MAX_PIECE; i++ )
{
if( (lMapInfo & (INT32U)0x00000001) ) // oh yes find a empyt block
{
nResult = i ;
break ;
}
else
{
lMapInfo = (lMapInfo >> 1)& 0xffffffff ;
}
}
return nResult ;
}

/****************************************
try_to_free_slab() if the psMMslab is
not be used then try to free it
****************************************/
static int try_to_free_slab(sMM_slab *psMMslab,eMm_size etype)
{
int nIsFree ;
INT32U lMapBit ;

lMapBit ^= lMapBit ;

if(MM_MAX_PIECE == psMMslab->nPiece )
{
lMapBit =~psMMslab->lUserInfo ;
}
else
{
lMapBit = psMMslab->lUserInfo ^ (((INT32U)0x00000001 << psMMslab->nPiece) -1) ;
}
if(!lMapBit)
{
slab_list_delete(psMMslab,etype) ;
}
return 0 ;
}

/*************
This is for test
*************/
#ifdef MM_TEST
int mm_test(void)
{
int i ;
char *pTest ;
char *p[MM_MAX_PIECE] ;
char *desc = "hello world!" ;
//clrscr() ;

for(i=0;i<MM_MAX_PIECE; i++)
{
p[i]=AP_Malloc(0) ;
}
for(i=0; i<MM_MAX_PIECE; i++)
{
if(p[i])
{
sprintf(p[i],"hello world %d",i) ;
}
}
for(i=0 ; i<MM_MAX_PIECE; i++)
{
if(p[i])
{
printf("Test %s add=%d\n",p[i],(INT32U)p[i]) ;
}
}
//getch();
for(i=0; i<MM_MAX_PIECE; i++)
{
AP_Free(p[i],0 );
}
printf("start free\n");
pTest = AP_Malloc(0) ;
if(pTest)
{
strcpy(pTest ,desc) ;
printf("after free %s address =%d \n",pTest, (INT32U)pTest) ;
}
return 0 ;
}
int main(void)
{
mm_init() ;
mm_test() ;
mm_destroy();
return 0;
}
#endif
回复
970361 2002-07-27
/******************************************
AP_Malloc(eMm_size etype) malloc memory for
user.
parameter : etype which type do you want
malloc
return value : pointer of memory address
pointer type is char*
******************************************/
char *AP_Malloc(eMm_size etype)
{
int nMapBit ;
char *pcResult ;
//INT16U pcResult ;
sMM_slab *psMMslab ;

psMMslab = NULL ;
pcResult = NULL ;
nMapBit = -1 ;

assert(etype < MM_TYEPS && etype >= 0) ;

psMMslab = _lpMm_slab_address[etype];

/*allocate memory first time */
do{
if(NULL == psMMslab )
{
psMMslab = slab_alloc( etype ) ;
if(NULL == psMMslab)
{
return NULL ; // not enough memory ;
}
slab_list_insert(psMMslab, etype) ;
}
nMapBit = find_block(psMMslab);
if((int)-1 == nMapBit )
{
psMMslab = (sMM_slab*)psMMslab->next ;
}
else
{
break ;
}
}while((int)-1 == nMapBit) ;

if((INT16U)nMapBit < psMMslab->nPiece )
{
pcResult = (psMMslab->pStart) + psMMslab->nPieceSize * (INT16U)nMapBit ;
set_mm_useinfo(psMMslab,(INT16U)nMapBit ) ;
}
return pcResult ;
}
/******************************************
AP_Free() reback the memory of p pointed
etype is type of p
******************************************/
void AP_Free(char *p,eMm_size etype)
{
INT16U nOffset ;
sMM_slab *psMMslab ;

psMMslab = NULL ;
nOffset = 0 ;

assert(etype < MM_TYEPS && etype >= 0) ;

psMMslab = _lpMm_slab_address[etype] ;

while(NULL != psMMslab)
{
/*oh yeah find the persion of pointer p
* and reback the map
* if the slab is empty try to free
*/
if( (p >= psMMslab->pStart)
&& (p < (psMMslab->pStart + psMMslab->nPiece * psMMslab->nPieceSize)) )
{
nOffset = ( (INT16U)p- (INT16U)psMMslab->pStart ) / psMMslab->nPieceSize ;
set_mm_useinfo(psMMslab, nOffset);
MEMSET(p,0,psMMslab->nPieceSize );
try_to_free_slab(psMMslab, etype) ;
break ;
}
/* oh not find p's persion
* and find next
*/
else
{
psMMslab = (sMM_slab*)psMMslab->next ;
}
} // end while
}


/********************************************
slab_alloc() allocate mem for struct of slab
and init it.
parameter : etype which type slab you
you want to .
return value: pointer to sMM_slab
********************************************/
static sMM_slab* slab_alloc(eMm_size etype)
{
sMM_slab *p ;

p=NULL ;
p=(sMM_slab*)malloc( sizeof(sMM_slab) ) ;
if(NULL == p )
return NULL ;

/*init value
*/
p->pStart =NULL ;
p->next = NULL ;
p->nPiece = (MM_MAX_PIECE >>(INT16U)etype) & 0xffff ;
p->nPieceSize = (MM_MINSIZE<<(INT16U)etype) & 0xffff ;

p->lUserInfo ^= p->lUserInfo ;

p->pStart = memory_malloc(p) ; //allocate memory

if(NULL == p->pStart)
{
free(p) ;
return NULL ;
}

/*RECORD which piece memory are empty!
* if block empty set the map bit is '1'
*/
if(p->nPiece < MM_MAX_PIECE )
{
p->lUserInfo ^= ((INT32U)0x00000001 << p->nPiece) -1 ;
}
else
{
p->lUserInfo = ~p->lUserInfo ; //set all bits of p->lUserInfo is '1'
}

return p ;
}
回复
970361 2002-07-27
/****************************************************

Project Name : memory manager

Modification: 2002-7-25
description: This memory manager
now I offer four type size memory
malloc :(32byte,64byte,128byte,256byte)
****************************************************/

#include "apmm1.h"
#include <stdlib.h>
#include <stdio.h>
#include <assert.h>

#define MM_TYEPS ((INT16U)4) //提供多少尺寸的中内存分配方案
#define MM_MINSIZE ((INT16U)32) //可申请内存块最小单位(字节)
#define MM_MAX_PIECE ((INT16U)32) //一个slab最多可分为多少片

static sMM_slab *_lpMm_slab_address[MM_TYEPS] ; //存放4个slab结构的首地址

static sMM_slab* slab_alloc(eMm_size etype) ;
static char* memory_malloc(sMM_slab *psMMslab);
static int slab_list_insert(sMM_slab *psMMslab,eMm_size etype) ;
static int slab_list_delete(sMM_slab *psMMslab,eMm_size etype) ;
static int set_mm_useinfo(sMM_slab *psMMslab,INT16U nBit );
static int slab_free(sMM_slab *psMMslab);
static int find_block(sMM_slab *psMMslab);
static int try_to_free_slab(sMM_slab *psMMslab,eMm_size etype);

/*********************************
mm_init() Init memory manager model ,
intial golbals pointers and
malloc enough memory.

parameter : void
return value : pointer of globals
memory area
*********************************/
int mm_init(void)
{
int i ;
//MEMSET(_lpMm_slab_address,0,sizeof(_lpMm_slab_address) );
for(i=0; i<MM_TYEPS; i++ )
{
_lpMm_slab_address[i] = NULL ;
}
return 0 ;
}

/******************************
mm_destroy() destroy memory
******************************/
//#ifdef PC_dos
void mm_destroy(void)
{
int i,j ;

for(i=0; i< MM_TYEPS; i++)
{
while(_lpMm_slab_address[i])
{
slab_list_delete(_lpMm_slab_address[i], i) ;
}
}
}
//#endif
回复
发动态
发帖子
数据结构与算法
创建于2007-08-27

3.2w+

社区成员

数据结构与算法相关内容讨论专区
申请成为版主
社区公告
暂无公告