Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .github/lexicon.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3041,6 +3041,8 @@ xtasktonotify
xtasktoquery
xtasktoresume
xtasktosuspend
xtaskupdateheapallocationstats
xtaskupdateheapfreedstats
xtaskwaitingtoreceive
xtaskwaitingtosend
xtaskwokenbyreceive
Expand Down
5,824 changes: 2,917 additions & 2,907 deletions History.txt

Large diffs are not rendered by default.

20 changes: 14 additions & 6 deletions include/FreeRTOS.h
Original file line number Diff line number Diff line change
Expand Up @@ -756,6 +756,10 @@
#define configGENERATE_RUN_TIME_STATS 0
#endif

#ifndef configTRACK_TASK_MEMORY_ALLOCATIONS
#define configTRACK_TASK_MEMORY_ALLOCATIONS 0
#endif

#if ( configGENERATE_RUN_TIME_STATS == 1 )

#ifndef portCONFIGURE_TIMER_FOR_RUN_TIME_STATS
Expand Down Expand Up @@ -1203,22 +1207,26 @@ typedef struct xSTATIC_TCB
#if ( configGENERATE_RUN_TIME_STATS == 1 )
configRUN_TIME_COUNTER_TYPE ulDummy16;
#endif
#if ( configTRACK_TASK_MEMORY_ALLOCATIONS == 1 )
uint32_t ullDummy17[ 2 ];
size_t xDummy18[ 2 ];
#endif
#if ( configUSE_NEWLIB_REENTRANT == 1 )
struct _reent xDummy17;
struct _reent xDummy19;
#endif
#if ( configUSE_TASK_NOTIFICATIONS == 1 )
uint32_t ulDummy18[ configTASK_NOTIFICATION_ARRAY_ENTRIES ];
uint8_t ucDummy19[ configTASK_NOTIFICATION_ARRAY_ENTRIES ];
uint32_t ulDummy20[ configTASK_NOTIFICATION_ARRAY_ENTRIES ];
uint8_t ucDummy21[ configTASK_NOTIFICATION_ARRAY_ENTRIES ];
#endif
#if ( tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE != 0 )
uint8_t uxDummy20;
uint8_t uxDummy22;
#endif

#if ( INCLUDE_xTaskAbortDelay == 1 )
uint8_t ucDummy21;
uint8_t ucDummy23;
#endif
#if ( configUSE_POSIX_ERRNO == 1 )
int iDummy22;
int iDummy24;
#endif
} StaticTask_t;

Expand Down
41 changes: 32 additions & 9 deletions include/task.h
Original file line number Diff line number Diff line change
Expand Up @@ -153,15 +153,28 @@ typedef struct xTASK_PARAMETERS
* in the system. */
typedef struct xTASK_STATUS
{
TaskHandle_t xHandle; /* The handle of the task to which the rest of the information in the structure relates. */
const char * pcTaskName; /* A pointer to the task's name. This value will be invalid if the task was deleted since the structure was populated! */ /*lint !e971 Unqualified char types are allowed for strings and single characters only. */
UBaseType_t xTaskNumber; /* A number unique to the task. */
eTaskState eCurrentState; /* The state in which the task existed when the structure was populated. */
UBaseType_t uxCurrentPriority; /* The priority at which the task was running (may be inherited) when the structure was populated. */
UBaseType_t uxBasePriority; /* The priority to which the task will return if the task's current priority has been inherited to avoid unbounded priority inversion when obtaining a mutex. Only valid if configUSE_MUTEXES is defined as 1 in FreeRTOSConfig.h. */
configRUN_TIME_COUNTER_TYPE ulRunTimeCounter; /* The total run time allocated to the task so far, as defined by the run time stats clock. See https://www.FreeRTOS.org/rtos-run-time-stats.html. Only valid when configGENERATE_RUN_TIME_STATS is defined as 1 in FreeRTOSConfig.h. */
StackType_t * pxStackBase; /* Points to the lowest address of the task's stack area. */
configSTACK_DEPTH_TYPE usStackHighWaterMark; /* The minimum amount of stack space that has remained for the task since the task was created. The closer this value is to zero the closer the task has come to overflowing its stack. */
TaskHandle_t xHandle; /* The handle of the task to which the rest of the information in the structure relates. */
const char * pcTaskName; /* A pointer to the task's name. This value will be invalid if the task was deleted since the structure was populated! */ /*lint !e971 Unqualified char types are allowed for strings and single characters only. */
UBaseType_t xTaskNumber; /* A number unique to the task. */
eTaskState eCurrentState; /* The state in which the task existed when the structure was populated. */
UBaseType_t uxCurrentPriority; /* The priority at which the task was running (may be inherited) when the structure was populated. */
StackType_t * pxStackBase; /* Points to the lowest address of the task's stack area. */
configSTACK_DEPTH_TYPE usStackHighWaterMark; /* The minimum amount of stack space that has remained for the task since the task was created. The closer this value is to zero the closer the task has come to overflowing its stack. */

#if ( configUSE_MUTEXES == 1 )
UBaseType_t uxBasePriority; /* The priority to which the task will return if the task's current priority has been inherited to avoid unbounded priority inversion when obtaining a mutex. Only valid if configUSE_MUTEXES is defined as 1 in FreeRTOSConfig.h. */
#endif

#if ( configGENERATE_RUN_TIME_STATS == 1 )
uint32_t ulRunTimeCounter; /* The total run time allocated to the task so far, as defined by the run time stats clock. See https://www.FreeRTOS.org/rtos-run-time-stats.html. Only valid when configGENERATE_RUN_TIME_STATS is defined as 1 in FreeRTOSConfig.h. */
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ulRunTimeCounter should now have type configRUN_TIME_COUNTER_TYPE so users can use a 64-bit counter if they wish.

#endif

#if ( configTRACK_TASK_MEMORY_ALLOCATIONS == 1 )
uint32_t ulNumberOfHeapAllocations; /* The number of times this task called pvPortMalloc() if using heap_3, 4 or 5. */
uint32_t ulNumberOfHeapFrees; /* The number of times this task called vPortFree() if using heap_3, 4 or 5. */
size_t xHeapBytesCurrentlyHeld; /* The total number of bytes allocated by this task but not yet freed. Any task freeing the heap memory will reduce this count in the task that originally allocated the memory. */
size_t xMaxHeapBytesEverHeld; /* The maximum amount of bytes allocated by this task at any one time. */
#endif
} TaskStatus_t;

/* Possible return values for eTaskConfirmSleepModeStatus(). */
Expand Down Expand Up @@ -3105,6 +3118,16 @@ TaskHandle_t pvTaskIncrementMutexHeldCount( void ) PRIVILEGED_FUNCTION;
*/
void vTaskInternalSetTimeOutState( TimeOut_t * const pxTimeOut ) PRIVILEGED_FUNCTION;

/*
* Only available when configTRACK_TASK_MEMORY_ALLOCATIONS is set to 1. These
* functions are called by the memory allocation schemes to track the amount
* of heap memory used by a task, as well as the number of times a task has
* allocated memory and the number of times a task has freed memory.
*/
size_t xTaskUpdateHeapAllocationStats( TaskHandle_t * pxAllocatingTask,
size_t xAllocationSizeBytes ) PRIVILEGED_FUNCTION;
size_t xTaskUpdateHeapFreedStats( TaskHandle_t pxTaskIn,
size_t xBytesBeingFreed ) PRIVILEGED_FUNCTION;

/* *INDENT-OFF* */
#ifdef __cplusplus
Expand Down
31 changes: 31 additions & 0 deletions portable/MemMang/heap_4.c
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,11 @@ typedef struct A_BLOCK_LINK
{
struct A_BLOCK_LINK * pxNextFreeBlock; /*<< The next free block in the list. */
size_t xBlockSize; /*<< The size of the free block. */

#if( configTRACK_TASK_MEMORY_ALLOCATIONS == 1 )
TaskHandle_t xAllocatingTask; /*<< Handle of the task that made the allocation. */
size_t xRequestedBlockSize; /*<< The size of the block requested, which will be less than xBlockSize as it may be unaligned and does not include the block link structure. */
#endif
} BlockLink_t;

/*-----------------------------------------------------------*/
Expand Down Expand Up @@ -119,6 +124,10 @@ void * pvPortMalloc( size_t xWantedSize )
BlockLink_t * pxBlock, * pxPreviousBlock, * pxNewBlockLink;
void * pvReturn = NULL;

#if( configTRACK_TASK_MEMORY_ALLOCATIONS == 1 )
size_t xOriginalRequestedSize = ( size_t ) xWantedSize;
#endif

vTaskSuspendAll();
{
/* If this is the first call to malloc then the heap will require
Expand Down Expand Up @@ -230,6 +239,18 @@ void * pvPortMalloc( size_t xWantedSize )
mtCOVERAGE_TEST_MARKER();
}

#if( configTRACK_TASK_MEMORY_ALLOCATIONS == 1 )
{
/* Record the amount of heap allocated by the current
* task. Note this will be a little less than the
* actually allocated size as it doesn't account for
* the space allocated for the block link or the
* alignment. */
( void ) xTaskUpdateHeapAllocationStats( &( pxBlock->xAllocatingTask ), xOriginalRequestedSize );
pxBlock->xRequestedBlockSize = xOriginalRequestedSize;
}
#endif

/* The block is being returned - it is allocated and owned
* by the application and has no "next" block. */
pxBlock->xBlockSize |= xBlockAllocatedBit;
Expand Down Expand Up @@ -300,6 +321,16 @@ void vPortFree( void * pv )
* allocated. */
pxLink->xBlockSize &= ~xBlockAllocatedBit;

#if( configTRACK_TASK_MEMORY_ALLOCATIONS == 1 )
{
/* Reduce the amount of RAM recorded as being currently
* allocated in the task that originally allocated the
* memory - which might be different to the task that is
* freeing the memory. */
( void ) xTaskUpdateHeapFreedStats( pxLink->xAllocatingTask, pxLink->xRequestedBlockSize );
}
#endif

vTaskSuspendAll();
{
/* Add this block to the list of free blocks. */
Expand Down
31 changes: 31 additions & 0 deletions portable/MemMang/heap_5.c
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,11 @@ typedef struct A_BLOCK_LINK
{
struct A_BLOCK_LINK * pxNextFreeBlock; /*<< The next free block in the list. */
size_t xBlockSize; /*<< The size of the free block. */

#if( configTRACK_TASK_MEMORY_ALLOCATIONS == 1 )
TaskHandle_t xAllocatingTask; /*<< Handle of the task that made the allocation. */
size_t xRequestedBlockSize; /*<< The size of the block requested, which will be less than xBlockSize as it may be unaligned and does not include the block link structure. */
#endif
} BlockLink_t;

/*-----------------------------------------------------------*/
Expand Down Expand Up @@ -137,6 +142,10 @@ void * pvPortMalloc( size_t xWantedSize )
BlockLink_t * pxBlock, * pxPreviousBlock, * pxNewBlockLink;
void * pvReturn = NULL;

#if( configTRACK_TASK_MEMORY_ALLOCATIONS == 1 )
size_t xOriginalRequestedSize = ( size_t ) xWantedSize;
#endif

/* The heap must be initialised before the first call to
* prvPortMalloc(). */
configASSERT( pxEnd );
Expand Down Expand Up @@ -239,6 +248,18 @@ void * pvPortMalloc( size_t xWantedSize )
mtCOVERAGE_TEST_MARKER();
}

#if( configTRACK_TASK_MEMORY_ALLOCATIONS == 1 )
{
/* Record the amount of heap allocated by the current
* task. Note this will be a little less than the
* actually allocated size as it doesn't account for
* the space allocated for the block link or the
* alignment. */
( void ) xTaskUpdateHeapAllocationStats( &( pxBlock->xAllocatingTask ), xOriginalRequestedSize );
pxBlock->xRequestedBlockSize = xOriginalRequestedSize;
}
#endif

/* The block is being returned - it is allocated and owned
* by the application and has no "next" block. */
pxBlock->xBlockSize |= xBlockAllocatedBit;
Expand Down Expand Up @@ -308,6 +329,16 @@ void vPortFree( void * pv )
* allocated. */
pxLink->xBlockSize &= ~xBlockAllocatedBit;

#if( configTRACK_TASK_MEMORY_ALLOCATIONS == 1 )
{
/* Reduce the amount of RAM recorded as being currently
* allocated in the task that originally allocated the
* memory - which might be different to the task that is
* freeing the memory. */
xTaskUpdateHeapFreedStats( pxLink->xAllocatingTask, pxLink->xRequestedBlockSize );
}
#endif

vTaskSuspendAll();
{
/* Add this block to the list of free blocks. */
Expand Down
Loading