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

📄 cm_mem.c

📁 中国石油二期加油站IC系统后台通讯软件
💻 C
📖 第 1 页 / 共 3 页
字号:
*              function is called by cmFree. The function does not check the 
*              validity of the memory block. The caller must be sure that the 
*              block was previously allocated and belongs to the heap pool. The 
*              function maintain the sorting order of the memory block on the
*              starting address of the block. This function also do compaction 
*              if the neighbouring blocks are already in the heap. 
*
*
*
*       File:  cm_mem.c
*
*/
	#ifdef ANSI
PRIVATE S16  cmHeapFree 
(
CmMmHeapCb  *heapCb,
Data        *ptr,
Size         size 
)
	#else
PRIVATE S16  cmHeapFree (heapCb, ptr, size)
CmMmHeapCb  *heapCb;
Data        *ptr;
Size         size;
	#endif
{
	CmHEntry  *p;    
	CmHEntry  *curHBlk;	   /* Current heap block */ 

	TRC2(cmHeapFree);

	/* Roundup the requested size */
	size = CMM_DATALIGN(size, (heapCb->minSize));

	/* increase the avlSize */
	heapCb->avlSize += size;

	p = (CmHEntry *)ptr; 

	/* Acquire the heap lock */
	(Void) SLock (&(heapCb->heapLock));

	for( curHBlk = heapCb->next; curHBlk; curHBlk = curHBlk->next)
	{
		/* 
		 * The block will be inserted to maintain the sorted order on the
		 * starting address of the block.
		 */
		if(p > curHBlk)
		{
			if(!(curHBlk->next) || 
			   (p < (curHBlk->next)))
			{
				/* Heap block should be inserted here */

				/* 
				 * Check if the block to be returned can be merged with the
				 * current block.
				 */
				if(((Data *)curHBlk + curHBlk->size) == (Data *)p)
				{
					/* Merge the block */
					size = (curHBlk->size += size);
					p = curHBlk;
				}
				else
				{
					/* insert the block */
					p->next = curHBlk->next;
					p->size = size; 
					curHBlk->next = p;
				}

				/* Try to merge with the next block in the chain */
				if(((Data *)p + size) == (Data *)(p->next))
				{
					/* p->next can not be NULL */
					p->size += p->next->size; 
					p->next  = p->next->next;
				}

				/* Release the lock */
				(Void) SUnlock (&(heapCb->heapLock));

				RETVALUE(ROK);
			}
		}
		else if(p < curHBlk)
		{
			/* 
			* Check if the block to be returned can be merged with the
			* current block.
			*/
			if(((Data *)p + p->size) == (Data *)curHBlk)
			{
				/* Merge the block */
				p->size += curHBlk->size;
				p->next = curHBlk->next;
			}
			else
			{
				/* insert the block */
				p->next = curHBlk;
				p->size = size; 
			}

			heapCb->next = p;

			/* Release the lock */
			(Void) SUnlock (&(heapCb->heapLock));

			RETVALUE(ROK);
		}

	}

	if(heapCb->next == NULLP)
	{
		/* Heap block is empty. Insert the block in the head. */
		heapCb->next = p;
		p->next = NULLP;
		p->size = size;

		/* Release the heap lock */
		(Void) SUnlock (&(heapCb->heapLock));

		RETVALUE(ROK);
	}

	/* Release the lock */
	(Void) SUnlock (&(heapCb->heapLock));

	RETVALUE(RFAILED);
} /* end of cmHeapFree */


#else /* not use  trilium source code */


/*
*
*       Fun:   cmMmHeapInit
*
*       Desc:  Initialize the heap pool. 
*
*
*       Ret:   ROK     - successful
*              RFAILED - unsuccessful.
*
*       Notes: This function is called by the cmMmRegInit. 
*
*       File:  cm_mem.c
*
*/
	#ifdef ANSI
PRIVATE Void  cmMmHeapInit 
(
Data        *memAddr,
CmMmHeapCb  *heapCb,
Size         size 
)
	#else
PRIVATE Void  cmMmHeapInit (memAddr, heapCb, size)
Data        *memAddr;
CmMmHeapCb  *heapCb;
Size         size;
	#endif
{
	TRC2(cmMmHeapInit);


#ifdef POOL_DBG
	memset(memAddr, 0, size);
#endif

	/* Initialize the heap control block */
	heapCb->vStart      = memAddr;
	heapCb->vEnd        = memAddr + size;
	heapCb->avlSize    = size;
	heapCb->minSize    = CMM_MINBUFSIZE;

	heapCb->next       = (CmHEntry *)memAddr;
	heapCb->next->next = (CmHEntry *)((char *)memAddr + size - sizeof(CmHEntry));
	heapCb->next->next->next = NULLP;
	heapCb->next->prev = NULLP;
	heapCb->next->size = 0;

#if (ERRCLASS & ERRCLS_DEBUG)
	heapCb->numFragBlk  = 0;
	heapCb->numReq      = 0;
	heapCb->numFailure  = 0;
#endif

}


/*
*
*       Fun:   cmHeapAlloc
*
*       Desc:  Allocates the memory block from the heap pool. 
*
*
*       Ret:   ROK     - successful
*              RFAILED - unsuccessful.
*
*       Notes: This function is called by the cmAlloc. cmAlloc calls this
*              function when there is no memory block available in the bucket 
*              and the  heap pool is configured.
*
*
*
*       File:  cm_mem.c
*
*/
	#ifdef ANSI
PRIVATE S16  cmHeapAlloc 
(
CmMmHeapCb  *heapCb,
Data       **ptr,
Size        *size 
)
	#else
PRIVATE S16  cmHeapAlloc (heapCb, ptr, size)
CmMmHeapCb  *heapCb;
Data       **ptr;
Size        *size;
	#endif
{
	CmHEntry  *tmpEntry;	/* heap block */
	CmHEntry  *newEntry;	/* new heap block */

	TRC2(cmHeapAlloc);

	/* Roundup the requested size */
	*size = CMM_DATALIGN(*size, (heapCb->minSize));
	if(*size == 0)
	{
		RETVALUE(RFAILED);
	}

	/* Acquire the heap lock */
	(Void) SLock (&(heapCb->heapLock));

	tmpEntry = heapCb->next;
	while(NULL != tmpEntry->next)
	{
		if((S32)((char *)tmpEntry->next - (char *)tmpEntry - tmpEntry->size \
				 - 2*sizeof(CmHEntry)) >= (S32)*size)
		{
			break;
		}
		tmpEntry = tmpEntry->next;
	}
	if(NULL == tmpEntry->next)
	{
		printf("heapCb->avlSize = %d\n", (int)heapCb->avlSize);
		(Void) SUnlock (&(heapCb->heapLock));
		RETVALUE(ROUTRES);
	}

	if(0 == tmpEntry->size)
	{

		tmpEntry->size = *size;
		*ptr = (Data *)(tmpEntry + 1);
		heapCb->avlSize -= (*size + sizeof(CmHEntry));
#if (ERRCLASS & ERRCLS_DEBUG)
		heapCb->numReq++;
#endif
		(Void) SUnlock (&(heapCb->heapLock));
		RETVALUE(ROK);
	}
	newEntry = (CmHEntry*)((char *)tmpEntry + sizeof(CmHEntry) + tmpEntry->size);
	newEntry->next = tmpEntry->next;
	newEntry->prev = tmpEntry;
	tmpEntry->next = newEntry;

	if(NULL != newEntry->next)
	{
		newEntry->next->prev = newEntry;
	}
	newEntry->size = *size;
	*ptr = (Data *)(newEntry + 1);

	heapCb->avlSize -= (*size + sizeof(CmHEntry));

#if (ERRCLASS & ERRCLS_DEBUG)
	heapCb->numReq++;
#endif
	(Void) SUnlock (&(heapCb->heapLock));
	RETVALUE(ROK);
}


/*
*
*       Fun:   cmHeapFree
*
*       Desc:  Return the memory block from the heap pool. 
*
*
*       Ret:   ROK     - successful
*              RFAILED - unsuccessful.
*
*       Notes: This function returns the memory block to the heap  pool. This 
*              function is called by cmFree. The function does not check the 
*              validity of the memory block. The caller must be sure that the 
*              block was previously allocated and belongs to the heap pool. The 
*              function maintain the sorting order of the memory block on the
*              starting address of the block. This function also do compaction 
*              if the neighbouring blocks are already in the heap. 
*
*
*
*       File:  cm_mem.c
*
*/
	#ifdef ANSI
PRIVATE S16  cmHeapFree 
(
CmMmHeapCb  *heapCb,
Data        *ptr,
Size         size 
)
	#else
PRIVATE S16  cmHeapFree (heapCb, ptr, size)
CmMmHeapCb  *heapCb;
Data        *ptr;
Size         size;
	#endif
{
	CmHEntry  *p;    
	CmHEntry  *tmp;    

	TRC2(cmHeapFree);

	size = CMM_DATALIGN(size, (heapCb->minSize));
	p = (CmHEntry*)ptr;
	p--;
	(Void) SLock (&(heapCb->heapLock));

	if(size != p->size)
	{
		(Void) SUnlock (&(heapCb->heapLock));
		RETVALUE(RFAILED);
	}
	heapCb->avlSize += (size + sizeof(CmHEntry));

	tmp = p->prev;
	if(NULL != tmp)
	{
		tmp->next = p->next;
		if(NULL != p->next)
		{
			p->next->prev= tmp;
		}

	}
	else
	{
		p->size = 0;
	}
#if (ERRCLASS & ERRCLS_DEBUG)
	heapCb->numReq--;
#endif
	(Void) SUnlock (&(heapCb->heapLock));
	RETVALUE(ROK);
}


#endif /* use trillium source code */

/***********************************************************************************
* Function Name           : cmPrntMem
* Input Parameters        : 
* Output Parameters       :
* Return value            :
* Global Variable Accessed:
* Global Variable Modified:
* Extern Call Functions   :
* Description             :
* Modification            :
************************************************************************************/

#ifdef ANSI
PRIVATE S16  cmPrntMem 
(
Void *regionCb,
Size msgLen
)
#else
PRIVATE S16  cmPrntMem (regionCb, msgLen)
Void *regionCb;
Size msgLen;
#endif
{
	CmMmRegCb *regCb = regionCb;
	U16 Cnt;

	printf("region: %d, number of bucket: %d\n", regCb->region, regCb->numBkts);
	for(Cnt = 0; Cnt < regCb->numBkts; Cnt++)
	{
		printf("Bucket: %d\n", Cnt);
		printf("size: %d, numblk: %d, numAlloc: %d\n\n", (int)regCb->bktTbl[Cnt].size, (int)regCb->bktTbl[Cnt].numBlks, (int)regCb->bktTbl[Cnt].numAlloc);
#if (ERRCLASS & ERRCLS_DEBUG)
		printf("Heap in used block: %d\n", (int)regCb->heapCb.numReq);
#endif
	}
	printf("HeapSize: %d, avalibleSize: %d, alloc size: %d\n\n", (int)(regCb->heapCb.vEnd-regCb->heapCb.vStart), (int)regCb->heapCb.avlSize, (int)msgLen);
	RETVALUE(ROK);
}





#undef TEST
#ifdef TEST
	#include "string.h"

	#define BUF_SIZE 256
	#define Q_SIZE		256

Data buf[BUF_SIZE];

CmMmHeapCb Entry, * Cb;
typedef struct
{
	Data * Buf[Q_SIZE];
	Size    Len[Q_SIZE];
	S32 Head;
	S32     Tail;
	S32     Cnt;
	S32   Size;
} Qu;
Qu Q1;
U8 g_rand = 0X7F;

void testHeap()
{
	Data * tmp;
	Size len;

	Cb = &Entry;
	Q1.Head = Q1.Tail = 0;
	Q1.Cnt = 0;
	Q1.Size = 256;

	cmMmHeapInit(buf, &Entry, BUF_SIZE);

	while(1)
	{
		if((rand()&0xff) > g_rand)
		{
			while(0 == (len = rand()&0xff));
			if(ROK == cmHeapAlloc(Cb, &tmp, &len))
			{
				if(Q1.Cnt >= Q1.Size)
				{
					cmHeapFree(Cb, tmp, len);
					continue;
				}
				Q1.Buf[Q1.Head] = tmp;
				Q1.Len[Q1.Head] = len;
				Q1.Cnt++;
				if(++Q1.Head == Q1.Size)
				{
					Q1.Head = 0;
				}
				printf("get ptr: ptr = %p, len = %d, availiable size = %d\n ", tmp, (int)len, (int)Cb->avlSize);
				memset(tmp, 0xff, len);
			}
		}
		else
		{
			if(Q1.Cnt == 0)
			{
				continue;
			}
			tmp = Q1.Buf[Q1.Tail];
			len = Q1.Len[Q1.Tail];
			Q1.Cnt--;
			if(++Q1.Tail == Q1.Size)
			{
				Q1.Tail = 0;
			}
			if(ROK != cmHeapFree(Cb, tmp, len))
			{
				printf("error:ptr = %p, len = %d\n", tmp, (int)len);
				taskSuspend(taskIdSelf());
			}
			printf("free ptr: ptr = %p, len = %d, availible size = %d\n ", tmp, (int)len, (int)Cb->avlSize);
		}
	}
}

#endif


/********************************************************************30**
 
		 End of file: cm_mem.c 1.4  -  10/14/98 14:31:52
 
*********************************************************************31*/


/********************************************************************40**
 
		Notes:
 
*********************************************************************41*/

/********************************************************************50**
 
*********************************************************************51*/


/********************************************************************60**
 
		Revision history:
 
*********************************************************************61*/

/********************************************************************90**
 
	ver       pat    init                  description
------------ -------- ---- -----------------------------------------------
1.1          ---      rm   1. initial release

1.2          ---      kr   1. Fixed a bug in function cmMmRegInit
			 ---      kp   2. Fixed miscellaneous GCC compile warnings
			 ---      kp   3. Bug fix in cmHeapFree

1.3          ---      rm   1. Implement separate locks for each configured
							  bucket.

1.4          ---      ada  1. Removed chksrc generated error

*********************************************************************91*/


⌨️ 快捷键说明

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