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

📄 winmem.c

📁 MinGUI 可视化程序代码
💻 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 + -