📄 avm_allo.c
字号:
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 + -