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 + -
显示快捷键?