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

📄 avm_allo.c

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

File name : avm_allo.c

Description : Audio and video memory module memory allocation features


Date               Modification                             Name
----               ------------                             ----
17 Jun 99           Created                                  HG
 6 Oct 99           Introduce partitions functions           HG
*******************************************************************************/


/* Private Definitions (internal use only) ---------------------------------- */

/*#define COMPRESS_AREA
#define FREE_AREA
#define FREE_ALL*/
#define GET_LARGEST_FREE_BLOCK_SIZE

#define USE_SEMAPHORE

/*#define DEBUG_CODE*/

/*#define DO_NOT_ALLOW_AREAS_CROSSING*/


/* Includes ----------------------------------------------------------------- */

#include <string.h>
#include <stdlib.h>

#include "stddefs.h"
#include "stlite.h"
#include "sttbx.h"

#include "stavmem.h"
#include "avm_init.h"
#include "avm_allo.h"


/* Private Types ------------------------------------------------------------ */


/* Private Constants -------------------------------------------------------- */

#define MAX_SIZE_ALIGNING_MASK  0xff    /* Limitation of the aligning mask for the size */


/* Private Variables (static)------------------------------------------------ */


/* Public Variables --------------------------------------------------------- */

stavmem_Partition_t PartitionArray[STAVMEM_MAX_MAX_PARTITION];


/* Private Macros ----------------------------------------------------------- */


/* Private Function prototypes ---------------------------------------------- */

static BOOL RoundUpAlignment(U32 *Alignment_p);

static void InsertBlockAboveBlock(MemBlockDesc_t **VeryTopBlock_p, MemBlockDesc_t *InsertBlock_p, MemBlockDesc_t *ListBlock_p);
static void InsertBlockBelowBlock(MemBlockDesc_t **VeryBottomBlock_p, MemBlockDesc_t *InsertBlock_p, MemBlockDesc_t *ListBlock_p);
static void RemoveBlock(MemBlockDesc_t **VeryTopBlock_p, MemBlockDesc_t **VeryBottomBlock_p, MemBlockDesc_t *ListBlock_p);

static MemBlockDesc_t *AllocBlockDescriptor(MemBlockDesc_t **TopOfFreeBlocksList_p);
static void FreeBlockDescriptor(MemBlockDesc_t **TopOfSpaceFreeBlocksList_p, MemBlockDesc_t *Mem_p);

static ST_ErrorCode_t MarkForbiddenRangesAndBorders(stavmem_Partition_t *Partition_p, const U32 NumberOfForbiddenRanges, STAVMEM_MemoryRange_t *NotOrderedForbiddenRangeArray_p, const U32 NumberOfForbiddenBorders, void **NotOrderedForbiddenBorderArray_p);
static void UnMarkForbiddenRangesAndBorders(stavmem_Partition_t *Partition_p);
static BOOL IsInForbiddenRangeOrBorder(const void *StartAddr_p, const void *StopAddr_p, const U32 NumberOfForbiddenRanges, STAVMEM_MemoryRange_t *NotOrderedForbiddenRangeArray_p, const U32 NumberOfForbiddenBorders, void **NotOrderedForbiddenBorderArray_p);

static ST_ErrorCode_t AllocBlockNoSemaphore(const STAVMEM_AllocBlockParams_t *AllocBlockParams_p, STAVMEM_BlockHandle_t *BlockHandle_p);
static ST_ErrorCode_t FreeNoSemaphore(stavmem_Partition_t *Partition_p, STAVMEM_BlockHandle_t BlockHandle);


/* Functions ---------------------------------------------------------------- */


/*
--------------------------------------------------------------------------------
Create a memory partition in an initialised device
--------------------------------------------------------------------------------
*/
ST_ErrorCode_t STAVMEM_CreatePartition(const ST_DeviceName_t DeviceName,
                                       const STAVMEM_CreatePartitionParams_t *CreateParams_p,
                                       STAVMEM_PartitionHandle_t *PartitionHandle_p)
{
    U32 PartitionIndex;
    stavmem_Device_t *Device_p;
    ST_ErrorCode_t Err = ST_NO_ERROR;

    /* Exit now if parameters are bad */
    if ((CreateParams_p == NULL) || (PartitionHandle_p == NULL))
    {
        return(ST_ERROR_BAD_PARAMETER);
    }

    /* Check if device already initialised and return error if not so */
    Device_p = stavmem_GetPointerOnDeviceNamed(DeviceName);
    if (Device_p == NULL)
    {
        /* Device name not found */
        return(ST_ERROR_UNKNOWN_DEVICE);
    }

    /* Look for a free partition and return error if none is free */
    PartitionIndex = 0;
    while ((PartitionArray[PartitionIndex].PartitionValidity == AVMEM_VALID_PARTITION) && (PartitionIndex < STAVMEM_MAX_MAX_PARTITION))
    {
        PartitionIndex++;
    }
    if (PartitionIndex >= STAVMEM_MAX_MAX_PARTITION)
    {
        /* None of the partitions is free */
        return(STAVMEM_ERROR_MAX_PARTITION);
    }

    PartitionArray[PartitionIndex].Device_p = Device_p; /* 'inherits' device characteristics */

    /* In the current simplified implementation, there's no multiple partition
       so let the whole space become a unique partition */
    PartitionArray[PartitionIndex].PartitionVeryTopBlock_p = PartitionArray[PartitionIndex].Device_p->SpaceVeryTopBlock_p;
    PartitionArray[PartitionIndex].PartitionVeryBottomBlock_p = PartitionArray[PartitionIndex].Device_p->SpaceVeryBottomBlock_p;

    /* Register partition */
    PartitionArray[PartitionIndex].PartitionValidity = AVMEM_VALID_PARTITION;

    /* Let handle be the address of the partition */
    *PartitionHandle_p = (STAVMEM_PartitionHandle_t) &PartitionArray[PartitionIndex];

    STTBX_Report((STTBX_REPORT_LEVEL_INFO, "Partition created on device '%s'", DeviceName));

    return(Err);
}


/*
--------------------------------------------------------------------------------
Delete a memory partition in an initialised device
--------------------------------------------------------------------------------
*/
ST_ErrorCode_t STAVMEM_DeletePartition(const ST_DeviceName_t DeviceName,
                                       const STAVMEM_DeletePartitionParams_t *DeleteParams_p,
                                       STAVMEM_PartitionHandle_t *PartitionHandle_p)
{
    MemBlockDesc_t *Block_p;
    BOOL FoundBlocks;
    stavmem_Partition_t *Partition_p;
    stavmem_Device_t *Device_p;
    ST_ErrorCode_t Err = ST_NO_ERROR;

    /* Exit now if parameters are bad */
    if ((DeleteParams_p == NULL) || (PartitionHandle_p == NULL))
    {
        return(ST_ERROR_BAD_PARAMETER);
    }

    /* Check if device already initialised and return error if not so */
    Device_p = stavmem_GetPointerOnDeviceNamed(DeviceName);
    if (Device_p == NULL)
    {
        /* Device name not found */
        return(ST_ERROR_UNKNOWN_DEVICE);
    }

    /* Get pointer to partition the block belongs to */
    Partition_p = (stavmem_Partition_t *) *PartitionHandle_p;

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

    /* Delete the partition only if the device corresponds */
    if (Partition_p->Device_p != Device_p)
    {
        return(ST_ERROR_BAD_PARAMETER);
    }

    /* Ensure the partition has no more block allocated. If there is, free them if required */
    Block_p = Partition_p->PartitionVeryTopBlock_p;
    FoundBlocks = FALSE;
    while ((Block_p != NULL) && (!FoundBlocks))
	{
        FoundBlocks = ((Block_p->IsUsed) && ((Block_p->AllocMode == STAVMEM_ALLOC_MODE_TOP_BOTTOM) || (Block_p->AllocMode == STAVMEM_ALLOC_MODE_BOTTOM_TOP)));
        Block_p = Block_p->BlockBelow_p;
    }
    Block_p = Partition_p->PartitionVeryTopBlock_p;
    if (FoundBlocks)
    {
        /* Some still allocated blocks were found: delete them of fail */
        if (DeleteParams_p->ForceDelete)
        {
            /* Delete all still allocated blocks */
            while (Block_p != NULL)
            {
                if ((Block_p->IsUsed) && ((Block_p->AllocMode == STAVMEM_ALLOC_MODE_TOP_BOTTOM) || (Block_p->AllocMode == STAVMEM_ALLOC_MODE_BOTTOM_TOP)))
                {
                    /* Free block */
                    FreeNoSemaphore(Partition_p, (STAVMEM_BlockHandle_t) Block_p);
                    /* Always success */
                }
                Block_p = Block_p->BlockBelow_p;
            }
        }
        else
        {
            /* Cannot delete partition: there are still allocated blocks */
            return(STAVMEM_ERROR_ALLOCATED_BLOCK);
        }
    }

    /* Actions before deleting partition: loose partition blocks */
    Partition_p->PartitionVeryTopBlock_p = NULL;
    Partition_p->PartitionVeryBottomBlock_p = NULL;

    /* Un-register partition */
    Partition_p->PartitionValidity = ~AVMEM_VALID_PARTITION;

    STTBX_Report((STTBX_REPORT_LEVEL_INFO, "Partition deleted on device '%s'", Partition_p->Device_p->DeviceName));

    return(Err);
}



/*******************************************************************************
Name        : stavmem_BlockHandleBelongsToSpace
Description : Tells if a block belongs to the initialised device
Parameters  : block handle and device
Assumptions :
Limitations :
Returns     : TRUE if block belongs to space, FALSE otherwise
*******************************************************************************/
__inline BOOL stavmem_BlockHandleBelongsToSpace(STAVMEM_BlockHandle_t BlockHandle, stavmem_Device_t Device)
{
    if ((((U32) BlockHandle) >= ((U32) Device.FirstBlock_p)) && /* Block handle address may be in range */
        (((U32) BlockHandle) <= (((U32) Device.FirstBlock_p) + (sizeof(MemBlockDesc_t) * (Device.TotalAllocatedBlocks - 1)))) && /* Block handle address is in range */
        (((((U32) BlockHandle) - ((U32) Device.FirstBlock_p)) % (sizeof(MemBlockDesc_t))) == 0) && /* Block handle address is valid (in range and aligned) */
        (((MemBlockDesc_t *) BlockHandle)->AllocMode != STAVMEM_ALLOC_MODE_INVALID)) /* Structure is not in list of available blocks */
    {
        return(TRUE);
    }

    return(FALSE);
}



#ifdef DEBUG_CODE
/*******************************************************************************
Name        : stavmem_BlockAndBip
Description : Bips and blocks with a loop. Change value to exit the loop
Parameters  : None
Assumptions :
Limitations :
Returns     : None
*******************************************************************************/
static void stavmem_BlockAndBip(void)
{
    volatile U32 val = 0;
    STTBX_Print(("\a\a"));

    while (val == 0)
    {
        ; /* change value in val to exit the loop ! */
    }
}

static boolean stavmem_DisplayAllBlocksInfo(MemBlockDesc_t *VeryTopBlock_p, MemBlockDesc_t *VeryBottomBlock_p)
{
    U32 Address, Size;
    U32 CalculatedFreeSize = 0;
/*    U32 AskedFreeSize;*/
    char AllocModeStr[10];
    MemBlockDesc_t *Cur_p;
    boolean RetErr = TRUE;

    STTBX_Print(("\nMEMORY BLOCKS FROM BOTTOM:\n"));
    Cur_p = VeryBottomBlock_p;
    while (Cur_p != NULL)
    {
        Size = Cur_p->Size;
        Address = ((U32) Cur_p->StartAddr_p);
        switch (Cur_p->AllocMode)
        {
            case STAVMEM_ALLOC_MODE_BOTTOM_TOP:
                strcpy(AllocModeStr, "BottomTop");
                break;

            case STAVMEM_ALLOC_MODE_TOP_BOTTOM:
                strcpy(AllocModeStr, "TopBottom");
                break;

            case STAVMEM_ALLOC_MODE_RESERVED:
                strcpy(AllocModeStr, "RESERVED!");
                break;

            case STAVMEM_ALLOC_MODE_FORBIDDEN:
                strcpy(AllocModeStr, "FORBIDDEN");
                break;

            default:
                strcpy(AllocModeStr, "-Invalid-");
                RetErr = FALSE;
                break;
        }
        if ((RetErr) && (!Cur_p->IsUsed))
        {
            strcpy(AllocModeStr, "--FREE!--");
            CalculatedFreeSize += Size;
        }

        STTBX_Print(("%#08x-%#08x : %s (%#x byte%c) \n", Address, Address + Size - 1, AllocModeStr, Size, (Size>1)?'s':'.'));

⌨️ 快捷键说明

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