📄 lmalloc.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 + -