|
|
|
@ -355,211 +355,3 @@ unsigned char *puc;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#define INCLUDE_TEST_CODE 0
|
|
|
|
|
#if INCLUDE_TEST_CODE == 1
|
|
|
|
|
|
|
|
|
|
#define heapMAX_TEST_BLOCKS 6
|
|
|
|
|
|
|
|
|
|
void vTestHeap4( void )
|
|
|
|
|
{
|
|
|
|
|
void *pvReturned;
|
|
|
|
|
static void *pvUsedBlocks[ heapMAX_TEST_BLOCKS ];
|
|
|
|
|
unsigned long ulIndex = 0, ulSize, ulRandSample;
|
|
|
|
|
size_t xSize1, xSize2, xSize3;
|
|
|
|
|
static const unsigned long ulCombinations[ 6 ][ 3 ] =
|
|
|
|
|
{
|
|
|
|
|
{ 0, 1, 2 },
|
|
|
|
|
{ 0, 2, 1 },
|
|
|
|
|
{ 1, 0, 2 },
|
|
|
|
|
{ 1, 2, 0 },
|
|
|
|
|
{ 2, 0, 1 },
|
|
|
|
|
{ 2, 1, 0 }
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/* Attempt to obtain a block of memory that equals the enture heap size.
|
|
|
|
|
This should fail as the size of a block link structure will be added to the
|
|
|
|
|
block in pvPortMalloc(). */
|
|
|
|
|
pvReturned = pvPortMalloc( xTotalHeapSize );
|
|
|
|
|
configASSERT( pvReturned == NULL );
|
|
|
|
|
|
|
|
|
|
/* Attempt to obtain a block of memory that equals the entire heap size
|
|
|
|
|
minus the size of the block link structure that will get added to the
|
|
|
|
|
wanted size inside pvPortMalloc(). This should also fail as the heap
|
|
|
|
|
already contains a start and end block link structure. */
|
|
|
|
|
pvReturned = pvPortMalloc( xTotalHeapSize - heapSTRUCT_SIZE );
|
|
|
|
|
configASSERT( pvReturned == NULL );
|
|
|
|
|
|
|
|
|
|
/* Attempt to obtain a block of memory that equals the entire heap size
|
|
|
|
|
minus the size of the block link structure that will get added to the
|
|
|
|
|
wanted size inside pvPortMalloc(), minus the size of the block link
|
|
|
|
|
structure that marks the end of the heap. */
|
|
|
|
|
pvReturned = pvPortMalloc( xTotalHeapSize - ( 2 * heapSTRUCT_SIZE ) );
|
|
|
|
|
|
|
|
|
|
/* The returned value should point just past the first block link. */
|
|
|
|
|
configASSERT( pvReturned == ( xHeap.ucHeap + heapSTRUCT_SIZE ) );
|
|
|
|
|
|
|
|
|
|
/* There should be no heap remaining. */
|
|
|
|
|
configASSERT( xFreeBytesRemaining == 0 );
|
|
|
|
|
|
|
|
|
|
/* The start should point to the end. */
|
|
|
|
|
configASSERT( xStart.pxNextFreeBlock == pxEnd );
|
|
|
|
|
|
|
|
|
|
/* Free the memory again. */
|
|
|
|
|
vPortFree( pvReturned );
|
|
|
|
|
|
|
|
|
|
/* The heap should be back to its full size, which is the total bytes
|
|
|
|
|
in the array minus the space taken up by the pxEnd structure. */
|
|
|
|
|
configASSERT( xFreeBytesRemaining == ( xTotalHeapSize - heapSTRUCT_SIZE ) );
|
|
|
|
|
|
|
|
|
|
/* The start block should now point to a block that holds the entire heap
|
|
|
|
|
space, which should itself point to the end. */
|
|
|
|
|
configASSERT( xStart.pxNextFreeBlock->xBlockSize == ( xTotalHeapSize - heapSTRUCT_SIZE ) );
|
|
|
|
|
configASSERT( xStart.pxNextFreeBlock->pxNextFreeBlock == pxEnd );
|
|
|
|
|
|
|
|
|
|
/* The next test plugs a gap that create a continuous block up to the pxEnd
|
|
|
|
|
marker. */
|
|
|
|
|
|
|
|
|
|
/* Remove a small block. */
|
|
|
|
|
pvUsedBlocks[ ulIndex ] = pvPortMalloc( 8 );
|
|
|
|
|
configASSERT( xFreeBytesRemaining == ( xTotalHeapSize - heapSTRUCT_SIZE - 8 - heapSTRUCT_SIZE ) );
|
|
|
|
|
ulIndex++;
|
|
|
|
|
|
|
|
|
|
/* Remove another block. */
|
|
|
|
|
pvUsedBlocks[ ulIndex ] = pvPortMalloc( 32 );
|
|
|
|
|
|
|
|
|
|
/* Return the frist removed block, which should join with the start block
|
|
|
|
|
and leave a gap. */
|
|
|
|
|
vPortFree( pvUsedBlocks[ 0 ] );
|
|
|
|
|
|
|
|
|
|
/* Return the second free block, which should fill the gap. */
|
|
|
|
|
vPortFree( pvUsedBlocks[ 1 ] );
|
|
|
|
|
|
|
|
|
|
/* The heap should be back to its full size, which is the total bytes
|
|
|
|
|
in the array minus the space taken up by the pxEnd structure. */
|
|
|
|
|
configASSERT( xFreeBytesRemaining == ( xTotalHeapSize - heapSTRUCT_SIZE ) );
|
|
|
|
|
|
|
|
|
|
/* The start block should now point to a block that holds the entire heap
|
|
|
|
|
space, which should itself point to the end. */
|
|
|
|
|
configASSERT( xStart.pxNextFreeBlock->xBlockSize == ( xTotalHeapSize - heapSTRUCT_SIZE ) );
|
|
|
|
|
configASSERT( xStart.pxNextFreeBlock->pxNextFreeBlock == pxEnd );
|
|
|
|
|
|
|
|
|
|
/* The next test plugs a gap that create a continuous block but not up to
|
|
|
|
|
the end marker - it then fills the last gap too. */
|
|
|
|
|
|
|
|
|
|
ulIndex = 0;
|
|
|
|
|
|
|
|
|
|
/* Remove a small block. */
|
|
|
|
|
pvUsedBlocks[ ulIndex ] = pvPortMalloc( 8 );
|
|
|
|
|
configASSERT( xFreeBytesRemaining == ( xTotalHeapSize - heapSTRUCT_SIZE - 8 - heapSTRUCT_SIZE ) );
|
|
|
|
|
ulIndex++;
|
|
|
|
|
|
|
|
|
|
/* Remove another block. */
|
|
|
|
|
pvUsedBlocks[ ulIndex ] = pvPortMalloc( 32 );
|
|
|
|
|
ulIndex++;
|
|
|
|
|
|
|
|
|
|
/* And one final block. */
|
|
|
|
|
pvUsedBlocks[ ulIndex ] = pvPortMalloc( 128 );
|
|
|
|
|
|
|
|
|
|
/* Return the frist removed block, which should join with the start block
|
|
|
|
|
and leave a gap. */
|
|
|
|
|
vPortFree( pvUsedBlocks[ 0 ] );
|
|
|
|
|
|
|
|
|
|
/* Return the last block, which should join with the end. */
|
|
|
|
|
vPortFree( pvUsedBlocks[ 2 ] );
|
|
|
|
|
|
|
|
|
|
/* Return the middle block block, which should fill the gap. */
|
|
|
|
|
vPortFree( pvUsedBlocks[ 1 ] );
|
|
|
|
|
|
|
|
|
|
/* The heap should be back to its full size, which is the total bytes
|
|
|
|
|
in the array minus the space taken up by the pxEnd structure. */
|
|
|
|
|
configASSERT( xFreeBytesRemaining == ( xTotalHeapSize - heapSTRUCT_SIZE ) );
|
|
|
|
|
|
|
|
|
|
/* The start block should now point to a block that holds the entire heap
|
|
|
|
|
space, which should itself point to the end. */
|
|
|
|
|
configASSERT( xStart.pxNextFreeBlock->xBlockSize == ( xTotalHeapSize - heapSTRUCT_SIZE ) );
|
|
|
|
|
configASSERT( xStart.pxNextFreeBlock->pxNextFreeBlock == pxEnd );
|
|
|
|
|
|
|
|
|
|
for( ulIndex = 0; ulIndex < 6; ulIndex++ )
|
|
|
|
|
{
|
|
|
|
|
pvUsedBlocks[ 0 ] = pvPortMalloc( 10 );
|
|
|
|
|
pvUsedBlocks[ 1 ] = pvPortMalloc( 1 );
|
|
|
|
|
pvUsedBlocks[ 2 ] = pvPortMalloc( 10000 );
|
|
|
|
|
|
|
|
|
|
vPortFree( pvUsedBlocks[ ulCombinations[ ulIndex ][ 0 ] ] );
|
|
|
|
|
vPortFree( pvUsedBlocks[ ulCombinations[ ulIndex ][ 1 ] ] );
|
|
|
|
|
vPortFree( pvUsedBlocks[ ulCombinations[ ulIndex ][ 2 ] ] );
|
|
|
|
|
|
|
|
|
|
/* The heap should be back to its full size, which is the total bytes
|
|
|
|
|
in the array minus the space taken up by the pxEnd structure. */
|
|
|
|
|
configASSERT( xFreeBytesRemaining == ( xTotalHeapSize - heapSTRUCT_SIZE ) );
|
|
|
|
|
|
|
|
|
|
/* The start block should now point to a block that holds the entire heap
|
|
|
|
|
space, which should itself point to the end. */
|
|
|
|
|
configASSERT( xStart.pxNextFreeBlock->xBlockSize == ( xTotalHeapSize - heapSTRUCT_SIZE ) );
|
|
|
|
|
configASSERT( xStart.pxNextFreeBlock->pxNextFreeBlock == pxEnd );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Do the same, but using the entire block of memory. */
|
|
|
|
|
for( ulIndex = 0; ulIndex < 6; ulIndex++ )
|
|
|
|
|
{
|
|
|
|
|
/* Total heap size. */
|
|
|
|
|
ulSize = xTotalHeapSize - heapSTRUCT_SIZE;
|
|
|
|
|
|
|
|
|
|
/* Minus 4 heap structs (three allocated blocks plus pxEnd. */
|
|
|
|
|
ulSize -= 4 * heapSTRUCT_SIZE;
|
|
|
|
|
|
|
|
|
|
pvUsedBlocks[ 0 ] = pvPortMalloc( ulSize / 3 );
|
|
|
|
|
pvUsedBlocks[ 1 ] = pvPortMalloc( ulSize / 3 );
|
|
|
|
|
/* The last block includes any remainder. */
|
|
|
|
|
pvUsedBlocks[ 2 ] = pvPortMalloc( ( ulSize / 3 ) + ( ulSize % 3 ) );
|
|
|
|
|
configASSERT( pvUsedBlocks[ 2 ] );
|
|
|
|
|
configASSERT( xFreeBytesRemaining == 0 );
|
|
|
|
|
|
|
|
|
|
vPortFree( pvUsedBlocks[ ulCombinations[ ulIndex ][ 0 ] ] );
|
|
|
|
|
vPortFree( pvUsedBlocks[ ulCombinations[ ulIndex ][ 1 ] ] );
|
|
|
|
|
vPortFree( pvUsedBlocks[ ulCombinations[ ulIndex ][ 2 ] ] );
|
|
|
|
|
|
|
|
|
|
/* The heap should be back to its full size, which is the total bytes
|
|
|
|
|
in the array minus the space taken up by the pxEnd structure. */
|
|
|
|
|
configASSERT( xFreeBytesRemaining == ( xTotalHeapSize - heapSTRUCT_SIZE ) );
|
|
|
|
|
|
|
|
|
|
/* The start block should now point to a block that holds the entire heap
|
|
|
|
|
space, which should itself point to the end. */
|
|
|
|
|
configASSERT( xStart.pxNextFreeBlock->xBlockSize == ( xTotalHeapSize - heapSTRUCT_SIZE ) );
|
|
|
|
|
configASSERT( xStart.pxNextFreeBlock->pxNextFreeBlock == pxEnd );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Do the same, but using random block sizes. */
|
|
|
|
|
for( ulRandSample = 0; ulRandSample < 0xffffffUL; ulRandSample++ )
|
|
|
|
|
{
|
|
|
|
|
xSize1 = rand();
|
|
|
|
|
xSize2 = rand();
|
|
|
|
|
xSize3 = rand();
|
|
|
|
|
|
|
|
|
|
for( ulIndex = 0; ulIndex < 6; ulIndex++ )
|
|
|
|
|
{
|
|
|
|
|
pvUsedBlocks[ 0 ] = pvPortMalloc( xSize1 );
|
|
|
|
|
pvUsedBlocks[ 1 ] = pvPortMalloc( xSize2 );
|
|
|
|
|
pvUsedBlocks[ 2 ] = pvPortMalloc( xSize3 );
|
|
|
|
|
|
|
|
|
|
vPortFree( pvUsedBlocks[ ulCombinations[ ulIndex ][ 0 ] ] );
|
|
|
|
|
vPortFree( pvUsedBlocks[ ulCombinations[ ulIndex ][ 1 ] ] );
|
|
|
|
|
vPortFree( pvUsedBlocks[ ulCombinations[ ulIndex ][ 2 ] ] );
|
|
|
|
|
|
|
|
|
|
/* The heap should be back to its full size, which is the total bytes
|
|
|
|
|
in the array minus the space taken up by the pxEnd structure. */
|
|
|
|
|
configASSERT( xFreeBytesRemaining == ( xTotalHeapSize - heapSTRUCT_SIZE ) );
|
|
|
|
|
|
|
|
|
|
/* The start block should now point to a block that holds the entire heap
|
|
|
|
|
space, which should itself point to the end. */
|
|
|
|
|
configASSERT( xStart.pxNextFreeBlock->xBlockSize == ( xTotalHeapSize - heapSTRUCT_SIZE ) );
|
|
|
|
|
configASSERT( xStart.pxNextFreeBlock->pxNextFreeBlock == pxEnd );
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Particularly test the case where the block being inserted fills a gap
|
|
|
|
|
requiring both the block in front and the block behind to be merged into one. */
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#endif INCLUDE_TEST_CODE
|
|
|
|
|