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

📄 avm_allo.c

📁 udio and video memory module memory allocation features
💻 C
📖 第 1 页 / 共 5 页
字号:
{
    MemBlockDesc_t *Block_p, *New_p = NULL, *Bot_p = NULL, *Top_p = NULL;
    U32 BlockAlignedSize, ReAllocAlignedSize, AlignedSizeDifference, AddrAlignedSizeDifference;
    U32 AligningMask, SizeAligningMask;
    U32 Tmp;
#ifdef DEBUG_CODE
    U32 ChangedSize;
    void *ChangedStart;
    void *BlockAddrBefore;
    U32 BlockSizeBefore, BlockUserSizeBefore, BotSizeBefore;
    U8 PreserveProbe;
#endif
    BOOL EnlargeBelowForbidden = FALSE;
    void *PreserveAddr_p;
    U32 PreserveSize;
    STAVMEM_AllocBlockParams_t AllocBlockParams;
    stavmem_Partition_t *Partition_p;
    ST_ErrorCode_t Err = ST_NO_ERROR;

    /* Exit if bad parameter */
    if ((BlockHandle_p == NULL) ||
        (ReAllocBlockParams_p == NULL) ||
        ((ReAllocBlockParams_p->NumberOfForbiddenRanges > 0) && (ReAllocBlockParams_p->ForbiddenRangeArray_p == NULL)) ||
        ((ReAllocBlockParams_p->NumberOfForbiddenBorders > 0) && (ReAllocBlockParams_p->ForbiddenBorderArray_p == NULL)))
    {
        return(ST_ERROR_BAD_PARAMETER);
    }

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

    /* Exit if the partition is not valid */
    if (Partition_p->PartitionValidity != AVMEM_VALID_PARTITION)
    {
        return(STAVMEM_ERROR_INVALID_PARTITION_HANDLE);
    }

    /* Exit if bad parameter */
    if ((ReAllocBlockParams_p->NumberOfForbiddenRanges > Partition_p->Device_p->MaxForbiddenRanges) ||
        (ReAllocBlockParams_p->NumberOfForbiddenBorders > Partition_p->Device_p->MaxForbiddenBorders))
    {
        return(ST_ERROR_BAD_PARAMETER);
    }

    /* Exit if block handle is invalid */
    if ((*BlockHandle_p == STAVMEM_INVALID_BLOCK_HANDLE) || (!stavmem_BlockHandleBelongsToSpace(*BlockHandle_p, *(Partition_p->Device_p))))
    {
        /* Bad block handle */
        return(STAVMEM_ERROR_INVALID_BLOCK_HANDLE);
    }

    /* Setting pointer to block descriptor */
    Block_p = (MemBlockDesc_t *) *BlockHandle_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

    /* Exit if block is crossing any specified forbidden zone */
    if (IsInForbiddenRangeOrBorder(Block_p->StartAddr_p, (void *) (((U32) Block_p->StartAddr_p) + Block_p->Size - 1),
           ReAllocBlockParams_p->NumberOfForbiddenRanges, ReAllocBlockParams_p->ForbiddenRangeArray_p,
           ReAllocBlockParams_p->NumberOfForbiddenBorders, ReAllocBlockParams_p->ForbiddenBorderArray_p))
    {
        return(STAVMEM_ERROR_BLOCK_IN_FORBIDDEN_ZONE);
    }

    /* Exit if block is not in partition */
    if ((U32) (Block_p->PartitionHandle) != (U32) (Partition_p))
    {
        return(STAVMEM_ERROR_INVALID_PARTITION_HANDLE);
    }

    /* If first address of the block is a forbidden border, cannot cross it */
    Tmp = 0;
    while ((!EnlargeBelowForbidden) && (Tmp < ReAllocBlockParams_p->NumberOfForbiddenBorders))
    {
        /* Test if any forbidden border is the first address of the block. */
        if (((U32) ReAllocBlockParams_p->ForbiddenBorderArray_p[Tmp]) == ((U32) Block_p->StartAddr_p))
        {
            EnlargeBelowForbidden = TRUE;
        }
        Tmp++;
    }

#ifdef USE_SEMAPHORE
    /* Wait for the allocations locking semaphore to be free */
    semaphore_wait(&(Partition_p->Device_p->LockAllocSemaphore));
#endif

    /* Mark forbidden zones to disable allocation on these zones */
    Err = MarkForbiddenRangesAndBorders(Partition_p,
            ReAllocBlockParams_p->NumberOfForbiddenRanges, ReAllocBlockParams_p->ForbiddenRangeArray_p,
            ReAllocBlockParams_p->NumberOfForbiddenBorders, ReAllocBlockParams_p->ForbiddenBorderArray_p);

    /* Process allocation if no errors in forbidden zones marking */
    if (Err == ST_NO_ERROR)
    {
        /* Initialise variables */
        BlockAlignedSize = Block_p->Size - (((U32) Block_p->AlignedStartAddr_p) - ((U32) Block_p->StartAddr_p));
        PreserveAddr_p = Block_p->AlignedStartAddr_p;
        PreserveSize = Block_p->UserSize;
#ifdef DEBUG_CODE
        PreserveProbe = *((U8 *) PreserveAddr_p);
#endif
        AligningMask = Block_p->Alignment - 1;

        /* Adjust the size so the end address will be aligned */
        /* Consequence: alloc 5 byte aligned on 8 will alloc 8 bytes ! */
        if (AligningMask <= MAX_SIZE_ALIGNING_MASK)
        {
            SizeAligningMask = AligningMask;
        }
        else
        {
           SizeAligningMask = MAX_SIZE_ALIGNING_MASK;
        }
        ReAllocAlignedSize = (ReAllocBlockParams_p->Size + SizeAligningMask) & ~SizeAligningMask;

        if (ReAllocAlignedSize < Block_p->UserSize)
        {
            /* The requested size is smaller and allows to reduce current block size */
            AlignedSizeDifference = BlockAlignedSize - ReAllocAlignedSize;
            AddrAlignedSizeDifference = (AlignedSizeDifference + AligningMask) & ~AligningMask;

            if ((Block_p->BlockAbove_p != NULL) && (!Block_p->BlockAbove_p->IsUsed))
            {
                /* The block above is unused, so give it some more memory */
                Block_p->Size     -= AlignedSizeDifference;
                Block_p->UserSize = ReAllocBlockParams_p->Size;
                Block_p->BlockAbove_p->Size += AlignedSizeDifference;
                Block_p->BlockAbove_p->StartAddr_p = (void *) (((U32) Block_p->BlockAbove_p->StartAddr_p) - AlignedSizeDifference);
#ifdef DEBUG_CODE
STTBX_Print(("****** Re-allocate with reduction on top.\n"));
                if ((((U32) Block_p->AlignedStartAddr_p) - ((U32) Block_p->StartAddr_p) + Block_p->UserSize) > Block_p->Size)
                {
                    /* ErrorCase */
                    stavmem_BlockAndBip();
                }
#endif

                /* Start address is unchanged: data is preserved, no need to copy it */
            }
            else if ((Block_p->BlockBelow_p != NULL) && (!Block_p->BlockBelow_p->IsUsed) &&
                     ((((U32) Block_p->AlignedStartAddr_p) + AddrAlignedSizeDifference + ReAllocBlockParams_p->Size) <= (((U32) Block_p->StartAddr_p) + Block_p->Size)))
            {
                /* The block below is unused, so give it some more memory */
                Block_p->Size     -= AddrAlignedSizeDifference;
                Block_p->UserSize = ReAllocBlockParams_p->Size;
                Block_p->StartAddr_p        = (void *) (((U32) Block_p->StartAddr_p) + AddrAlignedSizeDifference);
                Block_p->AlignedStartAddr_p = (void *) (((U32) Block_p->AlignedStartAddr_p) + AddrAlignedSizeDifference);
#ifdef DEBUG_CODE
STTBX_Print(("****** Re-allocate with reduction on bottom.\n"));
                if ((((U32) Block_p->AlignedStartAddr_p) - ((U32) Block_p->StartAddr_p) + Block_p->UserSize) > Block_p->Size)
                {
                    /* ErrorCase */
                    stavmem_BlockAndBip();
                }
#endif

                Block_p->BlockBelow_p->Size += AddrAlignedSizeDifference;

                /* Now copy data if required */
                if (ReAllocBlockParams_p->PreserveData)
                {
/*                    STAVMEM_CopyBlock1D(PreserveAddr_p, Block_p->AlignedStartAddr_p, Block_p->UserSize);*/
                    (*(ReAllocBlockParams_p->PreserveDataFunction)) (PreserveAddr_p, Block_p->AlignedStartAddr_p, Block_p->UserSize);
#ifdef DEBUG_CODE
                    if ((*(U8 *) Block_p->AlignedStartAddr_p) != PreserveProbe)
                    {
                        /* ErrorCase */
STTBX_Print(("****** PreserveData failed.\n"));
                        stavmem_BlockAndBip();
                    }
#endif
                }
            }
            else
            {
                /* The blocks below and above are used or is the end of the list,
                   so create a new unused block for the memory left by the re-allocated block.
                   Allocate block structure */
                New_p = AllocBlockDescriptor(&(Partition_p->Device_p->TopOfSpaceFreeBlocksList_p));

                if (New_p == NULL)
                {
                    /* Failed to allocate new block structure */
                    Err = STAVMEM_ERROR_MAX_BLOCKS;
                }
                else
                {
                    /* Block structure allocation successful */
                    /* Reduce current block size */
                    Block_p->Size     -= AlignedSizeDifference;
                    Block_p->UserSize = ReAllocBlockParams_p->Size;

                    /* Setup new block */
                    New_p->StartAddr_p = (void *) (((U32) Block_p->StartAddr_p) + Block_p->Size);
                    New_p->Size        = AlignedSizeDifference;
                    New_p->IsUsed      = FALSE;

                    /* Insert new unused block above block in partition blocks list */
                    InsertBlockAboveBlock(&(Partition_p->PartitionVeryTopBlock_p), New_p, Block_p);

                    /* Start address is unchanged: data is preserved, no need to copy it */
                }
#ifdef DEBUG_CODE
STTBX_Print(("****** Re-allocate with reduction on top and free block creation.\n"));
                if ((((U32) Block_p->AlignedStartAddr_p) - ((U32) Block_p->StartAddr_p) + Block_p->UserSize) > Block_p->Size)
                {
                    /* ErrorCase */
                    stavmem_BlockAndBip();
                }
#endif
            }
        }
        else if (ReAllocAlignedSize > BlockAlignedSize)
        {
            /* The requested size is larger and requires enlargement of block or re-allocattion */
            AlignedSizeDifference = ReAllocAlignedSize - BlockAlignedSize;
            AddrAlignedSizeDifference = (AlignedSizeDifference + AligningMask) & ~AligningMask;

            /* Consider blocks below and above */
            Bot_p = Block_p->BlockBelow_p;
            Top_p = Block_p->BlockAbove_p;

            if ((Top_p != NULL) && (!Top_p->IsUsed) && (Top_p->Size >= AlignedSizeDifference))
            {
                /* Block above is unused and large enough: use part of it to enlarge block */
                Block_p->Size     += AlignedSizeDifference;
                Block_p->UserSize = ReAllocBlockParams_p->Size;
#ifdef DEBUG_CODE
STTBX_Print(("****** Re-allocate with enlargment on top.\n"));
                if ((((U32) Block_p->AlignedStartAddr_p) - ((U32) Block_p->StartAddr_p) + Block_p->UserSize) > Block_p->Size)
                {
                    /* ErrorCase */
                    stavmem_BlockAndBip();
                }
#endif

                Top_p->StartAddr_p = (void *) (((U32) Top_p->StartAddr_p) + AlignedSizeDifference);
                Top_p->Size        -= AlignedSizeDifference;
                if (Top_p->Size == 0)
                {
                    /* The top unused block is now of zero size so remove it from partition list of blocks */
                    RemoveBlock(&(Partition_p->PartitionVeryTopBlock_p), &(Partition_p->PartitionVeryBottomBlock_p), Top_p);

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

                /* Start address is unchanged: data is preserved, no need to copy it */
            }
            else if ((!EnlargeBelowForbidden) && (Bot_p != NULL) && (!Bot_p->IsUsed) && /* can enlarge below and block below is free and */
                     ((((U32) Block_p->AlignedStartAddr_p) - AddrAlignedSizeDifference) >= ((U32) Bot_p->StartAddr_p)))
            {
                /* Block below is unused: use part of it. */
#ifdef DEBUG_CODE
                ChangedSize = (AddrAlignedSizeDifference - (((U32) Block_p->AlignedStartAddr_p) - ((U32) Block_p->StartAddr_p)));
                ChangedStart = Block_p->StartAddr_p;
                BlockAddrBefore = Block_p->AlignedStartAddr_p;
                BlockSizeBefore = Block_p->Size;
                BlockUserSizeBefore = Block_p->UserSize;
                BotSizeBefore = Bot_p->Size;
#endif
                Bot_p->Size       -= (AddrAlignedSizeDifference - (((U32) Block_p->AlignedStartAddr_p) - ((U32) Block_p->StartAddr_p)));
                Block_p->Size     += (AddrAlignedSizeDifference - (((U32) Block_p->AlignedStartAddr_p) - ((U32) Block_p->StartAddr_p)));
                Block_p->UserSize = ReAllocBlockParams_p->Size;
                Block_p->StartAddr_p        = (void *) (((U32) Bot_p->StartAddr_p) + Bot_p->Size);
                Block_p->AlignedStartAddr_p = (void *) (((U32) Block_p->AlignedStartAddr_p) - AddrAlignedSizeDifference);
#ifdef DEBUG_CODE
STTBX_Print(("****** Re-allocate with enlargment on bottom.\n"));
                if ((((U32) Block_p->AlignedStartAddr_p) - ((U32) Block_p->StartAddr_p) + Block_p->UserSize) > Block_p->Size)
                {
                    /* ErrorCase */
                    stavmem_BlockAndBip();
                }
#endif

                if (Bot_p->Size == 0)
                {
                    /* The below unused block is now of zero size so remove it from partition list of blocks */
                    RemoveBlock(&(Partition_p->PartitionVeryTopBlock_p), &(Partition_p->PartitionVeryBottomBlock_p), Bot_p);

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

                /* Now copy data if required */
                if (ReAllocBlockParams_p->PreserveData)
                {
/*                    STAVMEM_CopyBlock1D(PreserveAddr_p, Block_p->AlignedStartAddr_p, PreserveSize);*/
                    (*(ReAllocBlockParams_p->PreserveDataFunction)) (PreserveAddr_p, Block_p->AlignedStartAddr_p, PreserveSize);
#ifdef DEBUG_CODE
                    if ((*(U8 *) Block_p->AlignedStartAddr_p) != PreserveProbe)
                    {
                        /* ErrorCase */
STTBX_Print(("****** PreserveData failed.\n"));
                        stavmem_BlockAndBip();
                    }
#endif
                }
            }
            else
            {
#ifdef DEBUG_CODE
STTBX_Print(("****** Re-allocate with enlargment by Allocate and Free.\n"));
#endif
                /* Need more space but blocks above and below are not large
                   enough: re-allocate block somewhere else and free the current place */
                AllocBlockParams.Size      = ReAllocBlockParams_p->Size;
                AllocBlockParams.Alignment = Block_p->Alignment;
                AllocBlockParams.AllocMode  = Block_p->AllocMode;
                AllocBlockParams.PartitionHandle  = Block_p->PartitionHandle;
                AllocBlockParams.NumberOfForbiddenRanges = ReAllocBlockParams_p->NumberOfForbiddenRanges;
                AllocBlockParams.ForbiddenRangeArray_p = ReAllocBlockParams_p->ForbiddenRangeArray_p;
                AllocBlockParams.NumberOfForbiddenBorders = ReAllocBlockParams_p->NumberOfForbiddenBorders;
                AllocBlockParams.ForbiddenBorderArray_p = ReAllocBlockParams_p->ForbiddenBorderArray_p;

⌨️ 快捷键说明

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