Move size calculation out of critical section (#748)

The size calculation in pvPortMalloc uses only parameters and read
only constants and therefore, can be moved out of critical section
to make the critical section as small as possible.
This commit is contained in:
Moral-Hao 2023-08-17 00:01:17 +08:00 committed by GitHub
parent 6f3586516a
commit bcd6dbd772
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 106 additions and 84 deletions

View file

@ -103,8 +103,8 @@ typedef struct A_BLOCK_LINK
} BlockLink_t; } BlockLink_t;
static const uint16_t heapSTRUCT_SIZE = ( ( sizeof( BlockLink_t ) + ( portBYTE_ALIGNMENT - 1 ) ) & ~( ( size_t ) portBYTE_ALIGNMENT_MASK ) ); static const size_t xHeapStructSize = ( ( sizeof( BlockLink_t ) + ( size_t ) ( portBYTE_ALIGNMENT - 1 ) ) & ~( ( size_t ) portBYTE_ALIGNMENT_MASK ) );
#define heapMINIMUM_BLOCK_SIZE ( ( size_t ) ( heapSTRUCT_SIZE * 2 ) ) #define heapMINIMUM_BLOCK_SIZE ( ( size_t ) ( xHeapStructSize * 2 ) )
/* Create a couple of list links to mark the start and end of the list. */ /* Create a couple of list links to mark the start and end of the list. */
PRIVILEGED_DATA static BlockLink_t xStart, xEnd; PRIVILEGED_DATA static BlockLink_t xStart, xEnd;
@ -159,22 +159,20 @@ void * pvPortMalloc( size_t xWantedSize )
void * pvReturn = NULL; void * pvReturn = NULL;
size_t xAdditionalRequiredSize; size_t xAdditionalRequiredSize;
vTaskSuspendAll();
{
/* If this is the first call to malloc then the heap will require
* initialisation to setup the list of free blocks. */
if( xHeapHasBeenInitialised == pdFALSE )
{
prvHeapInit();
xHeapHasBeenInitialised = pdTRUE;
}
if( xWantedSize > 0 ) if( xWantedSize > 0 )
{ {
/* The wanted size must be increased so it can contain a BlockLink_t /* The wanted size must be increased so it can contain a BlockLink_t
* structure in addition to the requested amount of bytes. Some * structure in addition to the requested amount of bytes. */
* additional increment may also be needed for alignment. */ if( heapADD_WILL_OVERFLOW( xWantedSize, xHeapStructSize ) == 0 )
xAdditionalRequiredSize = heapSTRUCT_SIZE + portBYTE_ALIGNMENT - ( xWantedSize & portBYTE_ALIGNMENT_MASK ); {
xWantedSize += xHeapStructSize;
/* Ensure that blocks are always aligned to the required number
* of bytes. */
if( ( xWantedSize & portBYTE_ALIGNMENT_MASK ) != 0x00 )
{
/* Byte alignment required. */
xAdditionalRequiredSize = portBYTE_ALIGNMENT - ( xWantedSize & portBYTE_ALIGNMENT_MASK );
if( heapADD_WILL_OVERFLOW( xWantedSize, xAdditionalRequiredSize ) == 0 ) if( heapADD_WILL_OVERFLOW( xWantedSize, xAdditionalRequiredSize ) == 0 )
{ {
@ -185,6 +183,30 @@ void * pvPortMalloc( size_t xWantedSize )
xWantedSize = 0; xWantedSize = 0;
} }
} }
else
{
mtCOVERAGE_TEST_MARKER();
}
}
else
{
xWantedSize = 0;
}
}
else
{
mtCOVERAGE_TEST_MARKER();
}
vTaskSuspendAll();
{
/* If this is the first call to malloc then the heap will require
* initialisation to setup the list of free blocks. */
if( xHeapHasBeenInitialised == pdFALSE )
{
prvHeapInit();
xHeapHasBeenInitialised = pdTRUE;
}
/* Check the block size we are trying to allocate is not so large that the /* Check the block size we are trying to allocate is not so large that the
* top bit is set. The top bit of the block size member of the BlockLink_t * top bit is set. The top bit of the block size member of the BlockLink_t
@ -210,7 +232,7 @@ void * pvPortMalloc( size_t xWantedSize )
{ {
/* Return the memory space - jumping over the BlockLink_t structure /* Return the memory space - jumping over the BlockLink_t structure
* at its start. */ * at its start. */
pvReturn = ( void * ) ( ( ( uint8_t * ) pxPreviousBlock->pxNextFreeBlock ) + heapSTRUCT_SIZE ); pvReturn = ( void * ) ( ( ( uint8_t * ) pxPreviousBlock->pxNextFreeBlock ) + xHeapStructSize );
/* This block is being returned for use so must be taken out of the /* This block is being returned for use so must be taken out of the
* list of free blocks. */ * list of free blocks. */
@ -271,7 +293,7 @@ void vPortFree( void * pv )
{ {
/* The memory being freed will have an BlockLink_t structure immediately /* The memory being freed will have an BlockLink_t structure immediately
* before it. */ * before it. */
puc -= heapSTRUCT_SIZE; puc -= xHeapStructSize;
/* This unexpected casting is to keep some compilers from issuing /* This unexpected casting is to keep some compilers from issuing
* byte alignment warnings. */ * byte alignment warnings. */
@ -289,7 +311,7 @@ void vPortFree( void * pv )
heapFREE_BLOCK( pxLink ); heapFREE_BLOCK( pxLink );
#if ( configHEAP_CLEAR_MEMORY_ON_FREE == 1 ) #if ( configHEAP_CLEAR_MEMORY_ON_FREE == 1 )
{ {
( void ) memset( puc + heapSTRUCT_SIZE, 0, pxLink->xBlockSize - heapSTRUCT_SIZE ); ( void ) memset( puc + xHeapStructSize, 0, pxLink->xBlockSize - xHeapStructSize );
} }
#endif #endif

View file

@ -143,19 +143,6 @@ void * pvPortMalloc( size_t xWantedSize )
void * pvReturn = NULL; void * pvReturn = NULL;
size_t xAdditionalRequiredSize; size_t xAdditionalRequiredSize;
vTaskSuspendAll();
{
/* If this is the first call to malloc then the heap will require
* initialisation to setup the list of free blocks. */
if( pxEnd == NULL )
{
prvHeapInit();
}
else
{
mtCOVERAGE_TEST_MARKER();
}
if( xWantedSize > 0 ) if( xWantedSize > 0 )
{ {
/* The wanted size must be increased so it can contain a BlockLink_t /* The wanted size must be increased so it can contain a BlockLink_t
@ -195,6 +182,19 @@ void * pvPortMalloc( size_t xWantedSize )
mtCOVERAGE_TEST_MARKER(); mtCOVERAGE_TEST_MARKER();
} }
vTaskSuspendAll();
{
/* If this is the first call to malloc then the heap will require
* initialisation to setup the list of free blocks. */
if( pxEnd == NULL )
{
prvHeapInit();
}
else
{
mtCOVERAGE_TEST_MARKER();
}
/* Check the block size we are trying to allocate is not so large that the /* Check the block size we are trying to allocate is not so large that the
* top bit is set. The top bit of the block size member of the BlockLink_t * top bit is set. The top bit of the block size member of the BlockLink_t
* structure is used to determine who owns the block - the application or * structure is used to determine who owns the block - the application or

View file

@ -165,8 +165,6 @@ void * pvPortMalloc( size_t xWantedSize )
* prvPortMalloc(). */ * prvPortMalloc(). */
configASSERT( pxEnd ); configASSERT( pxEnd );
vTaskSuspendAll();
{
if( xWantedSize > 0 ) if( xWantedSize > 0 )
{ {
/* The wanted size must be increased so it can contain a BlockLink_t /* The wanted size must be increased so it can contain a BlockLink_t
@ -206,6 +204,8 @@ void * pvPortMalloc( size_t xWantedSize )
mtCOVERAGE_TEST_MARKER(); mtCOVERAGE_TEST_MARKER();
} }
vTaskSuspendAll();
{
/* Check the block size we are trying to allocate is not so large that the /* Check the block size we are trying to allocate is not so large that the
* top bit is set. The top bit of the block size member of the BlockLink_t * top bit is set. The top bit of the block size member of the BlockLink_t
* structure is used to determine who owns the block - the application or * structure is used to determine who owns the block - the application or