📄 pm-alloc.c
字号:
} PDEBUG(" Get it %d\n", npBestFitBlock); // :-), yeah, we get it! Goto allocation { PM_ALLOC_FREE_NODE_T *pBestBlock; pBestBlock = __PM_GET_BLOCK_POINTER(npBestFitBlock); if (uBestFitUnits > uReqUnits) // split is needed { if(uJustifyUnits && ((UINT)npBestFitBlock + uJustifyAdjust)%uJustifyUnits) { // the big trouble, we may need to split it into three INT npHeadBlock = npBestFitBlock; UINT uHeadBlockUnits = uJustifyUnits - ((UINT)npBestFitBlock + uJustifyAdjust)%uJustifyUnits; INT npTailBlock = npBestFitBlock + (INT)(uReqUnits + uHeadBlockUnits); // get the tailing block's address UINT uTailBlockUnits = uBestFitUnits - uReqUnits - uHeadBlockUnits; // get the tailing units PDEBUG(" Split from %d to %d [%d] %d\n", uBestFitUnits, uHeadBlockUnits, uReqUnits, uTailBlockUnits); // this will actually replace the origianl node __insert_new_free_block(pPMRoot, npHeadBlock, uHeadBlockUnits, pBestBlock->npNext, pBestBlock->npPrev, 0); if(uTailBlockUnits) // ok tailing block { __insert_new_free_block(pPMRoot, npTailBlock, uTailBlockUnits, pBestBlock->npNext, npHeadBlock, 0); } // and then the best fit block is ajusted to satisfy justification condition npBestFitBlock = npHeadBlock + (INT)uHeadBlockUnits; } else // no justification or justification is satisfied at the beginning { INT npNewBlock = npBestFitBlock + (INT)uReqUnits; // get the remainning block's address UINT uNewBlockUnits = uBestFitUnits - uReqUnits; // get the remainning units PDEBUG(" Split from %d to [%d] %d\n", uBestFitUnits, uReqUnits, uNewBlockUnits); // this will actually replace the origianl node __insert_new_free_block(pPMRoot, npNewBlock, uNewBlockUnits, pBestBlock->npNext, pBestBlock->npPrev, 0); // check if it is the head one if (npBestFitBlock == pPMRoot->npFreeList) { pPMRoot->npFreeList = npNewBlock; } } } else // no split is needed { // and certainly justification should be satisfied here // we need to delete it from the heap link if (pBestBlock->npNext >= 0) { PM_ALLOC_FREE_NODE_T *pNextBlock = __PM_GET_BLOCK_POINTER(pBestBlock->npNext); pNextBlock->npPrev = pBestBlock->npPrev; } if (pBestBlock->npPrev >= 0) { PM_ALLOC_FREE_NODE_T *pPrevBlock = __PM_GET_BLOCK_POINTER(pBestBlock->npPrev); pPrevBlock->npNext = pBestBlock->npNext; } else // it should be the head one { // check if it is the head one if (npBestFitBlock == pPMRoot->npFreeList) { pPMRoot->npFreeList = pBestBlock->npNext; } else // heap mistake { PFATAL("Heap corrupted, broken link!\n"); } } } PDEBUG(" Get a handle \n"); // the last step, get a free handle hRtn = os_get_from_pool(&pPMRoot->handlePool); // and fill it with proper values hRtn->pLogical = (void *)((BYTE *)pPMRoot->pLogicalAddress + npBestFitBlock*__PM_ALLOC_UNIT); hRtn->uPhysical = pPMRoot->uPhysicalAddress + npBestFitBlock*__PM_ALLOC_UNIT; hRtn->uSize = uReqUnits; pPMRoot->uFreeUnits -= uReqUnits; // decrease the free size // done, baby! }__pm_alloc_just_out: PML_LEAVE(); //######################################################################## return hRtn;}MEM_HANDLE_T pm_alloc_physical (void *pRoot, UINT uNumBytes){ return pm_alloc_physical_justify(pRoot, uNumBytes, 0);}void pm_free_physical (void *pRoot, MEM_HANDLE_T hPhysicalMem){ PM_ALLOC_ROOT_T *pPMRoot = (PM_ALLOC_ROOT_T *) pRoot; if(!pPMRoot || pPMRoot->init_magic != __PM_INIT_MAGIC) { PFATAL("Tried to use an invalid heap root pointer !\n"); return; } if (NULL == hPhysicalMem) return; if (0 == pPMRoot->uTotalUnits)// uninitialized { PFATAL("Tried to free after heap is destroyed !\n"); return; } // check if it is my baby, just protect me from mistakes if (os_validate_pool_element(&pPMRoot->handlePool, hPhysicalMem) < 0 || hPhysicalMem->uPhysical < pPMRoot->uPhysicalAddress || hPhysicalMem->uPhysical >= pPMRoot->uPhysicalAddress + pPMRoot->uTotalUnits*__PM_ALLOC_UNIT || 0 == hPhysicalMem->uSize ) { PFATAL("Tried to free a wrong / unallocated handle 0x%8.8x !\n", (UINT)hPhysicalMem); return; } PDEBUG(" Freeing 0x%8.8x size 0x%8.8x\n", hPhysicalMem->uPhysical, hPhysicalMem->uSize); //######################################################################## PML_ENTER(); { INT npAfterMe = -1; // haven't find yet INT npFree = (INT)(hPhysicalMem->uPhysical - pPMRoot->uPhysicalAddress)/__PM_ALLOC_UNIT; UINT uFreeUnits = hPhysicalMem->uSize; // now put it back into handle pool hPhysicalMem->uSize = 0; // unmark it // should we check if it is in pool already, this is fatal! os_put_back_to_pool(&pPMRoot->handlePool, hPhysicalMem); PDEBUG(" Look up it's position\n"); // look for it's position in blocks { INT npCurr = pPMRoot->npFreeList; while(npCurr >= 0 && npCurr < npFree) { PM_ALLOC_FREE_NODE_T *pCurrBlock = __PM_GET_BLOCK_POINTER(npCurr); if(pCurrBlock->npNext > npFree || pCurrBlock->npNext < 0) { npAfterMe = npCurr; break; } if(pCurrBlock->npNext < 0) break; // end of heap if(npCurr >= pCurrBlock->npNext) // check for heap corrupt { PFATAL("Allocation heap corrupted !\n"); goto __pm_free_out; } npCurr = pCurrBlock->npNext; } if(npCurr == npFree) // oops, you passed in an unallocated block { PM_ALLOC_FREE_NODE_T *pCurrB = __PM_GET_BLOCK_POINTER(npCurr); if(uFreeUnits != pCurrB->uUnits) { PFATAL("Heap chain are currupted !\n"); } else { PFATAL("Tried to free an unallocated" " block at physical 0x%8.8x !\n", (UINT)( pPMRoot->uPhysicalAddress + __PM_ALLOC_UNIT*npFree)); } goto __pm_free_out; } if(npAfterMe >= 0) // Yes, after me { PM_ALLOC_FREE_NODE_T *pAfterMeBlock = __PM_GET_BLOCK_POINTER(npAfterMe); __insert_new_free_block(pPMRoot, npFree, uFreeUnits, pAfterMeBlock->npNext, npAfterMe, 1); } else // no, before everyone { __insert_new_free_block(pPMRoot, npFree, uFreeUnits, pPMRoot->npFreeList, -1, 1); pPMRoot->npFreeList = npFree; } // ok done } pPMRoot->uFreeUnits += uFreeUnits; // increase the free size }__pm_free_out: PML_LEAVE(); //######################################################################## return;}ULONG pm_get_actual_physical_size(MEM_HANDLE_T hPhysicalMem){ if (NULL == hPhysicalMem) return 0; return (ULONG)hPhysicalMem->uSize*__PM_ALLOC_UNIT;}UINT pm_get_physical_base(void *pRoot){ PM_ALLOC_ROOT_T *pPMRoot = (PM_ALLOC_ROOT_T *) pRoot; if(!pPMRoot || pPMRoot->init_magic != __PM_INIT_MAGIC) { PFATAL("Tried to use an invalid heap root pointer !\n"); return 0; } return pPMRoot->uPhysicalAddress;}void *pm_get_logical_base(void *pRoot){ PM_ALLOC_ROOT_T *pPMRoot = (PM_ALLOC_ROOT_T *) pRoot; if(!pPMRoot || pPMRoot->init_magic != __PM_INIT_MAGIC) { PFATAL("Tried to use an invalid heap root pointer !\n"); return NULL; } return pPMRoot->pLogicalAddress;}UINT pm_get_physical_total_size(void *pRoot){ PM_ALLOC_ROOT_T *pPMRoot = (PM_ALLOC_ROOT_T *) pRoot; if(!pPMRoot || pPMRoot->init_magic != __PM_INIT_MAGIC) { PFATAL("Tried to use an invalid heap root pointer !\n"); return 0; } return pPMRoot->uTotalUnits*__PM_ALLOC_UNIT;}// Only used during initialize and deinitializevoid * __pm_alloc_physical_init(UINT uPhysicalAddr, void *pLogicalAddr, UINT uSize, UINT uMaxHandles){ PM_ALLOC_ROOT_T *pPMRoot; PDEBUG(" Physical mem at 0x%8.8x , size 0x%8.8x\n", uPhysicalAddr, uSize); if(uMaxHandles < 1 || NULL == pLogicalAddr) { return NULL; } //ok, let's check if the input paramaters are ok if (uPhysicalAddr % __PM_ALLOC_UNIT ) // first, lets align these parameters { UINT uInc = __PM_ALLOC_UNIT - uPhysicalAddr % __PM_ALLOC_UNIT; if (uSize < uInc) // hi, remainning is too small return NULL; uPhysicalAddr += uInc; (BYTE *)pLogicalAddr += uInc; uSize -= uInc; } if (uSize < __PM_ALLOC_UNIT + os_tell_pool_buffer_size(uMaxHandles, sizeof(struct __MEM_HANDLE_T_STRUCT))) // we should request at least this size return NULL; if ((uPhysicalAddr + uSize) < uPhysicalAddr) // how can we wrap around ?! return NULL; pPMRoot = MALLOC(sizeof(PM_ALLOC_ROOT_T)); if(!pPMRoot) { return NULL; // hi, I cann't do this } pPMRoot->pLogicalAddress = pLogicalAddr; //ok, we are going to set up every thing else PML_INIT(); // init the sync lock // firstly, the pPMRoot pPMRoot->uPhysicalAddress = uPhysicalAddr; pPMRoot->uTotalMem = uSize; // remember the total size pPMRoot->uTotalUnits = (uSize - os_tell_pool_buffer_size(uMaxHandles, sizeof(struct __MEM_HANDLE_T_STRUCT))) / __PM_ALLOC_UNIT; pPMRoot->uFreeUnits = pPMRoot->uTotalUnits; // every block is free pPMRoot->npFreeList = 0; // the first block to do // and the initial huge block { PM_ALLOC_FREE_NODE_T *pNode = (PM_ALLOC_FREE_NODE_T *) pPMRoot->pLogicalAddress; pNode->npNext = -1; // no next pNode->npPrev = -1; // no prev pNode->npAddr = 0; // my addr pNode->uUnits = pPMRoot->uFreeUnits; INIT_OVERRUN_DET(pPMRoot, 0); } pPMRoot->uMaxHandles = uMaxHandles; // then, the handle table pPMRoot->pHandlePoolBuffer = (void *)(pPMRoot->pLogicalAddress + pPMRoot->uTotalUnits*__PM_ALLOC_UNIT); os_create_pool(&pPMRoot->handlePool, pPMRoot->pHandlePoolBuffer, uMaxHandles, sizeof(struct __MEM_HANDLE_T_STRUCT)); { UINT i; MEM_HANDLE_T pHandle; for(i=0; i<uMaxHandles; i++) { pHandle = os_walk_up_pool(&pPMRoot->handlePool, i); pHandle->pLogical = NULL; pHandle->uPhysical = 0; pHandle->uSize = 0; } } // ok, any other issues ?? pPMRoot->init_magic = __PM_INIT_MAGIC; return pPMRoot;}INT __pm_alloc_physical_deinit(void *pRoot){ PM_ALLOC_ROOT_T *pPMRoot = (PM_ALLOC_ROOT_T *) pRoot; if(!pPMRoot || pPMRoot->init_magic != __PM_INIT_MAGIC) { PFATAL("Tried to use an invalid heap root pointer !\n"); return 0; } if (0 == pPMRoot->uTotalUnits) { PDEBUG("DEINIT: Tries to deinit before successful init !\n"); return -1; // you are going to deallocate an non existing one } __pm_alloc_physical_heap_walk(pRoot); if (pPMRoot->uFreeUnits != pPMRoot->uTotalUnits) { int i; PDEBUG("DEINIT: Some allocations are still in use !\n"); // dump these in use handles for(i=0; i<pPMRoot->uMaxHandles; i++) { MEM_HANDLE_T pHandle = os_walk_up_pool(&pPMRoot->handlePool, i); if (pHandle->uSize > 0) // in use handle { PDEBUG(" Handle 0x%8.8x, l_addr=0x%8.8x, p_addr=0x%8.8x, size=0x%8.8x units\n", pHandle, pHandle->pLogical, pHandle->uPhysical, pHandle->uSize); } } } // and the lock PML_DEINIT(); FREE(pPMRoot); return 0;}void __pm_alloc_physical_heap_walk(void *pRoot){#ifdef __PM_ALLOC_DEBUG PM_ALLOC_FREE_NODE_T *pNode; INT npNode; UINT nodes, sum; PM_ALLOC_ROOT_T *pPMRoot = (PM_ALLOC_ROOT_T *) pRoot; if(!pPMRoot || pPMRoot->init_magic != __PM_INIT_MAGIC) { PFATAL("Tried to use an invalid heap root pointer !\n"); return; } //######################################################################## PML_ENTER(); PDEBUGE("\n\n++++++++++++++++ Heap Dump +++++++++++++++\n"); if(pPMRoot->npFreeList < 0) { PDEBUG("Heap empty\n"); goto __os_pm_heap_walk_out; } nodes = sum = 0; npNode = pPMRoot->npFreeList; PDEBUGE("Start Trace Free Space\n"); while(npNode >= 0) { pNode = __PM_GET_BLOCK_POINTER(npNode); PDEBUGE(" Node 0x%8.8x, Addr= 0x%8.8x, size=0x%8.8x, prev=0x%8.8x, next=0x%8.8x\n", npNode, pNode->npAddr, pNode->uUnits, pNode->npPrev, pNode->npNext); PDEBUGE(" P Addr= 0x%8.8x, L Addr=0x%8.8x\n", (UINT)npNode*__PM_ALLOC_UNIT + pPMRoot->uPhysicalAddress, (UINT)npNode*__PM_ALLOC_UNIT + pPMRoot->pLogicalAddress); OVERRUN_DET(pPMRoot, npNode); nodes ++; sum += pNode->uUnits; if(pNode->npNext >= 0 && npNode >= pNode->npNext) { PFATAL("Heap Corrupted !!!\n"); break; } npNode = pNode->npNext; // next one } PDEBUGE("Total nodes = %d, total size = %d. \n", nodes, sum); PDEBUGE("++++++++++++++++++++++++++++++++++++++++++\n\n"); __os_pm_heap_walk_out: PML_LEAVE(); //######################################################################## return;#endif}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -