📄 memmanager.c
字号:
/* 45 */
pReleaseBlock -> pNextSegment = pSave -> pNextSegment;
pReleaseBlock -> pLastSegment = pSave -> pLastSegment;
if ( pSave -> pLastSegment != NULL )
{
pSave -> pLastSegment -> pNextSegment = pReleaseBlock;
}
if ( pSave -> pNextSegment != NULL ) /* new */
{
pSave -> pNextSegment -> pLastSegment = pReleaseBlock;
}
}
else
{
/* 54 */
/* there is space between the close block and the block to release */
/* pReleaseBlock is to the left */
/* 61 */
if ( pSave == pSwathFreeSpace ) /* no free space on left */
{
/* 62 */
pSwathFreeSpace = pReleaseBlock;
pReleaseBlock -> pLastSegment = NULL;
pReleaseBlock -> pNextSegment = pSave;
pSave -> pLastSegment = pReleaseBlock;
}
else
{
/* 63 */
pReleaseBlock -> pNextSegment = pSave;
pSave -> pLastSegment -> pNextSegment = pReleaseBlock;
pReleaseBlock -> pLastSegment = pSave -> pLastSegment;
pSave -> pLastSegment = pReleaseBlock;
}
}
}
}
}
/******************************************************************************
*
* Function Name: Malloc
*
* Description:
*
* Malloc is used to allocate memory not to be used as swath buffer space
* it is designed to operate more like the normal 'c' malloc function.
*
******************************************************************************/
ObjID Malloc ( Uint32 U32Size )
{
/* make sure that an even number of bytes is requested so that */
/* call to ReqMemSegment will work */
if ( U32Size & 1 )
{
U32Size ++;
}
/* Hack to fix arm dword alignment requirement */
if ( U32Size & 2 )
{
U32Size +=2;
}
/* make call to reserve memory and return pointer to data, free will */
/* adjust for segment header when memory is released */
return ( ( void * )( ReqMemSegment ( U32Size, NULL ) -> pU16DataPointer )); /* don't wait, don't accept smaller packet */
}
/******************************************************************************
*
* Function Name: ReqMemSegment
*
* Description:
*
* Request Swath Segment.
*
******************************************************************************/
MemSegmentHeader * ReqMemSegment ( Uint32 U32RequestSize,
MemSegmentHeader * pPreviousBlock)
{
MemSegmentHeader * pResult = NULL;
LockRAM();
while ((pResult=GetMemSegment(U32RequestSize, pPreviousBlock, FALSE)) == NULL)
{
// OSSleep();
}
UnlockRAM();
return (pResult);
}
/******************************************************************************
*
* Function Name: GetMemSegment
*
* Description:
*
* Request Swath Segment.
*
******************************************************************************/
MemSegmentHeader * GetMemSegment ( Uint32 U32RequestSize,
MemSegmentHeader * pPreviousBlock,
BOOL fAcceptSmallerSegment )
{
MemSegmentHeader * pRunner; /* pointer to a free segment */
MemSegmentHeader * pResult = NULL;
MemSegmentHeader aProbe;
MemSegmentHeader * pProbe = &aProbe; /* pointer to best fit segment */
MemSegmentHeader aProbeLargest;
MemSegmentHeader * pProbeLargest = &aProbeLargest; /* pointer to the largest segment */
MemSegmentHeader * pNewHeader;
Uint32 U32NewSize;
/* make sure that requested size is even */
if ( U32RequestSize & 3 )
{
#ifdef Sample
// Error (SWATHMAN_1); /*error handle*/
#endif
}
CollectSpace (); /* return any released swaths to the free space pool */
/* wait until some memory is available */
if ( pSwathFreeSpace == NULL )
{
return ( pResult );
}
/* init best fit size to be a large number */
pProbe -> U32DataSize = sizeof ( U16MemBuffer ) - sizeof ( MemSegmentHeader ) + 2;
/* init largest segment to be a small number */
pProbeLargest -> U32DataSize = 0;
/* init free pointer */
pRunner = pSwathFreeSpace;
/* look for an exact fit first */
do
{
if ( pRunner -> U32DataSize == U32RequestSize )
{
/* an exact fit has been found */
/* so decouple found segment from free space */
pResult = pRunner;
if ( pRunner -> pLastSegment == NULL )
{
if ( pRunner -> pNextSegment == NULL )
{
/* a request was made that would allocate all the memory */
/*NEVER_ERROR (); */
pSwathFreeSpace = NULL;
}
else
{
pSwathFreeSpace = pRunner -> pNextSegment;
pRunner -> pNextSegment -> pLastSegment = NULL;
pRunner -> pNextSegment = NULL;
}
}
else
{
pRunner -> pLastSegment -> pNextSegment = pRunner -> pNextSegment;
if ( pRunner -> pNextSegment != NULL )
{
pRunner -> pNextSegment -> pLastSegment = pRunner -> pLastSegment;
}
}
break;
}
else
{
/* Keep track of best fit segment. */
if ((pRunner -> U32DataSize < pProbe -> U32DataSize) &&
(pRunner -> U32DataSize >= U32RequestSize))
{
pProbe = pRunner;
}
/* Keep track of largest segment. */
if (pRunner -> U32DataSize > pProbeLargest -> U32DataSize)
{
pProbeLargest = pRunner;
}
}
/* point to next free segment */
pRunner = pRunner -> pNextSegment;
} while ( pRunner != NULL );
/* if a smaller segment is acceptable, prepare for it */
if (fAcceptSmallerSegment == TRUE)
{
if (pProbe -> U32DataSize > ( sizeof(U16MemBuffer) - sizeof(MemSegmentHeader) ))
{
if (pProbeLargest -> U32DataSize > 0)
{
pProbe = pProbeLargest;
}
}
}
/* if an exact match was found then set up next and last (previous) pointers */
if ( pResult != NULL )
{
pResult -> pNextSegment = NULL;
pResult -> pLastSegment = NULL;
/* link up with previous segment if it exists */
if ( pPreviousBlock != NULL )
{
pPreviousBlock -> pNextSegment = pResult;
pResult -> pLastSegment = pPreviousBlock;
}
pResult -> fTrashed = FALSE;
return ( pResult );
}
/* if an exact fit was not found, use the best fit free segment determined above */
/* or the largest segment if this is acceptable */
else if ( pProbe -> U32DataSize <= ( sizeof( U16MemBuffer ) - sizeof( MemSegmentHeader ) ) )
{
if ( pProbe -> U32DataSize > sizeof ( MemSegmentHeader ) + U32RequestSize )
{
/* space is available to build a new free space header and data */
U32NewSize = pProbe -> U32DataSize - sizeof ( MemSegmentHeader ) - U32RequestSize;
pNewHeader = (MemSegmentHeader *)WordPointerCheck
(( Uint8 * )(( Uint32 ) pProbe -> pU16DataPointer + U32RequestSize ));
pNewHeader -> pNextSegment = pProbe -> pNextSegment;
pNewHeader -> pLastSegment = pProbe -> pLastSegment;
pNewHeader -> fTrashed = FALSE;
if ( U32NewSize > 0 )
{
pNewHeader -> pU16DataPointer = WordPointerCheck
(( Uint8 * )(( Uint32 ) pNewHeader + sizeof ( MemSegmentHeader )));
}
else
{
pNewHeader -> pU16DataPointer = NULL;
}
pNewHeader -> U32DataSize = U32NewSize;
/* link newly created segment into the free space */
/* by doing this we are unlinking the segment we are ready to use */
if ( pNewHeader -> pLastSegment == NULL )
{
pSwathFreeSpace = pNewHeader;
}
if ( pNewHeader -> pNextSegment != NULL )
{
pNewHeader -> pNextSegment -> pLastSegment = pNewHeader;
}
if ( pProbe -> pLastSegment != NULL )
{
pProbe -> pLastSegment -> pNextSegment = pNewHeader;
}
pResult = pProbe;
/* free space adjustments are made, now it is safe to allow releases */
/* ALLOW_INTERRUPTS;*/
/* fill in new header information */
pResult -> U32DataSize = U32RequestSize;
pResult -> pU16DataPointer = WordPointerCheck
(( Uint8 * )(( Uint32 ) pResult + sizeof ( MemSegmentHeader )));
pResult -> pNextSegment = NULL;
pResult -> pLastSegment = NULL;
/* link up with previous segment if it exists */
if ( pPreviousBlock != NULL )
{
pPreviousBlock -> pNextSegment = pResult;
pResult -> pLastSegment = pPreviousBlock;
}
}
else
{
/* There is not enough room for data and a new header, but there is room */
/* for just the data - we can use this space anyway. */
/* WARNING: FOR THIS CASE THE U32DataSize WILL BE LARGER THAN THE REQUESTED */
/* DATA SIZE. THE USER OF THIS DATA SEGMENT SHOULD NOT RELY ON THE */
/* SEGMENT HEADER TO REFLECT THE AMOUNT OF DATA IN THE SEGMENT THAT */
/* IS VALID. THE U32DataSize IS USED BY THE MEMORY MANAGEMENT CODE */
/* TO RECLAIM MEMORY. */
pResult = pProbe;
/* decouple found segment from free space */
if ( pResult -> pLastSegment == NULL )
{
if ( pResult -> pNextSegment == NULL )
{
/* a request was made that would allocate all the memory */
/*NEVER_ERROR (); */
pSwathFreeSpace = NULL;
}
else
{
pSwathFreeSpace = pResult -> pNextSegment;
pResult -> pNextSegment -> pLastSegment = NULL;
pResult -> pNextSegment = NULL;
}
}
else
{
pResult -> pLastSegment -> pNextSegment = pResult -> pNextSegment;
if ( pResult -> pNextSegment != NULL )
{
pResult -> pNextSegment -> pLastSegment = pResult -> pLastSegment;
}
}
pResult -> pNextSegment = NULL;
pResult -> pLastSegment = NULL;
/* link up with previous segment if it exists */
if ( pPreviousBlock != NULL )
{
pPreviousBlock -> pNextSegment = pResult;
pResult -> pLastSegment = pPreviousBlock;
}
}
pResult -> fTrashed = FALSE;
return ( pResult );
}
if (pResult != NULL)
{
pResult -> fTrashed = FALSE;
}
return ( pResult );
}
/***************************************************************************
*
* Function Name:
* LockRAM
*
* Description:
*
* This function protects RAM allocation attempts.
* If the exec is started, semaphores are used. If not, interrupts are held.
*
*************************************************************************/
void LockRAM( void )
{
#ifdef Sample
if (fExecStarted) //if the exec start
{
Os_Wait (RAM); /* only allow one task at a time */
}
else
{
//DISABLE_INTERRUPTS; /*disable ARM interrupt*/
}
#endif
}
/***************************************************************************
*
* Function Name:
* UnockRAM
*
* Description:
*
* This function unlocks the semaphores surrounding RAM allocation, if the
* exec is started. If not, it allows interrupts previously held.
*
*************************************************************************/
void UnlockRAM ( void )
{
#ifdef Sample
if (fExecStarted)
{
Os_Signal (RAM); /* release this task */
}
else
{
//ENABLE_INTERRUPTS; /*enable ARM interrupt*/
}
#endif
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -