⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 memory.c

📁 minitos是一个实时的嵌入式操作系统
💻 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 + -