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

📄 lmalloc.c

📁 基于东南大学开发的SEP3203的ARM7中的所有驱动
💻 C
字号:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
#include "systsk.h"
#include "lmalloc.h"
#include "xlmalloc.h"

#include "sysdebug.h"

extern void SendSysAlarm( char *str );

#if ENABLE_SYSMEM_DEBUG_OUT
//#pragma data_seg( "DebugShare" )
unsigned long MemUsed = 0L;		// longn_qi 2002/01/25 for monitor memory leak
unsigned long MemUsedPeak = 0L;	// longn_qi 2002/03/28 for evaluate memory use
//#pragma data_seg(  )
#endif

static unsigned long Memfail=0L;/* Count of allocation failures */
static unsigned long Allocs=0L;	/* Total allocations */
static unsigned long Frees=0L;	/* Total frees */
static unsigned long Invalid=0L;/* Total calls to SysLfree with garbage arg */
//static int Memwait;		/* Number of tasks waiting for memory */

/* The array is to record the number that 
 * the special sized memory block is used.
 * Sizes[0]  -----   memory block size: 2/0
 *           .....
 * Sizes[n]  -----   memory block size: 2/n 
* max block size is 2/19 = 128K */
static unsigned long Sizes[20]={ 0L, 0L, 0L, 0L, 0L,\
				 0L, 0L, 0L, 0L, 0L,\
				 0L, 0L, 0L, 0L, 0L,\
				 0L, 0L, 0L, 0L, 0L };

/* This debugging pattern MUST be exactly equal in size 
 * to the "header" union defined later */
static BYTE Debugpat[] = { 0xfe,0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef };

static HEADER *Base=NULL;			//第一个空头change
static HEADER *First=NULL;			//第一个有效头change
static HEADER *Allocp = NULL;		//表链头(=Base)

////BYTE	array_memory[Heapsize];
BYTE	*array_memory = 0x30500000;				////gfd modify 
//BYTE	*array_memory = 0x31000000;				////gfd modify 
/* Heap memory, ABLKSIZE units */
static unsigned long Availmem = BTOU(Heapsize)-2;		

#ifdef HOT_RESET_DEBUG_CODE_ENABLE
void SysLmallocInit(void)
{
	int i;
	
#if ENABLE_SYSMEM_DEBUG_OUT
	MemUsed = 0L;
	MemUsedPeak = 0L;
#endif
	
	Memfail = 0L;
	Allocs = 0L;
	Frees = 0L;
	Invalid = 0L;

	for(i=0; i<20; i++)
		Sizes[i] = 0L;
	
	Base = NULL;	
	First = NULL;	
	Allocp = NULL;

	Availmem = BTOU(Heapsize)-2;
}
#endif

static BYTE ilog2(DWORD size)
{
//	double temp1,temp2,result;
//	temp1 = log10(size);
//	temp2 = log10(2);
//	result = temp1 / temp2;
//	return ((unsigned)result);
	
	BYTE	i;
	DWORD	mask = 0x80000000;
	
	for( i = 0; i < 16; i++ )
	{
		if( size & mask )
			break;
		else
			mask = mask >> 1;
	}
	
	return ( 16 - i );
}


/* Allocate block of 'nb' bytes */
void *SysLmalloc( DWORD nb )
{
#if Memdebug
	int i;
#endif
	//int i_state;
	register HEADER  *p,  *q;
	register unsigned long nu;

	if(nb == 0)
		return NULL;

	Allocs++;

/* Pessia: 2002/4/4 
 * Use macro Memdebug while not variable */
#if Memdebug
	/* Record the size of this request */
	if((i = ilog2(nb)) >= 0)
		Sizes[i]++;
#endif

	// longn_qi 2002/01/25 for monitor memory leak
//	MemUsed += nb;
//	memdbgoutput( "mem allocate: %ld Bytes", nb );
//	memdbgoutput( "mem in use: %ld Bytes", MemUsed );

	/* Round up to full block, then add one for header */
	nu = BTOU(nb);

	//i_state = dirps();
	vDisableDispatch();
	 
	/* Initialize heap pointers if necessary */
	if((q = Allocp) == NULL){
		
		//创建一个空头。目的:当所有空间分配完时,Lfree函数需要有一个表头
		Base = (HEADER *)array_memory;
		Base->s.ptr = Allocp = q = Base;
		Base->s.size = 1;
		
		
		First = Base + 1;
		Base->s.ptr = First;
		First->s.ptr = Base;
		First->s.size = BTOU(Heapsize)-2;
		
		//attention!
	}
	/* Search heap list */
	for(p = q->s.ptr; ; q = p, p = p->s.ptr){
		if(p->s.size >= nu){
			/* This chunk is at least as large as we need */
			if(p->s.size <= nu + 1){
				/* This is either a perfect fit (size == nu)
				 * or the SysLfree chunk is just one unit larger.
				 * In either case, alloc the whole thing,
				 * because there's no point in keeping a SysLfree
				 * block only large enough to hold the header.
				 */
				q->s.ptr = p->s.ptr;
			} else {
				/* Carve out piece from end of entry */
				p->s.size -= nu;
				p += p->s.size;
				p->s.size = nu;
			}

			p->s.ptr = p;	/* for auditing */
			Availmem -= p->s.size;
			if( Availmem < 1280 )
			{
				SendSysAlarm( "系统内存不足10K!请关闭一些窗口!" );
			}
			p++;
			
#if ENABLE_SYSMEM_DEBUG_OUT
			// debug for memory test
			memset( p, 0xcc, nb );
#endif
			break;
		}
		/* We've searched all the way around the list without
		 * finding anything. Try to get more core from the system,
		 * unless we're in an interrupt handler
		 */
		
		if(p == Allocp){
			p = NULL;
			Memfail++;
			SendSysAlarm( "系统内存严重不足!" );
			break;
		}
	}

	// longn_qi 2002/01/25 for monitor memory leak
#if ENABLE_SYSMEM_DEBUG_OUT
	{
		ID tid;
		UW newMem;

		get_tid( &tid );
		
		if( p != NULL )
		{
			newMem = ( (p-1)->s.size * ABLKSIZE );
			MemUsed += newMem;
			if( MemUsed > MemUsedPeak )
				MemUsedPeak = MemUsed;
			gDebugTaskMem[tid] += newMem;
//			memdbgoutput( "task %d +%ld Bytes(%ld Bytes, total %ld Bytes)", tid, newMem, gDebugTaskMem[tid], MemUsed );
//			fprintf( DebugLogFile, "task %d +%ld Bytes(%ld Bytes, total %ld Bytes)\n", tid, newMem, gDebugTaskMem[tid], MemUsed );
			fprintf( DebugLogFile, "task %d +%ld Bytes(total %ld Bytes, peak %ld Bytes)\n", tid, newMem, MemUsed, MemUsedPeak );
		}
		else
		{
			fprintf( DebugLogFile, "task %d allocate memory fail!\n", tid );
		}
	}
#endif

	//restore(i_state);
	vEnableDispatch();
	
	return (void *)p;
}


/* Put memory block back on heap */
void SysLfree( void *blk )
{
	register HEADER  *p,  *q;
	//unsigned short  *ptr;
	//int i_state;
//	unsigned int i;

	if(blk == NULL)
		return;		/* Required by ANSI */
	Frees++;
	p = ((HEADER  *)blk) - 1;
	/* Audit check */
	if(p->s.ptr != p){
		Invalid++;

#if ENABLE_SYSMEM_DEBUG_OUT
	{
		ID tid;

		get_tid( &tid );
		fprintf( DebugLogFile, "task %d free memory fail!\n", tid );
	}
#endif
		
		return;
	}
	Availmem += p->s.size;

/* Pessia: 2002/4/4 
 * Use macro Memdebug while not variable */
#if Memdebug
	/* Fill data area with pattern to detect later overwrites */
	for(i=1;i<p->s.size;i++)
		memcpy(p[i].c,Debugpat,sizeof(Debugpat));
#endif

	
	//i_state = dirps();
	vDisableDispatch();

	// longn_qi 2002/01/25 for monitor memory leak
#if ENABLE_SYSMEM_DEBUG_OUT
	{
		ID tid;
		UW freeMem;

		get_tid( &tid );
		
		freeMem = ( p->s.size * ABLKSIZE );
		MemUsed -= freeMem;
		gDebugTaskMem[tid] -= freeMem;
//		memdbgoutput( "task %d -%ld Bytes(%ld Bytes, total %ld Bytes)", tid, freeMem, gDebugTaskMem[tid], MemUsed );
//		fprintf( DebugLogFile, "task %d -%ld Bytes(%ld Bytes, total %ld Bytes)\n", tid, freeMem, gDebugTaskMem[tid], MemUsed );
		fprintf( DebugLogFile, "task %d -%ld Bytes(total %ld Bytes, peak %ld Bytes)\n", tid, freeMem, MemUsed, MemUsedPeak );
	}
#endif
	
 	/* Search the SysLfree list looking for the right place to insert */
	for(q = Allocp; !(p > q && p < q->s.ptr); q = q->s.ptr){
		/* Highest address on circular list? */
		if(q >= q->s.ptr && (p > q || p < q->s.ptr))
			break;
	}
	if(p + p->s.size == q->s.ptr){
		/* Combine with front of this entry */
		p->s.size += q->s.ptr->s.size;
		p->s.ptr = q->s.ptr->s.ptr;
		#if Memdebug 
			memcpy(q->s.ptr->c,Debugpat,sizeof(Debugpat));
		#endif
	} else {
		/* Link to front of this entry */
		p->s.ptr = q->s.ptr;
	}
	//空头始终要保留
	if((q + q->s.size == p) && (q != Base)){
		/* Combine with end of this entry */
		q->s.size += p->s.size;
		q->s.ptr = p->s.ptr;
		#if Memdebug
			memcpy(p->c,Debugpat,sizeof(Debugpat));
		#endif
	} else {
		/* Link to end of this entry */
		q->s.ptr = p;
	}

	//restore(i_state);
	vEnableDispatch();
	
	/*
	if(Memwait != 0)
		sig_sem(Memsem);  
	*/
}

/* Move existing block to new area */
void *SysLrealloc( void *area, DWORD size )
{
	unsigned osize;
	HEADER  *hp;
	void *pnew;
	
	if(size == 0)
		return NULL;
		
	hp = ((HEADER *)area) - 1;
	if(hp->s.ptr != hp)
		return NULL;
	
	osize = (hp->s.size -1) * ABLKSIZE;

	/* We must copy the block since freeing it may cause the heap
	 * debugging code to scribble over it.
	 */
	if((pnew = SysLmalloc(size)) != NULL)
		memcpy(pnew,area,size>osize? osize : size);
	SysLfree(area);
	return pnew;
}

/* Allocate block of cleared memory */
void *SysLcalloc( DWORD size )
{
	register char *cp;
	
	if(size == 0)
		return NULL;
		
	if((cp = SysLmalloc(size)) != NULL)
		memset(cp,0,size);
	return cp;
}


/* Version of SysLmalloc() that waits if necessary for memory to become available */
/*
void *
SysLmallocw(nb)
WORD nb;
{
	register void *p;

	if(nb == 0)
		return NULL;
		
	while((p = SysLmalloc(nb)) == NULL){
		Memwait++;
		twai_sem(Memsem, TMO_FEVR);
    	Memwait--;
	}
	return p;
}
*/

/* Version of calloc that waits if necessary for memory to become available */
/*
void *
Lcallocw(size)
unsigned size;	// Size of each element 
{
	register char *cp;
	
	if(size == 0)
		return NULL;
		
	cp = SysLmallocw(size);
	memset(cp,0,size);
	return cp;
}
*/
/* Print heap stats : only for debug */
/*
int
dostat(void)
{
	int i;

	printf("heap size %lu avail %lu (%lu%%) \n",
	 Heapsize,Availmem * ABLKSIZE,100L*Availmem*ABLKSIZE/Heapsize);
	
	printf("allocs %lu frees %lu (diff %lu) alloc fails %lu invalid frees %lu\n",
		Allocs,Frees,Allocs-Frees,Memfail,Invalid);
	printf("\n");
	return 0;
}
*/

/* Print heap Lfree list */
/*
int
dofreelist(void)
{
	HEADER  *p;
	int i = 0;
	int j;
	unsigned corrupt;
	int i_state;

	for(p = Base->s.ptr;p != (HEADER  *)Base;p = p->s.ptr){
		corrupt = 0;
		if(Memdebug){
			//i_state = dirps();
			for(j=1;j<p->s.size;j++){
				if(memcmp(p[j].c,Debugpat,sizeof(Debugpat)) != 0){
					corrupt = j;
					break;
				}
			}
			//restore(i_state);
		}
		if(corrupt)
			printf("%p %6lu C: %u",p,(p->s.size - 1) * ABLKSIZE,corrupt);
		else
			printf("%p %6lu",p,(p->s.size - 1) * ABLKSIZE);

		if(++i == 4){
			i = 0;
			if(printf("\n") == EOF)
				return 0;
		} else
			printf(" | ");
	}
	if(i != 0)
		printf("\n");
	return 0;
}


int
dosizes(void)

{
	int i;

	for(i=0;i<16;i += 4){
		printf("N>=%5u:%7ld| N>=%5u:%7ld| N>=%5u:%7ld| N>=%5u:%7ld\n",
		 1<<i,Sizes[i],	2<<i,Sizes[i+1],
		 4<<i,Sizes[i+2],8<<i,Sizes[i+3]);
	}
	return 0;
}

*/

⌨️ 快捷键说明

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