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;
static const uint16_t heapSTRUCT_SIZE = ( ( sizeof( BlockLink_t ) + ( portBYTE_ALIGNMENT - 1 ) ) & ~( ( size_t ) portBYTE_ALIGNMENT_MASK ) );
#define heapMINIMUM_BLOCK_SIZE ( ( size_t ) ( heapSTRUCT_SIZE * 2 ) )
static const size_t xHeapStructSize = ( ( sizeof( BlockLink_t ) + ( size_t ) ( portBYTE_ALIGNMENT - 1 ) ) & ~( ( size_t ) portBYTE_ALIGNMENT_MASK ) );
#define heapMINIMUM_BLOCK_SIZE ( ( size_t ) ( xHeapStructSize * 2 ) )
/* Create a couple of list links to mark the start and end of the list. */
PRIVILEGED_DATA static BlockLink_t xStart, xEnd;
@ -159,6 +159,45 @@ void * pvPortMalloc( size_t xWantedSize )
void * pvReturn = NULL;
size_t xAdditionalRequiredSize;
if( xWantedSize > 0 )
{
/* The wanted size must be increased so it can contain a BlockLink_t
* structure in addition to the requested amount of bytes. */
if( heapADD_WILL_OVERFLOW( xWantedSize, xHeapStructSize ) == 0 )
{
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 )
{
xWantedSize += xAdditionalRequiredSize;
}
else
{
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
@ -169,23 +208,6 @@ void * pvPortMalloc( size_t xWantedSize )
xHeapHasBeenInitialised = pdTRUE;
}
if( xWantedSize > 0 )
{
/* The wanted size must be increased so it can contain a BlockLink_t
* structure in addition to the requested amount of bytes. Some
* additional increment may also be needed for alignment. */
xAdditionalRequiredSize = heapSTRUCT_SIZE + portBYTE_ALIGNMENT - ( xWantedSize & portBYTE_ALIGNMENT_MASK );
if( heapADD_WILL_OVERFLOW( xWantedSize, xAdditionalRequiredSize ) == 0 )
{
xWantedSize += xAdditionalRequiredSize;
}
else
{
xWantedSize = 0;
}
}
/* 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
* structure is used to determine who owns the block - the application or
@ -210,7 +232,7 @@ void * pvPortMalloc( size_t xWantedSize )
{
/* Return the memory space - jumping over the BlockLink_t structure
* 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
* list of free blocks. */
@ -271,7 +293,7 @@ void vPortFree( void * pv )
{
/* The memory being freed will have an BlockLink_t structure immediately
* before it. */
puc -= heapSTRUCT_SIZE;
puc -= xHeapStructSize;
/* This unexpected casting is to keep some compilers from issuing
* byte alignment warnings. */
@ -289,7 +311,7 @@ void vPortFree( void * pv )
heapFREE_BLOCK( pxLink );
#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

View file

@ -143,6 +143,45 @@ void * pvPortMalloc( size_t xWantedSize )
void * pvReturn = NULL;
size_t xAdditionalRequiredSize;
if( xWantedSize > 0 )
{
/* The wanted size must be increased so it can contain a BlockLink_t
* structure in addition to the requested amount of bytes. */
if( heapADD_WILL_OVERFLOW( xWantedSize, xHeapStructSize ) == 0 )
{
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 )
{
xWantedSize += xAdditionalRequiredSize;
}
else
{
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
@ -156,45 +195,6 @@ void * pvPortMalloc( size_t xWantedSize )
mtCOVERAGE_TEST_MARKER();
}
if( xWantedSize > 0 )
{
/* The wanted size must be increased so it can contain a BlockLink_t
* structure in addition to the requested amount of bytes. */
if( heapADD_WILL_OVERFLOW( xWantedSize, xHeapStructSize ) == 0 )
{
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 )
{
xWantedSize += xAdditionalRequiredSize;
}
else
{
xWantedSize = 0;
}
}
else
{
mtCOVERAGE_TEST_MARKER();
}
}
else
{
xWantedSize = 0;
}
}
else
{
mtCOVERAGE_TEST_MARKER();
}
/* 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
* structure is used to determine who owns the block - the application or

View file

@ -165,47 +165,47 @@ void * pvPortMalloc( size_t xWantedSize )
* prvPortMalloc(). */
configASSERT( pxEnd );
vTaskSuspendAll();
if( xWantedSize > 0 )
{
if( xWantedSize > 0 )
/* The wanted size must be increased so it can contain a BlockLink_t
* structure in addition to the requested amount of bytes. */
if( heapADD_WILL_OVERFLOW( xWantedSize, xHeapStructSize ) == 0 )
{
/* The wanted size must be increased so it can contain a BlockLink_t
* structure in addition to the requested amount of bytes. */
if( heapADD_WILL_OVERFLOW( xWantedSize, xHeapStructSize ) == 0 )
xWantedSize += xHeapStructSize;
/* Ensure that blocks are always aligned to the required number
* of bytes. */
if( ( xWantedSize & portBYTE_ALIGNMENT_MASK ) != 0x00 )
{
xWantedSize += xHeapStructSize;
/* Byte alignment required. */
xAdditionalRequiredSize = portBYTE_ALIGNMENT - ( xWantedSize & portBYTE_ALIGNMENT_MASK );
/* Ensure that blocks are always aligned to the required number
* of bytes. */
if( ( xWantedSize & portBYTE_ALIGNMENT_MASK ) != 0x00 )
if( heapADD_WILL_OVERFLOW( xWantedSize, xAdditionalRequiredSize ) == 0 )
{
/* Byte alignment required. */
xAdditionalRequiredSize = portBYTE_ALIGNMENT - ( xWantedSize & portBYTE_ALIGNMENT_MASK );
if( heapADD_WILL_OVERFLOW( xWantedSize, xAdditionalRequiredSize ) == 0 )
{
xWantedSize += xAdditionalRequiredSize;
}
else
{
xWantedSize = 0;
}
xWantedSize += xAdditionalRequiredSize;
}
else
{
mtCOVERAGE_TEST_MARKER();
xWantedSize = 0;
}
}
else
{
xWantedSize = 0;
mtCOVERAGE_TEST_MARKER();
}
}
else
{
mtCOVERAGE_TEST_MARKER();
xWantedSize = 0;
}
}
else
{
mtCOVERAGE_TEST_MARKER();
}
vTaskSuspendAll();
{
/* 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
* structure is used to determine who owns the block - the application or