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

📄 avm_allo.c

📁 udio and video memory module memory allocation features
💻 C
📖 第 1 页 / 共 5 页
字号:

                Err = AllocBlockNoSemaphore(&AllocBlockParams, (STAVMEM_BlockHandle_t *) &New_p);

                if (Err == ST_NO_ERROR)
                {
                    /* Free old block */
                    Err = FreeNoSemaphore(Partition_p, (STAVMEM_BlockHandle_t) Block_p);
                    /* Always success */

                    /* Block allocated: copy data if required */
                    if (ReAllocBlockParams_p->PreserveData)
                    {
/*                        STAVMEM_CopyBlock1D(PreserveAddr_p, New_p->AlignedStartAddr_p, PreserveSize);*/
                        (*(ReAllocBlockParams_p->PreserveDataFunction)) (PreserveAddr_p, New_p->AlignedStartAddr_p, PreserveSize);
#ifdef DEBUG_CODE
                    if ((*(U8 *) New_p->AlignedStartAddr_p) != PreserveProbe)
                    {
                        /* ErrorCase */
STTBX_Print(("****** PreserveData failed.\n"));
                        stavmem_BlockAndBip();
                    }
#endif
                    }

                    /* Re-allocated block is now the new one */
                    Block_p = New_p;
#ifdef DEBUG_CODE
                    if ((((U32) Block_p->AlignedStartAddr_p) - ((U32) Block_p->StartAddr_p) + Block_p->UserSize) > Block_p->Size)
                    {
                        /* ErrorCase */
                        stavmem_BlockAndBip();
                    }
#endif
                }
            }
        }
        else
        {
            /*  The requested size fits in the allocated block because of alignment of the size when allocation:
                It doesn't allow to reduce the size of the block, neither does it require enlargment.
                Block doesn't need to change... */
            Block_p->UserSize = ReAllocBlockParams_p->Size;
#ifdef DEBUG_CODE
STTBX_Print(("****** Re-allocate with just size changing.\n"));
            if ((((U32) Block_p->AlignedStartAddr_p) - ((U32) Block_p->StartAddr_p) + Block_p->UserSize) > Block_p->Size)
            {
                /* ErrorCase */
                stavmem_BlockAndBip();
            }
#endif
        }
    }

    /* Unmark forbidden zones now that allocation is done */
    UnMarkForbiddenRangesAndBorders(Partition_p);

#ifdef USE_SEMAPHORE
    /* Free the allocations locking semaphore */
    semaphore_signal(&(Partition_p->Device_p->LockAllocSemaphore));
#endif

    *BlockHandle_p = (STAVMEM_BlockHandle_t) Block_p;

    return(Err);
}



/*
------------------------------------------------------------------------------
Get the parameters of a memory block.
------------------------------------------------------------------------------
*/
ST_ErrorCode_t STAVMEM_GetBlockParams(STAVMEM_BlockHandle_t BlockHandle, STAVMEM_BlockParams_t *BlockParams_p)
{
    MemBlockDesc_t *Block_p;
    stavmem_Partition_t *Partition_p;
    ST_ErrorCode_t Err = ST_NO_ERROR;

    /* Exit if bad parameter */
    if (BlockParams_p == NULL)
    {
        return(ST_ERROR_BAD_PARAMETER);
    }

    /* Get pointer to the block */
    Block_p = (MemBlockDesc_t *) BlockHandle;

    /* Exit if block handle is invalid of if block alloc mode is impossible */
    if ((Block_p == STAVMEM_INVALID_BLOCK_HANDLE) ||    /* Handle invalid */
        ((Block_p->AllocMode != STAVMEM_ALLOC_MODE_TOP_BOTTOM) && ((Block_p->AllocMode != STAVMEM_ALLOC_MODE_BOTTOM_TOP))) || /* bad data */
        (!Block_p->IsUsed))                             /* Block is unused (may have been freed) */
    {
        /* Bad block handle or impossible alloc mode */
        return(STAVMEM_ERROR_INVALID_BLOCK_HANDLE);
    }

    /* Get pointer to partition the block belongs to */
    Partition_p = (stavmem_Partition_t *) Block_p->PartitionHandle;

    /* Exit if partition invalid: block should have been freed !
       This should not happen, but it is here for security */
    if (Partition_p->PartitionValidity != AVMEM_VALID_PARTITION)
    {
        return(STAVMEM_ERROR_INVALID_BLOCK_HANDLE);
    }

    /* Output required parameters of the block */
    BlockParams_p->Size = Block_p->UserSize;
    BlockParams_p->StartAddr_p = Block_p->AlignedStartAddr_p;
    BlockParams_p->AllocMode = Block_p->AllocMode;
    BlockParams_p->Alignment = Block_p->Alignment;

    return(Err);
}



/*
--------------------------------------------------------------------------------
Get pointer to memory block start address
--------------------------------------------------------------------------------
*/
ST_ErrorCode_t STAVMEM_GetBlockAddress(STAVMEM_BlockHandle_t BlockHandle, void **Address_p)
{
    MemBlockDesc_t *Block_p;
    stavmem_Partition_t *Partition_p;
    ST_ErrorCode_t Err = ST_NO_ERROR;

    /* Exit if bad parameter */
    if (Address_p == NULL)
    {
        return(ST_ERROR_BAD_PARAMETER);
    }

    /* Get pointer to the block */
    Block_p = (MemBlockDesc_t *) BlockHandle;

    /* Exit if block handle is invalid of if block alloc mode is impossible */
    if ((Block_p == STAVMEM_INVALID_BLOCK_HANDLE) ||    /* Handle invalid */
        ((Block_p->AllocMode != STAVMEM_ALLOC_MODE_TOP_BOTTOM) && ((Block_p->AllocMode != STAVMEM_ALLOC_MODE_BOTTOM_TOP))) || /* bad data */
        (!Block_p->IsUsed))                             /* Block is unused (may have been freed) */
    {
        /* Bad block handle or impossible alloc mode */
        return(STAVMEM_ERROR_INVALID_BLOCK_HANDLE);
    }

    /* Get pointer to partition the block belongs to */
    Partition_p = (stavmem_Partition_t *) Block_p->PartitionHandle;

    /* Exit if partition invalid: block should have been freed !
       This should not happen, but it is here for security */
    if (Partition_p->PartitionValidity != AVMEM_VALID_PARTITION)
    {
        return(STAVMEM_ERROR_INVALID_BLOCK_HANDLE);
    }

    /* Output useful address of block: aligned start address */
    *Address_p = Block_p->AlignedStartAddr_p;

    return(Err);
}



/*******************************************************************************
Name        : stavmem_UnReserveBlockNoSemaphore
Description : Un-reserve block among list of reserved/unused blocks
              Used at initialisation only
Parameters  : pointer on device and pointer to sub-space
Assumptions : Pointers are not NULL.
              Used blocks are reserved ones only.
Limitations :
Returns     : ST_NO_ERROR if success,
              STAVMEM_ERROR_MAX_BLOCKS if lack of blocks (should never happen if alloc in init is well done)
*******************************************************************************/
ST_ErrorCode_t stavmem_UnReserveBlockNoSemaphore(stavmem_Device_t *Device_p, STAVMEM_MemoryRange_t *SubSpace_p)
{
    MemBlockDesc_t *Block_p = NULL, *UnReserved_p = NULL, *Above_p = NULL;
    U32 SizeDifference = 0;
    void *BlockStart_p = 0, *BlockStop_p = 0;

    /* Parse all reserved blocks to unreserve the one overlaping the given sub-space */
    Block_p = Device_p->SpaceVeryBottomBlock_p;
    while (Block_p != NULL)
	{
        if (Block_p->IsUsed)
        {
            /* This block is reserved: check if it overlaps sub-space to unreserve */
            BlockStart_p = Block_p->StartAddr_p;
            BlockStop_p  = (void *) (((U32) BlockStart_p) + Block_p->Size - 1);

            /* There's overlap if reserved block starts before end of the sub-space
               and stops after the begining of sub-space */
            if ((((U32) BlockStart_p) <= ((U32) SubSpace_p->StopAddr_p)) && (((U32) BlockStop_p) >= ((U32) SubSpace_p->StartAddr_p)))
            {
                /* reserved block overlaps part of the sub-space to unreserve */
                if (((U32) BlockStart_p) < ((U32) SubSpace_p->StartAddr_p))
                {
                    /* Reserved block starts before start of sub-space */
                    if (((U32) BlockStop_p) <= ((U32) SubSpace_p->StopAddr_p))
                    {
                        /* Reserved block stops inside sub-space */
                        SizeDifference = ((U32) BlockStop_p) + 1 - ((U32) SubSpace_p->StartAddr_p);

                        if (Block_p->BlockAbove_p != NULL)
                        {
                            /* There's a block above, it can only be an unreserved one: enlarge it */
                            Block_p->BlockAbove_p->StartAddr_p = (void *) (((U32) Block_p->BlockAbove_p->StartAddr_p) - SizeDifference);
                            Block_p->BlockAbove_p->Size += SizeDifference;
                        }
                        else
                        {
                            /* There's no block above: create a block of unused memory and unreserve it */
                            /* Allocate block structure */
                            UnReserved_p = AllocBlockDescriptor(&(Device_p->TopOfSpaceFreeBlocksList_p));
                            if (UnReserved_p == NULL)
                            {
                                /* Failed to allocate new block structure */
                                return(STAVMEM_ERROR_MAX_BLOCKS);
                            }

                            /* Block structure allocation successful */
                            /* Insert new block above block in space blocks list */
                            InsertBlockAboveBlock(&(Device_p->SpaceVeryTopBlock_p), UnReserved_p, Block_p);

                            /* Setup new block as an unused block*/
                            UnReserved_p->StartAddr_p = SubSpace_p->StartAddr_p;
                            UnReserved_p->Size = SizeDifference;
                            UnReserved_p->IsUsed = FALSE;
                        }

                        /* Reduce size of reserved block */
                        Block_p->Size -= SizeDifference;
                    }
                    else
                    {
                        /* Reserved block stops after stop of sub-space */
/*                        SizeDifference = ((U32) BlockStop_p) + 1 - ((U32) SubSpace_p->StartAddr_p);*/
                        /* Create 2 new blocks: one to unreserve and one for the rest of reserved */
                        /* Allocate block structure */
                        UnReserved_p = AllocBlockDescriptor(&(Device_p->TopOfSpaceFreeBlocksList_p));
                        if (UnReserved_p == NULL)
                        {
                            /* Failed to allocate new block structure */
                            return(STAVMEM_ERROR_MAX_BLOCKS);
                        }
                        else
                        {
                            /* Block structure allocation successful: Allocate 2nd block structure */
                            Above_p = AllocBlockDescriptor(&(Device_p->TopOfSpaceFreeBlocksList_p));
                            if (Above_p == NULL)
                            {
                                /* Failed to allocate new block structure */
                                return(STAVMEM_ERROR_MAX_BLOCKS);
                            }
                        }

                        /* Insert new block to unreserve above block in space blocks list */
                        InsertBlockAboveBlock(&(Device_p->SpaceVeryTopBlock_p), UnReserved_p, Block_p);

                        /* Setup new block as unused and unreserve it */
                        UnReserved_p->StartAddr_p = SubSpace_p->StartAddr_p;
                        UnReserved_p->Size = ((U32) SubSpace_p->StopAddr_p) + 1 - ((U32) SubSpace_p->StartAddr_p);
                        UnReserved_p->IsUsed = FALSE;

                        /* Insert new block above unreserved block in space blocks list */
                        InsertBlockAboveBlock(&(Device_p->SpaceVeryTopBlock_p), Above_p, UnReserved_p);

                        /* Setup block above as reserved */
                        Above_p->Alignment = 1;
                        Above_p->StartAddr_p = (void *) (((U32) SubSpace_p->StopAddr_p) + 1);
                        Above_p->AlignedStartAddr_p = Above_p->StartAddr_p;
                        Above_p->Size = ((U32) BlockStop_p) + 1 - ((U32) Above_p->StartAddr_p);
                        Above_p->UserSize = Above_p->Size;
                        Above_p->AllocMode = STAVMEM_ALLOC_MODE_RESERVED;
                        Above_p->IsUsed = TRUE;

                        /* Merge block above Above_p if it is also reserved */
                        if ((Above_p->BlockAbove_p != NULL) && (Above_p->BlockAbove_p->IsUsed))
                        {
                            Above_p->Size += Above_p->BlockAbove_p->Size;
                            Above_p = Above_p->BlockAbove_p;

                            /* Remove block from space list of blocks */
                            RemoveBlock(&(Device_p->SpaceVeryTopBlock_p), &(Device_p->SpaceVeryBottomBlock_p), Above_p);

                            /* Free off block structure */
                            FreeBlockDescriptor(&(Device_p->TopOfSpaceFreeBlocksList_p), Above_p);
                        }

                        /* Reduce size of reserved block */
                        Block_p->Size = ((U32) UnReserved_p->StartAddr_p) - ((U32) Block_p->StartAddr_p);
                    }
                }
                else
                {
                    /* Reserved block starts inside sub-space */
                    if (((U32) BlockStop_p) <= ((U32) SubSpace_p->StopAddr_p))
                    {
                        /* Reserved block stops inside sub-space: whole block must be un-reserved */
                        Block_p->IsUsed = FALSE;

                        Above_p = Block_p->BlockAbove_p;
                        /* Eventually merge with below and above unreserved blocks */
                        if (Above_p != NULL)
                        {
                            /* Merge the above block (which can only be unused) into the current unused memory block */
                            Block_p->Size += Above_p->Size;

                            /* Remove block from space list of blocks */
                            RemoveBlock(&(Device_p->SpaceVeryTopBlock_p), &(Device_p->SpaceVeryBottomBlock_p), Above_p);

                            /* Free off block structure */
                            FreeBlockDescriptor(&(Device_p->TopOfSpaceFreeBlocksList_p), Above_p);
                        }

        

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -