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

📄 avm_allo.c

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

    /* Get pointer to partition the block belongs to */
    Partition_p = (stavmem_Partition_t *) AllocBlockParams_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 ((AllocBlockParams_p->NumberOfForbiddenRanges > Partition_p->Device_p->MaxForbiddenRanges) ||
        (AllocBlockParams_p->NumberOfForbiddenBorders > Partition_p->Device_p->MaxForbiddenBorders))
    {
        return(ST_ERROR_BAD_PARAMETER);
    }

    /* Check counter of user-used blocks: if MaxUsedBlocks reached, cannot allocate more */
    if (Partition_p->Device_p->CurrentlyUsedBlocks >= Partition_p->Device_p->MaxUsedBlocks)
    {
        /* Not allowed to allocate more block */
        return(STAVMEM_ERROR_MAX_BLOCKS);
    }

#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,
            AllocBlockParams_p->NumberOfForbiddenRanges, AllocBlockParams_p->ForbiddenRangeArray_p,
            AllocBlockParams_p->NumberOfForbiddenBorders, AllocBlockParams_p->ForbiddenBorderArray_p);

    /* Process allocation if no errors in forbidden zones marking */
    if (Err == ST_NO_ERROR)
    {
        Err = AllocBlockNoSemaphore(AllocBlockParams_p, BlockHandle_p);
    }

    /* 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

    return(Err);
}



/*******************************************************************************
Name        : AllocBlockNoSemaphore
Description : Internal function to allocate block, not semaphore protected
              Used in STAVMEM_AllocBlock() and STAVMEM_ReAllocBlock()
Parameters  : parameters pointers not NULL
Assumptions :
Limitations :
Returns     : ST_NO_ERROR if success, STAVMEM_ERROR_PARTITION_FULL or
                                      STAVMEM_ERROR_MAX_BLOCKS otherwise
*******************************************************************************/
ST_ErrorCode_t AllocBlockNoSemaphore(const STAVMEM_AllocBlockParams_t *AllocBlockParams_p, STAVMEM_BlockHandle_t *BlockHandle_p)
{
    MemBlockDesc_t *Cur_p, *New_p = NULL;
    void *CurrentStartAddr_p, *CurrentAlignedStartAddr_p;
    U32 TotalSize, AlignedSize;
    U32 Alignment = AllocBlockParams_p->Alignment;
    U32 AligningMask, SizeAligningMask;
    stavmem_Partition_t *Partition_p;
    ST_ErrorCode_t Err = ST_NO_ERROR;

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

    /* Initialise variables */
    RoundUpAlignment(&Alignment);
    AligningMask = 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;
    }
    AlignedSize = (AllocBlockParams_p->Size + SizeAligningMask) & ~SizeAligningMask;

    if (AllocBlockParams_p->AllocMode == STAVMEM_ALLOC_MODE_TOP_BOTTOM)
    {
        /* Search for an unused memory block of size greater than "size" */
        Cur_p = Partition_p->PartitionVeryTopBlock_p;
        while (Cur_p != NULL)
        {
#ifdef DO_NOT_ALLOW_AREAS_CROSSING
            /* Don't allow the areas to cross each other */
            if (Cur_p->IsUsed && (Cur_p->AllocMode != STAVMEM_ALLOC_MODE_TOP_BOTTOM) && (Cur_p->AllocMode != STAVMEM_ALLOC_MODE_RESERVED) && (Cur_p->AllocMode != STAVMEM_ALLOC_MODE_FORBIDDEN))
            {
                /* Another area is reached: end search unsucessfully */
                Cur_p = NULL;
                break;
            }
#endif

            /* Check for a large enough unused block (size 0 means full range so it is enough for sure) */
/*                if ((!Cur_p->IsUsed) && (Cur_p->Size >= AlignedSize))*/
            if ((!Cur_p->IsUsed) && ((Cur_p->Size >= AlignedSize) || (Cur_p->Size == 0)))
            {
                /* Block is large enough before alignment, ensure it is still
                    large enough with alignment constraints */
                CurrentStartAddr_p = (void *) (((U32) Cur_p->StartAddr_p) + Cur_p->Size - AlignedSize);
                CurrentAlignedStartAddr_p = (void *) (((U32) CurrentStartAddr_p) & ~AligningMask);
                TotalSize = ((U32) CurrentStartAddr_p) - ((U32) CurrentAlignedStartAddr_p) + AlignedSize;

                /* If the unused memory block is large enough, exit search */
/*                    if (Cur_p->Size >= TotalSize)*/
                if ((Cur_p->Size >= TotalSize) || (Cur_p->Size == 0))
                {
#ifdef DEBUG_CODE
                    if (TotalSize < AllocBlockParams_p->Size)
                    {
                        /* Error case */
                        stavmem_BlockAndBip();
                    }
#endif
                    /* Found a unused block matching the requirements ! */
                    break;
                }
            }

            /* Unsuccessful search: check next block in the partition list */
            Cur_p = Cur_p->BlockBelow_p;
        }

        /* Search is finished: allocate in unused memory block if found */
        if (Cur_p != NULL)
        {
            /* Allocate block structure */
            New_p = AllocBlockDescriptor(&(Partition_p->Device_p->TopOfSpaceFreeBlocksList_p));

            if (New_p != NULL)
            {
                /* Block structure allocation successful
                    Insert new block above current block in partition blocks list */
                InsertBlockAboveBlock(&(Partition_p->PartitionVeryTopBlock_p), New_p, Cur_p);

                /* Setup new block  */
                New_p->AllocMode   = AllocBlockParams_p->AllocMode; /* STAVMEM_ALLOC_MODE_BOTTOM_TOP */
                New_p->StartAddr_p = CurrentAlignedStartAddr_p;
                New_p->Size        = TotalSize;
                New_p->Alignment   = Alignment;
                New_p->AlignedStartAddr_p = CurrentAlignedStartAddr_p;
                New_p->UserSize    = AllocBlockParams_p->Size;
                New_p->IsUsed      = TRUE;
                New_p->PartitionHandle = (STAVMEM_PartitionHandle_t) Partition_p;
#ifdef DEBUG_CODE
    if ((((U32) New_p->AlignedStartAddr_p) - ((U32) New_p->StartAddr_p) + New_p->UserSize) > New_p->Size)
    {
        /* ErrorCase */
        stavmem_BlockAndBip();
    }
#endif

                /* Update counter to respect MaxUsedBlocks */
                Partition_p->Device_p->CurrentlyUsedBlocks++;

                /* Reduce size of unused block and remove it from partition if it is of size 0 */
                Cur_p->Size -= TotalSize;
                if (Cur_p->Size == 0)
                {
                    /* Remove block from partition list of blocks */
                    RemoveBlock(&(Partition_p->PartitionVeryTopBlock_p), &(Partition_p->PartitionVeryBottomBlock_p), Cur_p);

                    /* Free off block structure */
                    FreeBlockDescriptor(&(Partition_p->Device_p->TopOfSpaceFreeBlocksList_p), Cur_p);
                }
            }
            else
            {
                /* Failed to allocate new block structure */
                Err = STAVMEM_ERROR_MAX_BLOCKS;
            }
        }
        else
        {
            /* Could not find a large enough memory block matching the allocation requirements */
            Err = STAVMEM_ERROR_PARTITION_FULL;
        }
    }
    else /*if (AllocBlockParams_p->AllocMode == STAVMEM_ALLOC_MODE_BOTTOM_TOP)*/
    {
        /* Search for an unused memory block of size greater than "size" */
        Cur_p = Partition_p->PartitionVeryBottomBlock_p;
        while (Cur_p != NULL)
        {
#ifdef DO_NOT_ALLOW_AREAS_CROSSING
            /* Don't allow the "Heap" to overflow the "Stack" */
            if (Cur_p->IsUsed && Cur_p->AllocMode != STAVMEM_ALLOC_MODE_BOTTOM_TOP && (Cur_p->AllocMode != STAVMEM_ALLOC_MODE_RESERVED)&& (Cur_p->AllocMode != STAVMEM_ALLOC_MODE_FORBIDDEN))
            {
                /* Another area is reached: end search unsucessfully */
                Cur_p = NULL;
                break;
            }
#endif

            /* Check for a large enough unused block (size 0 means full range so it is enough for sure) */
/*                if ((!Cur_p->IsUsed) && (Cur_p->Size >= AlignedSize))*/
            if ((!Cur_p->IsUsed) && ((Cur_p->Size >= AlignedSize) || (Cur_p->Size == 0)))
            {
                /* Block is large enough before alignment, ensure it is still
                    large enough with alignment constraints */
                CurrentAlignedStartAddr_p = (void *) ((((U32) Cur_p->StartAddr_p) + AligningMask) & ~AligningMask);
                TotalSize = ((U32) CurrentAlignedStartAddr_p) - ((U32) Cur_p->StartAddr_p) + AlignedSize;

                /* If the unused memory block is large enough, exit search */
/*                    if (Cur_p->Size >= TotalSize)*/
                if ((Cur_p->Size >= TotalSize) || (Cur_p->Size == 0))
                {
#ifdef DEBUG_CODE
                    if (TotalSize < AllocBlockParams_p->Size)
                    {
                        /* Error case */
                        stavmem_BlockAndBip();
                    }
#endif
                    /* Found a unused block matching the requirements ! */
                    break;
                }
            }

            /* Unsuccessful search: check next block in the partition list */
            Cur_p = Cur_p->BlockAbove_p;
        }

        /* Search is finished: allocate in unused memory block if found */
        if (Cur_p != NULL)
        {
            /* Allocate block structure */
            New_p = AllocBlockDescriptor(&(Partition_p->Device_p->TopOfSpaceFreeBlocksList_p));

            if (New_p != NULL)
            {
                /* Block structure allocation successful
                    Insert new block below current block in partition blocks list */
                InsertBlockBelowBlock(&(Partition_p->PartitionVeryBottomBlock_p), New_p, Cur_p);

                /* Setup new block */
                New_p->AllocMode   = AllocBlockParams_p->AllocMode; /* STAVMEM_ALLOC_MODE_TOP_BOTTOM */
                New_p->StartAddr_p  = Cur_p->StartAddr_p;
                New_p->Size       = TotalSize;
                New_p->Alignment  = Alignment;
                New_p->AlignedStartAddr_p = CurrentAlignedStartAddr_p;
                New_p->UserSize   = AllocBlockParams_p->Size;
                New_p->IsUsed     = TRUE;
                New_p->PartitionHandle = (STAVMEM_PartitionHandle_t) Partition_p;
#ifdef DEBUG_CODE
    if ((((U32) New_p->AlignedStartAddr_p) - ((U32) New_p->StartAddr_p) + New_p->UserSize) > New_p->Size)
    {
        /* ErrorCase */
        stavmem_BlockAndBip();
    }
#endif

                /* Update counter to respect MaxUsedBlocks */
                Partition_p->Device_p->CurrentlyUsedBlocks++;

                /* Update unused block start address and size, and remove it from partition if it is of size 0 */
                Cur_p->StartAddr_p = (void *) (((U32) Cur_p->StartAddr_p) + TotalSize);
                Cur_p->Size -= TotalSize;
                if (Cur_p->Size == 0)
                {
                    /* Remove block from partition list of blocks */
                    RemoveBlock(&(Partition_p->PartitionVeryTopBlock_p), &(Partition_p->PartitionVeryBottomBlock_p), Cur_p);

                    /* Free off block structure */
                    FreeBlockDescriptor(&(Partition_p->Device_p->TopOfSpaceFreeBlocksList_p), Cur_p);
                }
            }
            else
            {
                /* Failed to allocate new block structure */
                Err = STAVMEM_ERROR_MAX_BLOCKS;
            }
        }
        else
        {
            /* Could not find a large enough memory block matching the allocation requirements */
            Err = STAVMEM_ERROR_PARTITION_FULL;
        }
    }

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

    /* Output block handle as allocation result */
    if (New_p == NULL)
    {
        *BlockHandle_p = STAVMEM_INVALID_BLOCK_HANDLE;
    }
    else
    {
        *BlockHandle_p = (STAVMEM_BlockHandle_t) New_p;
    }

    return(Err);
}



/*
--------------------------------------------------------------------------------
Re-allocate a memory block (with different size)
--------------------------------------------------------------------------------
*/
ST_ErrorCode_t STAVMEM_ReAllocBlock(const STAVMEM_ReAllocBlockParams_t *ReAllocBlockParams_p, STAVMEM_BlockHandle_t *BlockHandle_p)

⌨️ 快捷键说明

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