localmemmgr.h

来自「君正早期ucos系统(只有早期的才不没有打包成库),MPLAYER,文件系统,图」· C头文件 代码 · 共 329 行

H
329
字号
/********************** BEGIN LICENSE BLOCK ************************************ * * JZ4740  mobile_tv  Project  V1.0.0 * INGENIC CONFIDENTIAL--NOT FOR DISTRIBUTION IN SOURCE CODE FORM * Copyright (c) Ingenic Semiconductor Co. Ltd 2005. All rights reserved. *  * This file, and the files included with this file, is distributed and made  * available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER  * EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS ALL SUCH WARRANTIES,  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS  * FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.  *  * http://www.ingenic.cn  * ********************** END LICENSE BLOCK ************************************** * *  Author: <dsqiu@ingenic.cn> <hlyu@ingenic.cn> * *  Create:   2008-03-04, by dsqiu *  Maintain: 2008-06-23, by hlyu  *             ******************************************************************************* */#define TRUE 1#define FALSE 0#define FREE		0#define RESERVED	1/* Memory block header = 9 bytes = 4 previous + 4 next + status */#define SIZE_HEADER	32#define local_prev(i)		(*((unsigned int *) (i)))#define local_next(i)		(*((unsigned int *) (i+4)))#define local_status(i)	(*((unsigned char *) (i+8)))#define local_size(i)		(local_next(i)-i-SIZE_HEADER)#define local_setalign(i,y)  (*((unsigned char *)(i-1))) = y#define local_getalign(i)  (*((unsigned char *)(i-1)))/* if going to split free block, need at least 4 bytes in new free part */#define MIN_FREE_BYTES   32//static unsigned char memory[MEM_LENGHT] __attribute__ ((aligned (MIN_FREE_BYTES)));#define local_first(x) (*(unsigned int *)x)      /*stores address of first byte of heap*/#define local_last(x) (*(unsigned int *)(x+4)) /*store address of last byte of heap + 1*/  /*   Local Heap Initiale    note: heap is 4 byte aligned*/   extern void GM_Dealloc(void* addr);extern int Module_EnterExt( void );extern int Module_ExitExt( void ); static inline int Local_HeapInit(unsigned int heap,unsigned int size){	if((heap % 4) != 0)		return 0;	if(size < 16)		return 0;	if(MIN_FREE_BYTES > 8)		local_first(heap) = (unsigned int)(heap + MIN_FREE_BYTES);	else				local_first(heap) = (unsigned int)(heap + 8);	local_last(heap) = (unsigned int)heap + size;		local_prev(local_first(heap))=0;	local_next(local_first(heap))=0;	local_status(local_first(heap))=FREE;	return 1;}/*end heapInit*/static inline int currentNodeAlloc(unsigned int heap,unsigned int i,unsigned int nbytes){	unsigned int free_size;   	/*handle case of current block being the last*/    	if(local_next(i) == 0){		free_size = local_last(heap) - i - SIZE_HEADER;	}else{	    free_size = local_size(i);	}   	/*either split current block, use entire current block, or fail*/    	if(free_size >= nbytes + SIZE_HEADER + MIN_FREE_BYTES)	{		unsigned int old_next;		unsigned int old_block;		unsigned int new_block;		old_next = local_next(i);		old_block = i;		/*fix up original block*/		local_next(i) = i+SIZE_HEADER+nbytes;			new_block = local_next(i);		local_status(i)=RESERVED;		/*set up new free block*/		i = local_next(i);							local_next(i)=old_next;		local_prev(i)=old_block;		local_status(i)=FREE;		/*right nieghbor must point to new free block*/		if(local_next(i)!=0)					{			i = local_next(i);			local_prev(i)=new_block;		}				return(TRUE);	}	else if(free_size >= nbytes)	{		local_status(i)=RESERVED;		return(TRUE);	}	return(FALSE);}/*end currentNodeAlloc*/static inline unsigned int my_alloc(unsigned int heap,unsigned int nbytes){	int ret;	unsigned int i; //printf("alloc %x\n",nbytes);	nbytes = ((nbytes  + MIN_FREE_BYTES - 1)/ MIN_FREE_BYTES )  * MIN_FREE_BYTES;	i=local_first(heap);	if(local_status(i)==FREE)	{		ret = currentNodeAlloc(heap,i,nbytes);		if(ret==TRUE)		{			//F("alloc mem = 0x%x,size = %d\n",i+SIZE_HEADER,nbytes); 			return(i+SIZE_HEADER);		}	}	while(local_next(i)!=0)	{		i=local_next(i);		if(local_status(i)==FREE)		{			ret = currentNodeAlloc(heap,i,nbytes);			if(ret==TRUE)			{				//F("alloc mem = 0x%x,size = %d\n",i+SIZE_HEADER,nbytes); 				return(i+SIZE_HEADER);			}		}	}	printf("mem too small!\n");	return 0;}static inline unsigned int Local_Alloc(unsigned int heap,unsigned int nbytes){		unsigned int i = my_alloc(heap,nbytes);	if(i != 0)		local_setalign(i,0);    	return i;}/*end Local_Alloc*/static inline void my_free(unsigned int heap,unsigned int address){	unsigned int block;	unsigned int lblock;	unsigned int rblock;  	block = address-SIZE_HEADER;	lblock = local_prev(block);	rblock = local_next(block);	/*	4 cases: FFF->F, FFR->FR, RFF->RF, RFR 	always want to merge free blocks 	*/	if((lblock!=0)&&(rblock!=0)&&(local_status(lblock)==FREE)&&(local_status(rblock)==FREE))	{		local_next(lblock)=local_next(rblock);		local_status(lblock)=FREE;		if(local_next(rblock)!=0){ local_prev(local_next(rblock))=lblock; }	}	else if((lblock!=0)&&(local_status(lblock)==FREE))	{		local_next(lblock)=local_next(block);		local_status(lblock)=FREE;		if(local_next(block)!=0){ local_prev(local_next(block))=lblock; }	}	else if((rblock!=0)&&(local_status(rblock)==FREE))	{		local_next(block)=local_next(rblock);		local_status(block)=FREE;		if(local_next(rblock)!=0){ local_prev(local_next(rblock))=block; }	}	else{ local_status(block)=FREE; }}/*Note: disaster will strike if fed wrong address*/static inline void Local_Dealloc(unsigned int heap,unsigned int address){			/*	4 cases: FFF->F, FFR->FR, RFF->RF, RFR 	always want to merge free blocks 	*/  address -= local_getalign(address);	my_free(heap,address);	return;}/*end Local_Dealloc*/static inline unsigned int Local_Realloc(unsigned int heap,unsigned int address,unsigned int nbytes){	unsigned int rr,addr,oldsize;	unsigned int block,rblock,rrblock;	unsigned int bsize,align;	unsigned int len;  	oldsize = nbytes;		nbytes = ((nbytes  + MIN_FREE_BYTES - 1)/ MIN_FREE_BYTES )  * MIN_FREE_BYTES; 	rr = address;	if (nbytes == 0) {			Local_Dealloc(heap,rr);			return 0;  }	if (address == 0)	{		    addr = my_alloc(heap,nbytes);	    if(addr != 0)	    	local_setalign(addr,0);      return addr;	}	align = local_getalign(address);	len = (nbytes + align  + MIN_FREE_BYTES - 1) &(~(MIN_FREE_BYTES - 1));	address -= local_getalign(address);	address -= SIZE_HEADER;    	bsize = local_size(address);	//printf("align = %d,address = %x  %d %d\n",align,address,nbytes,bsize);	if(nbytes <= bsize-align)	{		return rr;	}			rblock = local_next(address);	if((rblock != 0) &&(local_status(rblock) == FREE) )	{		//printf("rblock = %x %d %d",rblock,local_status(rblock),size(rblock));		bsize += local_size(rblock);		if(bsize >= nbytes + align)		{			rrblock = local_next(rblock);			local_next(address) = address + len + SIZE_HEADER;			block = local_next(address);			local_prev(block) = address;			local_next(block) = rrblock; 			local_status(block) = FREE;				return rr;	  }	}   	addr = my_alloc(heap,len);	//printf("realloc %x %x %x %x\n",addr,rr,nbytes,bsize);		if(addr == 0)		return 0;  addr += align;			local_setalign(addr,align);		memcpy((void *)addr,(void *)rr,bsize);	Local_Dealloc(heap,rr);	  return addr;	}static inline unsigned int Local_Calloc(unsigned int heap,unsigned int size,unsigned int n){	unsigned int rr;	rr = Local_Alloc(heap,size * n);	if(rr != 0)		memset((void *)rr,0,size * n);	return rr;}static inline unsigned int Local_alignAlloc(unsigned int heap,unsigned int align,unsigned int size){	unsigned int i2 = 0, i = my_alloc(heap,size + align);	if(i != 0)	{		i2 = (i +  align - 1) & ~(align - 1);		local_setalign(i2, i2 - i);	}		return i2;}/*end alloc*/

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?