www.pudn.com > HEC-linux.zip > mem.c


#include 
 
#define U1 unsigned char 
#define U8 __int64 
 
#define TRUE		1 
#define FALSE		0 
 
#define FREE		0 
#define RESERVED	1 
char *statStr[] = {"FREE","RESERVED"}; 
 
/* Memory block header = 17 bytes = 8 previous + 8 next + status */ 
 
#define SIZE_HEADER	17 
 
#define prev(i)		*((U8 *)&memory[i]) 
#define next(i)		*((U8 *)&memory[i+8]) 
#define status(i)	memory[i+16] 
#define size(i)		next(i)-i-SIZE_HEADER 
 
/* if going to split free block, need at least 8 bytes in new free part */ 
 
#define MIN_FREE_BYTES   8 
 
U1 memory[1024]; 
U8 first;	/*stores address of first byte of heap*/ 
U8 last;	/*store address of last byte of heap + 1*/ 
 
void heapInit() 
{ 
	first=5; 
	last=1024; 
	 
	prev(first)=0; 
	next(first)=0; 
	status(first)=FREE; 
 
	return; 
 
}/*end heapInit*/ 
 
int currentNodeAlloc(U8 i,U8 nbytes) 
{ 
	U8 size; 
 
	/*handle case of current block being the last*/ 
 
	if(next(i)==0){ size = last-i-SIZE_HEADER; } 
	else{ size = size(i); } 
 
	/*either split current block, use entire current block, or fail*/ 
 
	if(size >= nbytes + SIZE_HEADER + MIN_FREE_BYTES) 
	{ 
		U8 old_next; 
		U8 old_block; 
		U8 new_block; 
 
		old_next = next(i); 
		old_block = i; 
 
		/*fix up original block*/ 
 
		next(i)=i+SIZE_HEADER+nbytes;	 
		new_block = next(i); 
		status(i)=RESERVED; 
 
		/*set up new free block*/ 
 
		i = next(i);					 
		next(i)=old_next; 
		prev(i)=old_block; 
		status(i)=FREE; 
 
		/*right nieghbor must point to new free block*/ 
 
		if(next(i)!=0)			 
		{ 
			i = next(i); 
			prev(i)=new_block; 
		} 
		 
		return(TRUE); 
	} 
	else if(size >= nbytes) 
	{ 
		status(i)=RESERVED; 
		return(TRUE); 
	} 
 
	return(FALSE); 
 
}/*end currentNodeAlloc*/ 
 
U8 alloc(U8 nbytes) 
{ 
	int ret; 
	U8 i; 
 
	i=first; 
 
	if(status(i)==FREE) 
	{ 
		ret = currentNodeAlloc(i,nbytes); 
		if(ret==TRUE) 
		{ 
			return(i+SIZE_HEADER); 
		} 
	} 
 
	while(next(i)!=0) 
	{ 
		i=next(i); 
		if(status(i)==FREE) 
		{ 
			ret = currentNodeAlloc(i,nbytes); 
			if(ret==TRUE) 
			{ 
				return(i+SIZE_HEADER); 
			} 
		} 
	} 
 
	return(0); 
 
}/*end alloc*/ 
 
/*Note: disaster will strike if fed wrong address*/ 
 
void deAlloc(U8 address) 
{ 
	U8 block; 
	U8 lblock; 
	U8 rblock; 
 
	block = address-SIZE_HEADER; 
	lblock = prev(block); 
	rblock = next(block); 
 
	/* 
	4 cases: FFF->F, FFR->FR, RFF->RF, RFR  
	always want to merge free blocks  
	*/ 
 
	if((lblock!=0)&&(rblock!=0)&&(status(lblock)==FREE)&&(status(rblock)==FREE)) 
	{ 
		next(lblock)=next(rblock); 
		status(lblock)=FREE; 
		if(next(rblock)!=0){ prev(next(rblock))=lblock; } 
	} 
	else if((lblock!=0)&&(status(lblock)==FREE)) 
	{ 
		next(lblock)=next(block); 
		status(lblock)=FREE; 
		if(next(block)!=0){ prev(next(block))=lblock; } 
	} 
	else if((rblock!=0)&&(status(rblock)==FREE)) 
	{ 
		next(block)=next(rblock); 
		status(block)=FREE; 
		if(next(rblock)!=0){ prev(next(rblock))=block; } 
	} 
	else{ status(block)=FREE; } 
 
	return; 
 
}/*end deAlloc*/ 
 
void printMemory() 
{ 
	U8 i; 
	i=first; 
	printf("[%I64u,%I64u,%I64u,%s]\n",prev(i),i,next(i),statStr[status(i)]); 
	while(next(i)!=0) 
	{ 
		i=next(i); 
		printf("[%I64u,%I64u,%I64u,%s]\n",prev(i),i,next(i),statStr[status(i)]); 
	} 
	return; 
 
}/*end printMemory*/ 
 
void main() 
{ 
	U8 address[10]; 
	heapInit(); 
 
	printf("Allocating----------------\n"); 
	address[0]=alloc(10); printf("\taddress= %I64u\n",address[0]); 
	address[1]=alloc(20); printf("\taddress= %I64u\n",address[1]); 
	address[2]=alloc(15); printf("\taddress= %I64u\n",address[2]); 
	address[3]=alloc(40); printf("\taddress= %I64u\n",address[3]); 
	address[4]=alloc(5); printf("\taddress= %I64u\n",address[4]); 
	address[5]=alloc(1); printf("\taddress= %I64u\n",address[5]); 
	address[6]=alloc(2); printf("\taddress= %I64u\n",address[6]); 
	address[7]=alloc(200); printf("\taddress= %I64u\n",address[7]); 
	address[8]=alloc(1); printf("\taddress= %I64u\n",address[8]); 
	printf("Dump map------------------\n"); 
	printMemory(); 
	printf("\nDeallocating address[8]+++\n");deAlloc(address[8]);printMemory(); 
	printf("\nDeallocating address[7]+++\n");deAlloc(address[7]);printMemory(); 
	printf("\nDeallocating address[1]+++\n");deAlloc(address[1]);printMemory(); 
	printf("\nDeallocating address[3]+++\n");deAlloc(address[3]);printMemory(); 
	printf("\nDeallocating address[5]+++\n");deAlloc(address[5]);printMemory(); 
	printf("\nDeallocating address[4]+++\n");deAlloc(address[4]);printMemory(); 
	printf("\nDeallocating address[0]+++\n");deAlloc(address[0]);printMemory(); 
	printf("\nDeallocating address[2]+++\n");deAlloc(address[2]);printMemory(); 
	printf("\nDeallocating address[6]+++\n");deAlloc(address[6]);printMemory(); 
	return; 
 
}/*end main*/