Individual block alignment in heap_5

Hello,

I was wondering if there’s an option in heap_5 for a different alignment for certain blocks (portBYTE_ALIGNMENT), I am working with Arm M55, or if there’s an extension library that implements this functionality.

Thank you!

I do not think there is but you can write a wrapper, something like this:

#define SIZE_MAX                          ( ~( ( size_t ) 0 ) )
#define ADD_WILL_OVERFLOW( a, b )         ( ( a ) > ( SIZE_MAX - ( b ) ) )

#define BYTE_ALIGNMENT      16
#define BYTE_ALIGNMENT_MASK 0x000F

typedef struct BlockMetadata
{
    void * pvOriginalBlock;
    void * pvUserBlock;
} BlockMetadata_t;

const size_t xMetadataSize = ( sizeof( BlockMetadata_t ) + ( ( size_t ) ( BYTE_ALIGNMENT - 1 ) ) ) & ~( ( size_t ) BYTE_ALIGNMENT_MASK );

void * myCustomAlloc( size_t xWantedSize )
{
    size_t xAdditionalRequiredSize;
    BlockMetadata_t * metadata;
    void * pvOriginal = NULL;
    void * pvUser = NULL;

    if( xWantedSize > 0 )
    {
        if( ADD_WILL_OVERFLOW( xWantedSize, xMetadataSize ) == 0 )
        {
            xWantedSize += xMetadataSize;

            /* Ensure that blocks are always aligned to the required number
             * of bytes. */
            if( ( xWantedSize & BYTE_ALIGNMENT_MASK ) != 0x00 )
            {
                /* Byte alignment required. */
                xAdditionalRequiredSize = BYTE_ALIGNMENT - ( xWantedSize & BYTE_ALIGNMENT_MASK );

                if( ADD_WILL_OVERFLOW( xWantedSize, xAdditionalRequiredSize ) == 0 )
                {
                    xWantedSize += xAdditionalRequiredSize;
                }
                else
                {
                    xWantedSize = 0;
                }
            }
        }
        else
        {
            xWantedSize = 0;
        }
    }

    if( xWantedSize > 0 )
    {
        pvOriginal = pvPortMalloc( xWantedSize );

        if( pvOriginal != NULL )
        {
            metadata = ( BlockMetadata_t * ) pvOriginal;
            pvUser = ( void * ) ( ( uint8_t * ) pvOriginal + xMetadataSize );

            metadata->pvOriginalBlock = pvOriginal;
            metadata->pvUserBlock = pvUser;
        }
    }

    return pvUser;
}

void myCustomFree( void * pv )
{
    BlockMetadata_t * metadata;

    if( pv != NULL )
    {
        metadata = ( BlockMetadata_t * ) ( ( uint8_t * ) pv - xMetadataSize );

        if( metadata->pvUserBlock == pv )
        {
            vPortFree( metadata->pvOriginalBlock );
        }
    }
}

Thank you Gaurav, I will look into it!

regards,
Katia