📄 winmem.c
字号:
/******************************************************************************
*
* Copyright 2006 National ASIC Center, All right Reserved
*
* FILE NAME: WinMem.c
* PROGRAMMER: ming.c
* Date of Creation: 2006/08/8
*
* DESCRIPTION:
*
* NOTE:
*
* FUNCTIONS LIST:
* -----------------------------------------------------------------------------
*
* -----------------------------------------------------------------------------
*
* MODIFICATION HISTORY
* LastModify 2006/09/27
******************************************************************************/
#include "winmem.h"
//---------------------------------------------------------------------------
///////////////////////////////////////////////////////////////
#define BDS_FREE 0x0000
#define BDS_SPECIAL 0x0001
#define BDS_USED 0x0002
//---------------------------------------------------------------------------
void InitBlockDataHeap (TBLOCKHEAP *heap, int block_size, int block_count)
{ heap->heap = 0;
heap->blocksize = block_size + sizeof (int);
heap->blocknum = block_count;
}
//---------------------------------------------------------------------------
void FreeBlockDataHeap (TBLOCKHEAP *heap)
{ FreeMem (heap->heap);
}
//---------------------------------------------------------------------------
void *AllocBlock(TBLOCKHEAP *heap)
{ int i;
char* block_data = 0;
if (!heap->heap)
{ heap->heap = GetMem (heap->blocknum * heap->blocksize);
if (!heap->heap) goto ret;
heap->free = 0;
}
block_data = (char*) heap->heap + heap->blocksize*heap->free;
for (i = heap->free; i < heap->blocknum; i++)
{ if (*((int *)block_data) == BDS_FREE)
{ heap->free = i + 1;
*((int *)block_data) = BDS_USED;
goto ret;
}
block_data += heap->blocksize;
}
block_data = (char *)GetMem(heap->blocksize);
if (!block_data) goto ret;
*((int *)block_data) = BDS_SPECIAL;
ret:
if (block_data)
return block_data + sizeof (int);
return NULL;
}
//---------------------------------------------------------------------------
void FreeBlock (TBLOCKHEAP *heap, void* block)
{ int i;
char* block_data;
block_data = (char*) block - sizeof(int);
if (*((int *)block_data) == BDS_SPECIAL)
FreeMem(block_data);
else if (*((int *)block_data) == BDS_USED)
{ *((int *)block_data) = BDS_FREE;
i = (block_data - (char*)heap->heap)/heap->blocksize;
if (heap->free > i)
heap->free = i;
}
}
//---------------------------------------------------------------------------
#define BTOU(nb) ((((nb) + sizeof (MemHeader) - 1) / sizeof (MemHeader)) + 1)
typedef struct m_header
{ struct m_header *ptr;
unsigned long size;
}MemHeader;
static MemHeader *mBase=0; //第一个空头change
static MemHeader *mFirst=0; //第一个有效头change
static MemHeader *mAllocp = 0; //表链头(=Base)
static unsigned long mAvail = BTOU(HeapTotalSize)-2;
static unsigned long mFail=0;/* Count of allocation failures */
static unsigned long mAllocs=0; /* Total allocations */
static unsigned long mFrees=0; /* Total frees */
extern void *Simulator_GetMem(unsigned long bSize);
/* Allocate block of 'nb' bytes */
void *GetMem( DWORD ByteSize )
{ MemHeader *p, *q;
unsigned long nu;
if(ByteSize == 0)return 0;
mAllocs++;
/* Round up to full block, then add one for header */
nu = BTOU(ByteSize);
/* Initialize heap pointers if necessary */
q = mAllocp;
if(!q)
{ //创建一个空头。目的:当所有空间分配完时,Lfree函数需要有一个表头
#if BASE_OS_TYPE==1
mBase = (MemHeader *)Simulator_GetMem(HeapTotalSize);
#else
mBase = (MemHeader *)HeapStartAddress;
#endif
mBase->ptr = mAllocp = q = mBase;
mBase->size = 1;
mFirst =mBase + 1;
mBase->ptr = mFirst;
mFirst->ptr = mBase;
mFirst->size = BTOU(HeapTotalSize)-2;
}
/* Search heap list */
for(p = q->ptr; ; q = p, p = p->ptr){
if(p->size >= nu){
/* This chunk is at least as large as we need */
if(p->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->ptr = p->ptr;
} else {
/* Carve out piece from end of entry */
p->size -= nu;
p += p->size;
p->size = nu;
}
p->ptr = p; /* for auditing */
mAvail -= p->size;
if( mAvail < 1280 )
{
DebugAlert( "系统内存不足10K!请关闭一些窗口!" );
}
p++;
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 == mAllocp)
{ p = 0;
mFail++;
DebugAlert( "系统内存严重不足!" );
break;
}
}
return (void *)p;
}
/* Put memory block back on heap */
void FreeMem( void *blk )
{ MemHeader *p, *q;
if(!blk)return;
mFrees++;
p = ((MemHeader *)blk) - 1;
/* Audit check */
if(p->ptr != p)return;
mAvail += p->size;
/* Search the SysLfree list looking for the right place to insert */
for(q = mAllocp; !(p > q && p < q->ptr); q = q->ptr)
{ /* Highest address on circular list? */
if(q >= q->ptr && (p > q || p < q->ptr))break;
}
if(p + p->size == q->ptr)
{ /* Combine with front of this entry */
p->size += q->ptr->size;
p->ptr = q->ptr->ptr;
}
else
{ /* Link to front of this entry */
p->ptr = q->ptr;
}
//空头始终要保留
if((q + q->size == p) && (q != mBase))
{/* Combine with end of this entry */
q->size += p->size;
q->ptr = p->ptr;
}
else
{/* Link to end of this entry */
q->ptr = p;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -