📄 kernelheap.c
字号:
OsSchedLock(); /* Lock schedule */
#if CFG_PAR_CHECKOUT_EN >0 /* Check UMB in list */
if((U32)(usedMB) < (U32)(FMBlist))
{
preUMB = (P_UMB)((U32)(FMBlist->preUMB)-1);
while(preUMB != usedMB)
{
if(preUMB == NULL)
{
OsSchedUnlock();
return;
}
preUMB = (P_UMB)((U32)(preUMB->preMB)-1);
}
}
else
{
if(FMBlist == NULL)
{
nextUMB = (P_UMB)(Kheap.startAddr);
}
else
{
if(FMBlist->nextUMB != NULL)
{
nextUMB = (P_UMB)((U32)(FMBlist->nextUMB)-1);
}
else
{
nextUMB = NULL;
}
}
while(nextUMB != usedMB)
{
if(nextUMB == NULL)
{
OsSchedUnlock();
return;
}
if(((U32)(nextUMB->nextMB)&0x1) == 0)
{
nextFMB = (P_FMB)(nextUMB->nextMB);
nextUMB = (P_UMB)((U32)(nextFMB->nextUMB)-1);
}
else
{
nextUMB = (P_UMB)((U32)(nextUMB->nextMB)-1);
}
}
}
#endif
/* Is between two free memory block? */
if( (((U32)(usedMB->nextMB)&0x1) == 0) && (((U32)(usedMB->preMB)&0x1)==0) )
{ /* Yes,is the only one item in kernel heap? */
if((usedMB->nextMB == NULL) && (usedMB->preMB == NULL))
{
curFMB = (P_FMB)usedMB; /* Yes,release this item */
curFMB->nextFMB = NULL;
curFMB->nextUMB = NULL;
curFMB->preUMB = NULL;
FMBlist = curFMB;
}
else if(usedMB->preMB == NULL) /* Is the first item in kernel heap */
{
/* Yes,release this item,and set link for list */
curFMB = (P_FMB)usedMB;
nextFMB = (P_FMB)usedMB->nextMB;
curFMB->nextFMB = nextFMB->nextFMB;
curFMB->nextUMB = nextFMB->nextUMB;
curFMB->preUMB = NULL;
FMBlist = curFMB;
}
else if(usedMB->nextMB == NULL) /* Is the last item in kernel heap */
{ /* Yes,release this item,and set link for list */
curFMB = (P_FMB)(usedMB->preMB);
curFMB->nextFMB = NULL;
curFMB->nextUMB = NULL;
}
else /* All no,show this item between two normal FMB */
{
/* release this item,and set link for list */
nextFMB = (P_FMB)usedMB->nextMB;
curFMB = (P_FMB)(usedMB->preMB);
curFMB->nextFMB = nextFMB->nextFMB;
curFMB->nextUMB = nextFMB->nextUMB;
}
}
else if(((U32)(usedMB->preMB)&0x1) == 0) /* Is between FMB and UMB? */
{
if(usedMB->preMB == NULL) /* Yes,is the first item in kernel heap? */
{
/* Yes,release this item,and set link for list */
curFMB = (P_FMB)usedMB;
nextUMB = (P_UMB)usedMB->nextMB;
curFMB->nextUMB = nextUMB;
curFMB->preUMB = NULL;
curFMB->nextFMB = FMBlist;
FMBlist = curFMB;
}
else /* No,release this item,and set link for list */
{
curFMB = (P_FMB)usedMB->preMB;
nextUMB = (P_UMB)usedMB->nextMB;
curFMB->nextUMB = nextUMB;
}
}
else if(((U32)(usedMB->nextMB)&0x1) == 0) /* Is between UMB and FMB? */
{ /* Yes */
preUMB = (P_UMB)(usedMB->preMB); /* Get previous UMB */
curFMB = (P_FMB)(usedMB); /* new FMB */
preFMB = GetPreFMB(usedMB); /* Get previous FMB */
if(preFMB == NULL) /* Is previous FMB==NULL? */
{
nextFMB = FMBlist; /* Yes,get next FMB */
FMBlist = curFMB; /* Reset new FMB as the first item of FMB list*/
}
else
{
nextFMB = preFMB->nextFMB; /* No,get next FMB */
preFMB->nextFMB = curFMB; /* Set link for FMB list */
}
if(nextFMB == NULL) /* Is new FMB as last item of FMB list? */
{
curFMB->preUMB = preUMB; /* Yes,set link for list */
curFMB->nextUMB = NULL;
curFMB->nextFMB = NULL;
}
else
{
curFMB->preUMB = preUMB; /* No,set link for list */
curFMB->nextUMB = nextFMB->nextUMB;
curFMB->nextFMB = nextFMB->nextFMB;
}
}
else /* All no,show UMB between two UMB*/
{
curFMB = (P_FMB)(usedMB); /* new FMB */
preFMB = GetPreFMB(usedMB); /* Get previous FMB */
preUMB = (P_UMB)(usedMB->preMB); /* Get previous UMB */
nextUMB = (P_UMB)(usedMB->nextMB); /* Get next UMB */
if(preFMB == NULL ) /* Is previous FMB==NULL? */
{
nextFMB = FMBlist; /* Yes,get next FMB */
FMBlist = curFMB; /* Reset new FMB as the first item of FMB list */
}
else
{
nextFMB = preFMB->nextFMB; /* No,get next FMB */
preFMB->nextFMB = curFMB; /* Set link for FMB list */
}
curFMB->preUMB = preUMB; /* Set current FMB link for list */
curFMB->nextUMB = nextUMB;
curFMB->nextFMB = nextFMB;
}
if(curFMB->preUMB != NULL)/* Is current FMB as first item in kernel heap? */
{ /* No,set link for list */
preUMB = (P_UMB)((U32)(curFMB->preUMB)-1);
preUMB->nextMB = (void*)curFMB;
}
if(curFMB->nextUMB != NULL)/* Is current FMB as last item in kernel heap? */
{ /* No,set link for list */
nextUMB = (P_UMB)((U32)(curFMB->nextUMB)-1);
nextUMB->preMB = (void*)curFMB;
}
OsSchedUnlock(); /* Unlock schedule */
}
/**
*******************************************************************************
* @brief Get previous free memory block pointer.
* @param[in] usedMB Current used memory block.
* @param[out] None
* @retval Previous free memory block pointer.
*
* @par Description
* @details This function is called to get previous free memory block pointer.
*******************************************************************************
*/
static P_FMB GetPreFMB(P_UMB usedMB)
{
P_UMB preUMB;
preUMB = usedMB;
while(((U32)(preUMB->preMB)&0x1)) /* Is previous MB as FMB? */
{ /* No,get previous MB */
preUMB = (P_UMB)((U32)(preUMB->preMB)-1);
}
return (P_FMB)(preUMB->preMB); /* Yes,return previous MB */
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -