/* ------------------------------------------------------------------------------ */
static MBOOL SYSRAM_FreeUserPhy(SYSRAM_USER_ENUM const User, SYSRAM_MEM_BANK_ENUM const MemBankNo)
{
	MBOOL Ret = MFALSE;
	SYSRAM_MEM_NODE_STRUCT *pPrevOrNextNode = NULL;
	SYSRAM_MEM_NODE_STRUCT *pCurrNode = NULL;
	SYSRAM_MEM_NODE_STRUCT *pTempNode = NULL;

	SYSRAM_MEM_POOL_STRUCT * const pMemPoolInfo = SYSRAM_GetMemPoolInfo(MemBankNo);
	/*  */
	if (!pMemPoolInfo) {
		LOG_ERR("pMemPoolInfo==NULL,User(%d),MemBankNo(%d)", User, MemBankNo);
		return MFALSE;
	}
	/*  */
	pCurrNode = &pMemPoolInfo->pMemNode[0];
	for (; pCurrNode; pCurrNode = pCurrNode->pNext) {
		if (User == pCurrNode->User) {
			Ret = MTRUE;	/* user is found. */
			if (pMemPoolInfo->UserCount > 0)
				pMemPoolInfo->UserCount--;

			pCurrNode->User = SYSRAM_USER_NONE;
			if (NULL != pCurrNode->pPrev) {
				pPrevOrNextNode = pCurrNode->pPrev;
				/*  */
				if (SYSRAM_USER_NONE == pPrevOrNextNode->User) {
					/* Merge previous: prev(o) + curr(x) */
					pTempNode = pCurrNode;
					pCurrNode = pPrevOrNextNode;
					pCurrNode->Length += pTempNode->Length;
					pCurrNode->pNext = pTempNode->pNext;
					if (NULL != pTempNode->pNext) {
						pTempNode->pNext->pPrev = pCurrNode;
					}
					SYSRAM_FreeNode(pMemPoolInfo, pTempNode);
				}
			}

			if (NULL != pCurrNode->pNext) {
				pPrevOrNextNode = pCurrNode->pNext;
				/*  */
				if (SYSRAM_USER_NONE == pPrevOrNextNode->User) {
					/* Merge next: curr(o) + next(x) */
					pTempNode = pPrevOrNextNode;
					pCurrNode->Length += pTempNode->Length;
					pCurrNode->pNext = pTempNode->pNext;
					if (NULL != pCurrNode->pNext) {
						pCurrNode->pNext->pPrev = pCurrNode;
					}
					SYSRAM_FreeNode(pMemPoolInfo, pTempNode);
				}
			}
			break;
		}
	}
	/*  */
	return Ret;
}
Esempio n. 2
0
/*
Alignment should be 2^N, 4/8/2048 bytes alignment only
First fit algorithm
*/
static MUINT32 SYSRAM_AllocUserPhy(
    SYSRAM_USER_ENUM const      User,
    MUINT32 const               Size,
    MUINT32 const               Alignment,
    SYSRAM_MEM_BANK_ENUM const  MemBankNo
)
{
    SYSRAM_MEM_NODE_STRUCT* pSplitNode = NULL;
    SYSRAM_MEM_NODE_STRUCT* pCurrNode = NULL;
    MUINT32 AlingnedAddr = 0;
    MUINT32 ActualSize = 0;
    //
    SYSRAM_MEM_POOL_STRUCT*const pMemPoolInfo = SYSRAM_GetMemPoolInfo(MemBankNo);
    if(!pMemPoolInfo)
    {
        return  0;
    }
    //
    pCurrNode = &pMemPoolInfo->pMemNode[0];
    for (; pCurrNode && pCurrNode->Offset < pMemPoolInfo->Size; pCurrNode = pCurrNode->pNext)
    {
        if(SYSRAM_USER_NONE == pCurrNode->User)
        {
            //Free space
            AlingnedAddr = (pCurrNode->Offset + Alignment - 1)&(~(Alignment - 1));
            ActualSize = Size + AlingnedAddr - pCurrNode->Offset;
            if  (ActualSize <= pCurrNode->Length)
            {
                // Hit!! Split into 2
                // pSplitNode pointers to the next available (free) node.
                pSplitNode = SYSRAM_AllocNode(pMemPoolInfo);
                pSplitNode->Offset  = pCurrNode->Offset + ActualSize;
                pSplitNode->Length  = pCurrNode->Length - ActualSize;
                pSplitNode->pPrev   = pCurrNode;
                pSplitNode->pNext   = pCurrNode->pNext;
                //
                pCurrNode->User     = User;
                pCurrNode->Length   = ActualSize;
                pCurrNode->pNext    = pSplitNode;
                //
                if(NULL != pSplitNode->pNext)
                {
                    pSplitNode->pNext->pPrev = pSplitNode;
                }
                //
                pMemPoolInfo->UserCount++;
                break;
            }
            //Not hit
            ActualSize = 0;
        }
    };
    //
    return ActualSize ? (AlingnedAddr + pMemPoolInfo->Addr) : 0;
}