From: rtel Date: Fri, 5 Jul 2019 20:21:59 +0000 (+0000) Subject: Exercise the new vPortGetHeapStats() function from the Win32 demo projects. X-Git-Tag: V10.3.0~148 X-Git-Url: https://git.sur5r.net/?a=commitdiff_plain;h=59ce4f401beb56ad6257fa96d8e4e3aec14d3a6c;p=freertos Exercise the new vPortGetHeapStats() function from the Win32 demo projects. git-svn-id: https://svn.code.sf.net/p/freertos/code/trunk@2673 1d2547de-c912-0410-9cb9-b8ca96c0e9e2 --- diff --git a/FreeRTOS/Demo/WIN32-MSVC/.vs/WIN32/v14/.suo b/FreeRTOS/Demo/WIN32-MSVC/.vs/WIN32/v14/.suo index 7f5848df5..324972876 100644 Binary files a/FreeRTOS/Demo/WIN32-MSVC/.vs/WIN32/v14/.suo and b/FreeRTOS/Demo/WIN32-MSVC/.vs/WIN32/v14/.suo differ diff --git a/FreeRTOS/Demo/WIN32-MSVC/FreeRTOSConfig.h b/FreeRTOS/Demo/WIN32-MSVC/FreeRTOSConfig.h index cc08b5f3f..6b98922ee 100644 --- a/FreeRTOS/Demo/WIN32-MSVC/FreeRTOSConfig.h +++ b/FreeRTOS/Demo/WIN32-MSVC/FreeRTOSConfig.h @@ -62,7 +62,8 @@ #define configUSE_ALTERNATIVE_API 0 #define configUSE_QUEUE_SETS 1 #define configUSE_TASK_NOTIFICATIONS 1 -#define configSUPPORT_STATIC_ALLOCATION 1 +#define configSUPPORT_STATIC_ALLOCATION 0 +#define configSUPPORT_DYNAMIC_ALLOCATION 1 /* Software timer related configuration options. */ #define configUSE_TIMERS 1 diff --git a/FreeRTOS/Demo/WIN32-MSVC/WIN32.vcxproj b/FreeRTOS/Demo/WIN32-MSVC/WIN32.vcxproj index 87c034b6e..d3531b466 100644 --- a/FreeRTOS/Demo/WIN32-MSVC/WIN32.vcxproj +++ b/FreeRTOS/Demo/WIN32-MSVC/WIN32.vcxproj @@ -81,6 +81,7 @@ + diff --git a/FreeRTOS/Demo/WIN32-MSVC/WIN32.vcxproj.filters b/FreeRTOS/Demo/WIN32-MSVC/WIN32.vcxproj.filters index ae43ea750..0fcb7b740 100644 --- a/FreeRTOS/Demo/WIN32-MSVC/WIN32.vcxproj.filters +++ b/FreeRTOS/Demo/WIN32-MSVC/WIN32.vcxproj.filters @@ -160,6 +160,9 @@ Demo App Source\Full_Demo\Common Demo Tasks + + FreeRTOS Source\Source + diff --git a/FreeRTOS/Demo/WIN32-MSVC/main_full.c b/FreeRTOS/Demo/WIN32-MSVC/main_full.c index 3f19db32e..81d84750c 100644 --- a/FreeRTOS/Demo/WIN32-MSVC/main_full.c +++ b/FreeRTOS/Demo/WIN32-MSVC/main_full.c @@ -245,6 +245,7 @@ static void prvCheckTask( void *pvParameters ) { TickType_t xNextWakeTime; const TickType_t xCycleFrequency = pdMS_TO_TICKS( 4000UL ); +HeapStats_t xHeapStats; /* Just to remove compiler warning. */ ( void ) pvParameters; @@ -370,10 +371,17 @@ const TickType_t xCycleFrequency = pdMS_TO_TICKS( 4000UL ); /* This is the only task that uses stdout so its ok to call printf() directly. */ - printf( "%s - tick count %zu - free heap %zu - min free heap %zu\r\n", pcStatusMessage, - xTaskGetTickCount(), - xPortGetFreeHeapSize(), - xPortGetMinimumEverFreeHeapSize() ); + vPortGetHeapStats( &xHeapStats ); + + configASSERT( xHeapStats.xAvailableHeapSpaceInBytes == xPortGetFreeHeapSize() ); + configASSERT( xHeapStats.xMinimumEverFreeBytesRemaining == xPortGetMinimumEverFreeHeapSize() ); + + printf( "%s - tick count %zu - free heap %zu - min free heap %zu - largest free block %zu \r\n", + pcStatusMessage, + xTaskGetTickCount(), + xHeapStats.xAvailableHeapSpaceInBytes, + xHeapStats.xMinimumEverFreeBytesRemaining, + xHeapStats.xSizeOfLargestFreeBlockInBytes ); } } /*-----------------------------------------------------------*/ diff --git a/FreeRTOS/Demo/WIN32-MingW/main.c b/FreeRTOS/Demo/WIN32-MingW/main.c index 2f3b36bfd..2ccf29ac7 100644 --- a/FreeRTOS/Demo/WIN32-MingW/main.c +++ b/FreeRTOS/Demo/WIN32-MingW/main.c @@ -103,6 +103,12 @@ void vFullDemoIdleFunction( void ); */ static void prvInitialiseHeap( void ); +/* + * Performs a few sanity checks on the behaviour of the vPortGetHeapStats() + * function. + */ +static void prvExerciseHeapStats( void ); + /* * Prototypes for the standard FreeRTOS application hook (callback) functions * implemented within this file. See http://www.freertos.org/a00016.html . @@ -344,6 +350,8 @@ offsets into the array - with gaps in between and messy alignment just for test purposes. */ static uint8_t ucHeap[ configTOTAL_HEAP_SIZE ]; volatile uint32_t ulAdditionalOffset = 19; /* Just to prevent 'condition is always true' warnings in configASSERT(). */ +HeapStats_t xHeapStats; +const HeapStats_t xZeroHeapStats = { 0 }; const HeapRegion_t xHeapRegions[] = { /* Start address with dummy offsets Size */ @@ -360,7 +368,80 @@ const HeapRegion_t xHeapRegions[] = /* Prevent compiler warnings when configASSERT() is not defined. */ ( void ) ulAdditionalOffset; + /* The heap has not been initialised yet so expect stats to all be zero. */ + vPortGetHeapStats( &xHeapStats ); + configASSERT( memcmp( &xHeapStats, &xZeroHeapStats, sizeof( HeapStats_t ) ) == 0 ); + vPortDefineHeapRegions( xHeapRegions ); + + /* Sanity check vTaskGetHeapStats(). */ + prvExerciseHeapStats(); +} +/*-----------------------------------------------------------*/ + +static void prvExerciseHeapStats( void ) +{ +HeapStats_t xHeapStats; +size_t xInitialFreeSpace = xPortGetFreeHeapSize(), xMinimumFreeBytes; +size_t xMetaDataOverhead, i; +void *pvAllocatedBlock; +const size_t xArraySize = 5, xBlockSize = 1000UL; +void *pvAllocatedBlocks[ xArraySize ]; + + /* Check heap stats are as expected after initialisation but before any + allocations. */ + vPortGetHeapStats( &xHeapStats ); + + /* Minimum ever free bytes remaining should be the same as the total number + of bytes as nothing has been allocated yet. */ + configASSERT( xHeapStats.xMinimumEverFreeBytesRemaining == xHeapStats.xAvailableHeapSpaceInBytes ); + configASSERT( xHeapStats.xMinimumEverFreeBytesRemaining == xInitialFreeSpace ); + + /* Nothing has been allocated or freed yet. */ + configASSERT( xHeapStats.xNumberOfSuccessfulAllocations == 0 ); + configASSERT( xHeapStats.xNumberOfSuccessfulFrees == 0 ); + + /* Allocate a 1000 byte block then measure what the overhead of the + allocation in regards to how many bytes more than 1000 were actually + removed from the heap in order to store metadata about the allocation. */ + pvAllocatedBlock = pvPortMalloc( xBlockSize ); + configASSERT( pvAllocatedBlock ); + xMetaDataOverhead = ( xInitialFreeSpace - xPortGetFreeHeapSize() ) - xBlockSize; + + /* Free the block again to get back to where we started. */ + vPortFree( pvAllocatedBlock ); + vPortGetHeapStats( &xHeapStats ); + configASSERT( xHeapStats.xAvailableHeapSpaceInBytes == xInitialFreeSpace ); + configASSERT( xHeapStats.xNumberOfSuccessfulAllocations == 1 ); + configASSERT( xHeapStats.xNumberOfSuccessfulFrees == 1 ); + + /* Allocate blocks checking some stats value on each allocation. */ + for( i = 0; i < xArraySize; i++ ) + { + pvAllocatedBlocks[ i ] = pvPortMalloc( xBlockSize ); + configASSERT( pvAllocatedBlocks[ i ] ); + vPortGetHeapStats( &xHeapStats ); + configASSERT( xHeapStats.xMinimumEverFreeBytesRemaining == ( xInitialFreeSpace - ( ( i + 1 ) * ( xBlockSize + xMetaDataOverhead ) ) ) ); + configASSERT( xHeapStats.xMinimumEverFreeBytesRemaining == xHeapStats.xAvailableHeapSpaceInBytes ); + configASSERT( xHeapStats.xNumberOfSuccessfulAllocations == ( 2Ul + i ) ); + configASSERT( xHeapStats.xNumberOfSuccessfulFrees == 1 ); /* Does not increase during allocations. */ + } + + configASSERT( xPortGetFreeHeapSize() == xPortGetMinimumEverFreeHeapSize() ); + xMinimumFreeBytes = xPortGetFreeHeapSize(); + + /* Free the blocks again. */ + for( i = 0; i < xArraySize; i++ ) + { + vPortFree( pvAllocatedBlocks[ i ] ); + vPortGetHeapStats( &xHeapStats ); + configASSERT( xHeapStats.xAvailableHeapSpaceInBytes == ( xInitialFreeSpace - ( ( ( xArraySize - i - 1 ) * ( xBlockSize + xMetaDataOverhead ) ) ) ) ); + configASSERT( xHeapStats.xNumberOfSuccessfulAllocations == ( xArraySize + 1 ) ); /* Does not increase during frees. */ + configASSERT( xHeapStats.xNumberOfSuccessfulFrees == ( 2UL + i ) ); + } + + /* The minimum ever free heap size should not change as blocks are freed. */ + configASSERT( xMinimumFreeBytes == xPortGetMinimumEverFreeHeapSize() ); } /*-----------------------------------------------------------*/ diff --git a/FreeRTOS/Demo/WIN32-MingW/main_full.c b/FreeRTOS/Demo/WIN32-MingW/main_full.c index 13a66910a..84ae4074e 100644 --- a/FreeRTOS/Demo/WIN32-MingW/main_full.c +++ b/FreeRTOS/Demo/WIN32-MingW/main_full.c @@ -260,6 +260,7 @@ static void prvCheckTask( void *pvParameters ) { TickType_t xNextWakeTime; const TickType_t xCycleFrequency = pdMS_TO_TICKS( 2500UL ); +HeapStats_t xHeapStats; /* Just to remove compiler warning. */ ( void ) pvParameters; @@ -385,10 +386,19 @@ const TickType_t xCycleFrequency = pdMS_TO_TICKS( 2500UL ); /* This is the only task that uses stdout so its ok to call printf() directly. */ - printf( "%s - tick count %u - free heap %u - min free heap %u\r\n", pcStatusMessage, - xTaskGetTickCount(), - xPortGetFreeHeapSize(), - xPortGetMinimumEverFreeHeapSize() ); + vPortGetHeapStats( &xHeapStats ); + + configASSERT( xHeapStats.xAvailableHeapSpaceInBytes == xPortGetFreeHeapSize() ); + configASSERT( xHeapStats.xMinimumEverFreeBytesRemaining == xPortGetMinimumEverFreeHeapSize() ); + + printf( "%s - tick count %u - free heap %u - min free heap %u - largest free block %u - number of free blocks %u\r\n", + pcStatusMessage, + xTaskGetTickCount(), + xHeapStats.xAvailableHeapSpaceInBytes, + xHeapStats.xMinimumEverFreeBytesRemaining, + xHeapStats.xSizeOfLargestFreeBlockInBytes, + xHeapStats.xNumberOfFreeBlocks ); + fflush( stdout ); } }