📄 cm_mem.c
字号:
* 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 + -