📄 memory.c
字号:
/*
miniTOS V0.1.4 1998-2004 (c) 林良水 (Lin LS)
miniTOS是一个开放源码的软件,授权LGPL,但开发人员不保证本软件的可靠性,
以及对您的损失负任何责任。
www.minitos.com
本文实现动态内存管理。
create by Lin LS ,2003.12
Bug report: mail to (林良水) testmyself@163.net
*/
//#define VC_DEBUG
#include <stdio.h>
#define MIN_POOL_SIZE 1024
#define MM_FREE 0
#define MM_NOFREE 1
typedef struct
{
void *pMemoryPoolStartAddress;
unsigned int MemoryPoolSize;
}MEMORY_POOL;
struct __MEMORY_LINK
{
struct __MEMORY_LINK * prev;
struct __MEMORY_LINK * next;
int status; //0--free 1--used
unsigned int size;
int ValidFlag; //alway 0x55aa55aa
MEMORY_POOL * pMemoryPool;
};
typedef struct __MEMORY_LINK MEMORY_LINK;
//可重入
MEMORY_POOL * CreatePool(MEMORY_POOL * pMMPool,void * StartAddress,int size)
{
MEMORY_LINK *pMMLink;
if( (size<MIN_POOL_SIZE)||(StartAddress==NULL) )
{
pMMPool=NULL;
return NULL;
}
size=size/(sizeof(int)) * sizeof(int);
pMMPool->pMemoryPoolStartAddress=StartAddress;
pMMPool->MemoryPoolSize=size;
pMMLink=(MEMORY_LINK *)StartAddress;
pMMLink->prev=NULL;
pMMLink->next=NULL;
pMMLink->status=MM_FREE; //0--free 1--used
pMMLink->size=pMMPool->MemoryPoolSize-sizeof(MEMORY_LINK);
pMMLink->ValidFlag=0x55aa55aa;
pMMLink->pMemoryPool=pMMPool;
return pMMPool;
}
//不可重入
void * AllocMemory(MEMORY_POOL * pMMPool,unsigned int size)
{
unsigned int tmp;
MEMORY_LINK *pMMLink,*pMMLinkSplit;
size=(size+3)/4 * 4;
pMMLink=(MEMORY_LINK *)pMMPool->pMemoryPoolStartAddress;
do
{
if(pMMLink->status==MM_FREE)
{
if( ( pMMLink->size >= size )&&
( pMMLink->size <= size+ sizeof(MEMORY_LINK) ) )
{
//空间足够,并且不需要分割
pMMLink->status=MM_NOFREE;
pMMLink->ValidFlag=0x55aa55aa;
//break;
tmp=(unsigned int)((char *)pMMLink)+sizeof(MEMORY_LINK);
return (char *)tmp;
//return (int)pMMLink+sizeof(MEMORY_LINK);
}else
if( pMMLink->size > size+ sizeof(MEMORY_LINK) )
{
//空间足够,并且需要分割
pMMLinkSplit=(MEMORY_LINK *)(pMMLink+size+sizeof(MEMORY_LINK));
pMMLinkSplit->next=pMMLink->next;
pMMLinkSplit->prev=pMMLink;
pMMLink->next=pMMLinkSplit;
pMMLink->size=size;
pMMLink->status=MM_NOFREE;
pMMLinkSplit->size = pMMLink->size-size - sizeof(MEMORY_LINK);
pMMLinkSplit->status=MM_FREE;
pMMLinkSplit->ValidFlag=0x55aa55aa;
pMMLinkSplit->pMemoryPool=pMMPool;
//break;
tmp=(unsigned int)((char *)pMMLink)+sizeof(MEMORY_LINK);
return (char *)tmp;
}
}
pMMLink=pMMLink->next;
}while(pMMLink!=NULL);
return NULL;
}
//不可重入
int FreeMemory(void *pMM)
{
MEMORY_LINK *pMMLink;
//要释放的空间
pMMLink=( MEMORY_LINK *)( (int)pMM-sizeof(MEMORY_LINK) );
//MM valid?
if( (pMM==NULL)||(pMMLink==NULL)||(pMMLink->pMemoryPool==NULL)
||(pMMLink->status!=MM_NOFREE)|| (pMMLink->ValidFlag!=0x55aa55aa) )
{
return -1;
}
//release this Memory
pMMLink->status=MM_FREE;
//如果不是最后的链表,要判断是否下一个空间为空
//若下一个空间为空,合并他们
if( pMMLink->next!=NULL )
{
//Is the next MM Link free?
if(pMMLink->next->status==MM_FREE)
{
//yes,merge them.
// clear next link valid flag.
pMMLink->next->ValidFlag=0;
//recalc size
pMMLink->size+=pMMLink->next->size+sizeof(MEMORY_LINK);
//relocate next ptr.
pMMLink->next=pMMLink->next->next;
//设置下一个prev指针
if(pMMLink->next==NULL)
{
//合并后是最后一个
// g_pPrevHead=pMMLink;
}else
{
//合并后不是最后一个
pMMLink->next->prev=pMMLink;
}
}
}
//如果不是第一的链表,要判断是否上一个空间为空
//若上一个空间为空,合并他们
if( pMMLink->prev!=NULL )
{
//Is the prev MM Link free?
if(pMMLink->prev->status==MM_FREE)
{
//yes,merge them.
// clear this link valid flag.
pMMLink->ValidFlag=0;
//recalc prev MM size
pMMLink->prev->size+=pMMLink->size+sizeof(MEMORY_LINK);
//relocate next ptr.
pMMLink->prev->next=pMMLink->next;
//设置下一个prev指针
if(pMMLink->prev->next==NULL)
{
//合并后是最后一个
// g_pPrevHead=pMMLink;
}else
{
//合并后不是最后一个,set next Link's Prev pointer.
pMMLink->next->prev=pMMLink->prev;
}
}
}
return 0;
}
#ifdef VC_DEBUG
#define TEST_POOL_SIZE 100*1024
char PoolBuf[TEST_POOL_SIZE];
char *pBuf;
void main(void)
{
MEMORY_POOL mm_pool,*pMMPool;
printf("sizeof MM_POOL=%d\n",sizeof(MEMORY_POOL));
printf("sizeof MM_LINK=%d\n",sizeof(MEMORY_LINK));
pMMPool=CreatePool(&mm_pool,PoolBuf,TEST_POOL_SIZE);
pBuf=AllocMemory(pMMPool,TEST_POOL_SIZE-sizeof(MEMORY_LINK));
if(pBuf==NULL)
{
printf("alloc memory fail\n");
}else
{
printf("alloc memory success\n");
}
memset(pBuf,0x44,TEST_POOL_SIZE-sizeof(MEMORY_LINK));
if(FreeMemory(pBuf)<0)
{
printf("free memory fail\n");
}else
{
printf("free memory success\n");
}
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -