/***************************************************************************** Function : osMemFreeNode Description : free the node from memory & if there are free node beside, merger them. at last update "pstListHead' which saved all free node control head Input : pstNode -- the node which need be freed pPool --Pointer to memory pool Output : None Return : None *****************************************************************************/ INLINE VOID osMemFreeNode(LOS_MEM_DYN_NODE *pstNode, VOID *pPool) { LOS_MEM_DYN_NODE *pstNextNode = (LOS_MEM_DYN_NODE *)NULL; LOS_DL_LIST *pstListHead = (LOS_DL_LIST *)NULL; OS_MEM_REDUCE_USED(OS_MEM_NODE_GET_SIZE(pstNode->uwSizeAndFlag)); pstNode->uwSizeAndFlag = OS_MEM_NODE_GET_SIZE(pstNode->uwSizeAndFlag); if ((pstNode->pstPreNode != NULL) && (!OS_MEM_NODE_GET_USED_FLAG(pstNode->pstPreNode->uwSizeAndFlag))) { LOS_MEM_DYN_NODE *pstPreNode = pstNode->pstPreNode; osMemMergeNode(pstNode); pstNextNode = OS_MEM_NEXT_NODE(pstPreNode); if (!OS_MEM_NODE_GET_USED_FLAG(pstNextNode->uwSizeAndFlag)) { LOS_ListDelete(&(pstNextNode->stFreeNodeInfo)); osMemMergeNode(pstNextNode); } LOS_ListDelete(&(pstPreNode->stFreeNodeInfo)); pstListHead = OS_MEM_HEAD(pPool, pstPreNode->uwSizeAndFlag); if (NULL == pstListHead) { PRINT_ERR("%s %d\n", __FUNCTION__, __LINE__); return; } LOS_ListAdd(pstListHead,&(pstPreNode->stFreeNodeInfo)); } else { pstNextNode = OS_MEM_NEXT_NODE(pstNode); if (!OS_MEM_NODE_GET_USED_FLAG(pstNextNode->uwSizeAndFlag)) { LOS_ListDelete(&(pstNextNode->stFreeNodeInfo)); osMemMergeNode(pstNextNode); } pstListHead = OS_MEM_HEAD(pPool, pstNode->uwSizeAndFlag); if (NULL == pstListHead) { PRINT_ERR("%s %d\n", __FUNCTION__, __LINE__); return; } LOS_ListAdd(pstListHead,&(pstNode->stFreeNodeInfo)); } }
/***************************************************************************** Function : osMemSpitNode Description : spit new node from pstAllocNode, and merge remainder mem if necessary Input : pPool --Pointer to memory pool pstAllocNode --the source node which new node be spit from to. After pick up it's node info, change to point the new node uwAllocSize -- the size of new node Output : pstAllocNode -- save new node addr Return : None *****************************************************************************/ INLINE VOID osMemSpitNode(VOID *pPool, LOS_MEM_DYN_NODE *pstAllocNode, UINT32 uwAllocSize) { LOS_MEM_DYN_NODE *pstNewFreeNode = (LOS_MEM_DYN_NODE *)NULL; LOS_MEM_DYN_NODE *pstNextNode = (LOS_MEM_DYN_NODE *)NULL; LOS_DL_LIST *pstListHead = (LOS_DL_LIST *)NULL; pstNewFreeNode = (LOS_MEM_DYN_NODE *)((UINT8 *)pstAllocNode + uwAllocSize); pstNewFreeNode->pstPreNode = pstAllocNode; pstNewFreeNode->uwSizeAndFlag = pstAllocNode->uwSizeAndFlag - uwAllocSize; pstAllocNode->uwSizeAndFlag = uwAllocSize; pstNextNode = OS_MEM_NEXT_NODE(pstNewFreeNode); pstNextNode->pstPreNode = pstNewFreeNode; if (!OS_MEM_NODE_GET_USED_FLAG(pstNextNode->uwSizeAndFlag)) { LOS_ListDelete(&(pstNextNode->stFreeNodeInfo)); osMemMergeNode(pstNextNode); } pstListHead = OS_MEM_HEAD(pPool, pstNewFreeNode->uwSizeAndFlag); if (NULL == pstListHead) { PRINT_ERR("%s %d\n", __FUNCTION__, __LINE__); return; } LOS_ListAdd(pstListHead,&(pstNewFreeNode->stFreeNodeInfo)); }
/***************************************************************************** Function : LOS_MuxCreate Description : Create a mutex, Input : None Output : puwMuxHandle ------ Mutex operation handle Return : LOS_OK on success ,or error code on failure *****************************************************************************/ LITE_OS_SEC_TEXT_INIT UINT32 LOS_MuxCreate (UINT32 *puwMuxHandle) { UINT32 uwIntSave; MUX_CB_S *pstMuxCreated; LOS_DL_LIST *pstUnusedMux; UINT32 uwErrNo; UINT32 uwErrLine; if (NULL == puwMuxHandle) { return LOS_ERRNO_MUX_PTR_NULL; } uwIntSave = LOS_IntLock(); if (LOS_ListEmpty(&g_stUnusedMuxList)) { LOS_IntRestore(uwIntSave); OS_GOTO_ERR_HANDLER(LOS_ERRNO_MUX_ALL_BUSY); } pstUnusedMux = LOS_DL_LIST_FIRST(&(g_stUnusedMuxList)); LOS_ListDelete(pstUnusedMux); pstMuxCreated = (GET_MUX_LIST(pstUnusedMux)); /*lint !e413*/ pstMuxCreated->usMuxCount = 0; pstMuxCreated->ucMuxStat = OS_MUX_USED; pstMuxCreated->usPriority = 0; pstMuxCreated->pstOwner = (LOS_TASK_CB *)NULL; LOS_ListInit(&pstMuxCreated->stMuxList); *puwMuxHandle = (UINT32)pstMuxCreated->ucMuxID; LOS_IntRestore(uwIntSave); return LOS_OK; ErrHandler: OS_RETURN_ERROR_P2(uwErrLine, uwErrNo); }
/***************************************************************************** Function : osMemMergeNodeForReAllocBigger Description : reAlloc a Bigger memory node after merge pstNode and nextNode Input : pPool --- Pointer to memory pool uwAllocSize --- the size of new node which will be alloced pstNode --the node which wille be realloced uwNodeSize -- the size of old node pstNextNode -- pointer next node which will be merged Output : pstNode -- pointer to the new node after realloc Return : None *****************************************************************************/ INLINE VOID osMemMergeNodeForReAllocBigger(VOID *pPool, UINT32 uwAllocSize, LOS_MEM_DYN_NODE *pstNode, UINT32 uwNodeSize, LOS_MEM_DYN_NODE *pstNextNode) { pstNode->uwSizeAndFlag = uwNodeSize; LOS_ListDelete(&(pstNextNode->stFreeNodeInfo)); osMemMergeNode(pstNextNode); OS_MEM_ADD_USED(pstNode->uwSizeAndFlag - uwNodeSize); if ((uwAllocSize + OS_MEM_NODE_HEAD_SIZE + OS_MEM_ALIGN_SIZE) <= pstNode->uwSizeAndFlag) { OS_MEM_REDUCE_USED(pstNode->uwSizeAndFlag - uwAllocSize); osMemSpitNode(pPool, pstNode, uwAllocSize); } OS_MEM_NODE_SET_USED_FLAG(pstNode->uwSizeAndFlag); }
/***************************************************************************** Function : osMemAllocWithCheck Description : Allocate node from Memory pool Input : pPool --- Pointer to memory pool uwSize --- Size of memory in bytes to allocate Output : None Return : Pointer to allocated memory *****************************************************************************/ INLINE VOID *osMemAllocWithCheck(VOID *pPool, UINT32 uwSize) { LOS_MEM_DYN_NODE *pstAllocNode = (LOS_MEM_DYN_NODE *)NULL; UINT32 uwAllocSize; uwAllocSize = OS_MEM_ALIGN(uwSize + OS_MEM_NODE_HEAD_SIZE, OS_MEM_ALIGN_SIZE); pstAllocNode = osMemFindSuitableFreeBlock(pPool, uwAllocSize); if (pstAllocNode == NULL) { PRINT_ERR("[%s] No suitable free block, require free node size: 0x%x\n", __FUNCTION__, uwAllocSize); return NULL; } if ((uwAllocSize + OS_MEM_NODE_HEAD_SIZE + OS_MEM_ALIGN_SIZE) <= pstAllocNode->uwSizeAndFlag) { osMemSpitNode(pPool, pstAllocNode, uwAllocSize); } LOS_ListDelete(&(pstAllocNode->stFreeNodeInfo)); osMemSetMagicNumAndTaskid(pstAllocNode); OS_MEM_NODE_SET_USED_FLAG(pstAllocNode->uwSizeAndFlag); OS_MEM_ADD_USED(OS_MEM_NODE_GET_SIZE(pstAllocNode->uwSizeAndFlag)); return (pstAllocNode + 1); }