⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pm-alloc.c

📁 IBM source for pallas/vulcan/vesta
💻 C
📖 第 1 页 / 共 2 页
字号:
    }    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 + -