mirror of
https://github.com/espressif/esp-idf.git
synced 2025-08-06 14:14:33 +02:00
Merge branch 'refactor/refactor-freertos-tls-del-cb' into 'master'
freertos-smp: refactor thread local storage pointers deletion callbacks Closes IDF-3330 See merge request espressif/esp-idf!17972
This commit is contained in:
@@ -1229,11 +1229,6 @@ typedef struct xSTATIC_TCB
|
|||||||
#endif
|
#endif
|
||||||
#if ( configNUM_THREAD_LOCAL_STORAGE_POINTERS > 0 )
|
#if ( configNUM_THREAD_LOCAL_STORAGE_POINTERS > 0 )
|
||||||
void * pvDummy15[ configNUM_THREAD_LOCAL_STORAGE_POINTERS ];
|
void * pvDummy15[ configNUM_THREAD_LOCAL_STORAGE_POINTERS ];
|
||||||
#ifdef ESP_PLATFORM
|
|
||||||
#if ( configTHREAD_LOCAL_STORAGE_DELETE_CALLBACKS )
|
|
||||||
void *pvDummaTLSDelCb[ configNUM_THREAD_LOCAL_STORAGE_POINTERS ];
|
|
||||||
#endif
|
|
||||||
#endif //ESP_PLATFORM
|
|
||||||
#endif
|
#endif
|
||||||
#if ( configGENERATE_RUN_TIME_STATS == 1 )
|
#if ( configGENERATE_RUN_TIME_STATS == 1 )
|
||||||
uint32_t ulDummy16;
|
uint32_t ulDummy16;
|
||||||
|
@@ -3279,39 +3279,6 @@ void vTaskYieldWithinAPI( void );
|
|||||||
|
|
||||||
#ifdef ESP_PLATFORM
|
#ifdef ESP_PLATFORM
|
||||||
|
|
||||||
#if ( configTHREAD_LOCAL_STORAGE_DELETE_CALLBACKS )
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Prototype of local storage pointer deletion callback.
|
|
||||||
*/
|
|
||||||
typedef void (*TlsDeleteCallbackFunction_t)( int, void * );
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set local storage pointer and deletion callback.
|
|
||||||
*
|
|
||||||
* Each task contains an array of pointers that is dimensioned by the
|
|
||||||
* configNUM_THREAD_LOCAL_STORAGE_POINTERS setting in FreeRTOSConfig.h.
|
|
||||||
* The kernel does not use the pointers itself, so the application writer
|
|
||||||
* can use the pointers for any purpose they wish.
|
|
||||||
*
|
|
||||||
* Local storage pointers set for a task can reference dynamically
|
|
||||||
* allocated resources. This function is similar to
|
|
||||||
* vTaskSetThreadLocalStoragePointer, but provides a way to release
|
|
||||||
* these resources when the task gets deleted. For each pointer,
|
|
||||||
* a callback function can be set. This function will be called
|
|
||||||
* when task is deleted, with the local storage pointer index
|
|
||||||
* and value as arguments.
|
|
||||||
*
|
|
||||||
* @param xTaskToSet Task to set thread local storage pointer for
|
|
||||||
* @param xIndex The index of the pointer to set, from 0 to
|
|
||||||
* configNUM_THREAD_LOCAL_STORAGE_POINTERS - 1.
|
|
||||||
* @param pvValue Pointer value to set.
|
|
||||||
* @param pvDelCallback Function to call to dispose of the local
|
|
||||||
* storage pointer when the task is deleted.
|
|
||||||
*/
|
|
||||||
void vTaskSetThreadLocalStoragePointerAndDelCallback( TaskHandle_t xTaskToSet, BaseType_t xIndex, void *pvValue, TlsDeleteCallbackFunction_t pvDelCallback);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "idf_additions.h"
|
#include "idf_additions.h"
|
||||||
|
|
||||||
#endif //ESP_PLATFORM
|
#endif //ESP_PLATFORM
|
||||||
|
@@ -164,7 +164,17 @@ This file get's pulled into assembly sources. Therefore, some includes need to b
|
|||||||
|
|
||||||
#define configMAX_TASK_NAME_LEN CONFIG_FREERTOS_MAX_TASK_NAME_LEN
|
#define configMAX_TASK_NAME_LEN CONFIG_FREERTOS_MAX_TASK_NAME_LEN
|
||||||
|
|
||||||
|
#if ( CONFIG_FREERTOS_TLSP_DELETION_CALLBACKS )
|
||||||
|
/* If thread local storage pointer deletion callbacks are registered
|
||||||
|
* then we double the storage space reserved for the thread local
|
||||||
|
* storage pointers in the task TCB. The first half of the storage area
|
||||||
|
* is used to store the TLS pointers themselves while the second half
|
||||||
|
* is used to store the respective deletion callbacks.
|
||||||
|
*/
|
||||||
|
#define configNUM_THREAD_LOCAL_STORAGE_POINTERS ( CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS * 2 )
|
||||||
|
#else
|
||||||
#define configNUM_THREAD_LOCAL_STORAGE_POINTERS CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS
|
#define configNUM_THREAD_LOCAL_STORAGE_POINTERS CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS
|
||||||
|
#endif // CONFIG_FREERTOS_TLSP_DELETION_CALLBACKS
|
||||||
#define configSTACK_DEPTH_TYPE uint32_t
|
#define configSTACK_DEPTH_TYPE uint32_t
|
||||||
#define configUSE_NEWLIB_REENTRANT 1
|
#define configUSE_NEWLIB_REENTRANT 1
|
||||||
#define configENABLE_BACKWARD_COMPATIBILITY 0
|
#define configENABLE_BACKWARD_COMPATIBILITY 0
|
||||||
@@ -276,8 +286,6 @@ Default values for trace macros added by ESP-IDF and are not part of Vanilla Fre
|
|||||||
#define configTASKLIST_INCLUDE_COREID 1
|
#define configTASKLIST_INCLUDE_COREID 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define configTHREAD_LOCAL_STORAGE_DELETE_CALLBACKS 1
|
|
||||||
|
|
||||||
#ifndef __ASSEMBLER__
|
#ifndef __ASSEMBLER__
|
||||||
#if CONFIG_APPTRACE_SV_ENABLE
|
#if CONFIG_APPTRACE_SV_ENABLE
|
||||||
extern uint32_t port_switch_flag[];
|
extern uint32_t port_switch_flag[];
|
||||||
|
@@ -579,6 +579,38 @@ void vPortCleanUpCoprocArea( void * pxTCB )
|
|||||||
}
|
}
|
||||||
#endif /* XCHAL_CP_NUM > 0 */
|
#endif /* XCHAL_CP_NUM > 0 */
|
||||||
|
|
||||||
|
// ------- Thread Local Storage Pointers Deletion Callbacks -------
|
||||||
|
|
||||||
|
#if ( CONFIG_FREERTOS_TLSP_DELETION_CALLBACKS )
|
||||||
|
void vPortTLSPointersDelCb( void * pxTCB )
|
||||||
|
{
|
||||||
|
/* Typecast pxTCB to StaticTask_t type to access TCB struct members.
|
||||||
|
* pvDummy15 corresponds to pvThreadLocalStoragePointers member of the TCB.
|
||||||
|
*/
|
||||||
|
StaticTask_t *tcb = ( StaticTask_t * )pxTCB;
|
||||||
|
|
||||||
|
/* The TLSP deletion callbacks are stored at an offset of (configNUM_THREAD_LOCAL_STORAGE_POINTERS/2) */
|
||||||
|
TlsDeleteCallbackFunction_t *pvThreadLocalStoragePointersDelCallback = ( TlsDeleteCallbackFunction_t * )( &( tcb->pvDummy15[ ( configNUM_THREAD_LOCAL_STORAGE_POINTERS / 2 ) ] ) );
|
||||||
|
|
||||||
|
/* We need to iterate over half the depth of the pvThreadLocalStoragePointers area
|
||||||
|
* to access all TLS pointers and their respective TLS deletion callbacks.
|
||||||
|
*/
|
||||||
|
for( int x = 0; x < ( configNUM_THREAD_LOCAL_STORAGE_POINTERS / 2 ); x++ )
|
||||||
|
{
|
||||||
|
if ( pvThreadLocalStoragePointersDelCallback[ x ] != NULL ) //If del cb is set
|
||||||
|
{
|
||||||
|
/* In case the TLSP deletion callback has been overwritten by a TLS pointer, gracefully abort. */
|
||||||
|
if ( !esp_ptr_executable( pvThreadLocalStoragePointersDelCallback[ x ] ) ) {
|
||||||
|
ESP_LOGE("FreeRTOS", "Fatal error: TLSP deletion callback at index %d overwritten with non-excutable pointer %p", x, pvThreadLocalStoragePointersDelCallback[ x ]);
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
|
||||||
|
pvThreadLocalStoragePointersDelCallback[ x ]( x, tcb->pvDummy15[ x ] ); //Call del cb
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif // CONFIG_FREERTOS_TLSP_DELETION_CALLBACKS
|
||||||
|
|
||||||
// -------------------- Tick Handler -----------------------
|
// -------------------- Tick Handler -----------------------
|
||||||
|
|
||||||
extern void esp_vApplicationIdleHook(void);
|
extern void esp_vApplicationIdleHook(void);
|
||||||
@@ -655,11 +687,14 @@ void vApplicationMinimalIdleHook( void )
|
|||||||
/*
|
/*
|
||||||
* Hook function called during prvDeleteTCB() to cleanup any
|
* Hook function called during prvDeleteTCB() to cleanup any
|
||||||
* user defined static memory areas in the TCB.
|
* user defined static memory areas in the TCB.
|
||||||
* Currently, this hook function is used by the port to cleanup
|
|
||||||
* the Co-processor save area for targets that support co-processors.
|
|
||||||
*/
|
*/
|
||||||
void vPortCleanUpTCB ( void *pxTCB )
|
void vPortCleanUpTCB ( void *pxTCB )
|
||||||
{
|
{
|
||||||
|
#if ( CONFIG_FREERTOS_TLSP_DELETION_CALLBACKS )
|
||||||
|
/* Call TLS pointers deletion callbacks */
|
||||||
|
vPortTLSPointersDelCb( pxTCB );
|
||||||
|
#endif /* CONFIG_FREERTOS_TLSP_DELETION_CALLBACKS */
|
||||||
|
|
||||||
#if XCHAL_CP_NUM > 0
|
#if XCHAL_CP_NUM > 0
|
||||||
/* Cleanup coproc save area */
|
/* Cleanup coproc save area */
|
||||||
vPortCleanUpCoprocArea( pxTCB );
|
vPortCleanUpCoprocArea( pxTCB );
|
||||||
|
@@ -286,11 +286,6 @@ typedef struct tskTaskControlBlock /* The old naming convention is used to
|
|||||||
|
|
||||||
#if ( configNUM_THREAD_LOCAL_STORAGE_POINTERS > 0 )
|
#if ( configNUM_THREAD_LOCAL_STORAGE_POINTERS > 0 )
|
||||||
void * pvThreadLocalStoragePointers[ configNUM_THREAD_LOCAL_STORAGE_POINTERS ];
|
void * pvThreadLocalStoragePointers[ configNUM_THREAD_LOCAL_STORAGE_POINTERS ];
|
||||||
#ifdef ESP_PLATFORM
|
|
||||||
#if ( configTHREAD_LOCAL_STORAGE_DELETE_CALLBACKS )
|
|
||||||
TlsDeleteCallbackFunction_t pvThreadLocalStoragePointersDelCallback[ configNUM_THREAD_LOCAL_STORAGE_POINTERS ];
|
|
||||||
#endif
|
|
||||||
#endif //ESP_PLATFORM
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if ( configGENERATE_RUN_TIME_STATS == 1 )
|
#if ( configGENERATE_RUN_TIME_STATS == 1 )
|
||||||
@@ -1544,11 +1539,6 @@ static void prvInitialiseNewTask( TaskFunction_t pxTaskCode,
|
|||||||
#if ( configNUM_THREAD_LOCAL_STORAGE_POINTERS != 0 )
|
#if ( configNUM_THREAD_LOCAL_STORAGE_POINTERS != 0 )
|
||||||
{
|
{
|
||||||
memset( ( void * ) &( pxNewTCB->pvThreadLocalStoragePointers[ 0 ] ), 0x00, sizeof( pxNewTCB->pvThreadLocalStoragePointers ) );
|
memset( ( void * ) &( pxNewTCB->pvThreadLocalStoragePointers[ 0 ] ), 0x00, sizeof( pxNewTCB->pvThreadLocalStoragePointers ) );
|
||||||
#ifdef ESP_PLATFORM
|
|
||||||
#if ( configTHREAD_LOCAL_STORAGE_DELETE_CALLBACKS )
|
|
||||||
memset ( (void * ) &( pxNewTCB->pvThreadLocalStoragePointersDelCallback[0] ), 0x00, sizeof( pxNewTCB->pvThreadLocalStoragePointersDelCallback ) );
|
|
||||||
#endif
|
|
||||||
#endif //ESP_PLATFORM
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -4928,17 +4918,6 @@ static void prvCheckTasksWaitingTermination( void )
|
|||||||
|
|
||||||
static void prvDeleteTCB( TCB_t * pxTCB )
|
static void prvDeleteTCB( TCB_t * pxTCB )
|
||||||
{
|
{
|
||||||
#ifdef ESP_PLATFORM
|
|
||||||
#if ( configTHREAD_LOCAL_STORAGE_DELETE_CALLBACKS )
|
|
||||||
for( int x = 0; x < configNUM_THREAD_LOCAL_STORAGE_POINTERS; x++ )
|
|
||||||
{
|
|
||||||
if (pxTCB->pvThreadLocalStoragePointersDelCallback[ x ] != NULL) //If del cb is set
|
|
||||||
{
|
|
||||||
pxTCB->pvThreadLocalStoragePointersDelCallback[ x ](x, pxTCB->pvThreadLocalStoragePointers[ x ]); //Call del cb
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#endif //ESP_PLATFORM
|
|
||||||
|
|
||||||
/* This call is required specifically for the TriCore port. It must be
|
/* This call is required specifically for the TriCore port. It must be
|
||||||
* above the vPortFree() calls. The call is also used by ports/demos that
|
* above the vPortFree() calls. The call is also used by ports/demos that
|
||||||
@@ -6467,19 +6446,6 @@ static void prvAddCurrentTaskToDelayedList( TickType_t xTicksToWait,
|
|||||||
* ------------------------------------------------------------------------------------------------------------------ */
|
* ------------------------------------------------------------------------------------------------------------------ */
|
||||||
|
|
||||||
#ifdef ESP_PLATFORM
|
#ifdef ESP_PLATFORM
|
||||||
|
|
||||||
#if ( configTHREAD_LOCAL_STORAGE_DELETE_CALLBACKS )
|
|
||||||
void vTaskSetThreadLocalStoragePointerAndDelCallback( TaskHandle_t xTaskToSet, BaseType_t xIndex, void *pvValue , TlsDeleteCallbackFunction_t xDelCallback)
|
|
||||||
{
|
|
||||||
//Set the local storage pointer first
|
|
||||||
vTaskSetThreadLocalStoragePointer(xTaskToSet, xIndex, pvValue);
|
|
||||||
//Set the deletion callback
|
|
||||||
TCB_t * pxTCB;
|
|
||||||
pxTCB = prvGetTCBFromHandle( xTaskToSet );
|
|
||||||
pxTCB->pvThreadLocalStoragePointersDelCallback[ xIndex ] = xDelCallback;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if ( configUSE_NEWLIB_REENTRANT == 1 )
|
#if ( configUSE_NEWLIB_REENTRANT == 1 )
|
||||||
//Return global reent struct if FreeRTOS isn't running,
|
//Return global reent struct if FreeRTOS isn't running,
|
||||||
struct _reent* __getreent(void) {
|
struct _reent* __getreent(void) {
|
||||||
|
@@ -183,6 +183,17 @@ menu "FreeRTOS"
|
|||||||
This value must be at least 1. Index 0 is reserved for use by the pthreads API
|
This value must be at least 1. Index 0 is reserved for use by the pthreads API
|
||||||
thread-local-storage. Other indexes can be used for any desired purpose.
|
thread-local-storage. Other indexes can be used for any desired purpose.
|
||||||
|
|
||||||
|
config FREERTOS_TLSP_DELETION_CALLBACKS
|
||||||
|
bool "Enable thread local storage pointers deletion callbacks"
|
||||||
|
depends on FREERTOS_SMP && (FREERTOS_THREAD_LOCAL_STORAGE_POINTERS > 0)
|
||||||
|
default y
|
||||||
|
help
|
||||||
|
ESP-IDF provides users with the ability to free TLSP memory by registering TLSP deletion callbacks.
|
||||||
|
These callbacks are automatically called by FreeRTOS when a task is deleted.
|
||||||
|
When this option is turned on, the memory reserved for TLSPs in the TCB is doubled
|
||||||
|
to make space for storing the deletion callbacks. If the user does not wish to use TLSP deletion
|
||||||
|
callbacks then this option could be turned off to save space in the TCB memory.
|
||||||
|
|
||||||
config FREERTOS_IDLE_TASK_STACKSIZE
|
config FREERTOS_IDLE_TASK_STACKSIZE
|
||||||
int "Idle Task stack size"
|
int "Idle Task stack size"
|
||||||
range 768 32768
|
range 768 32768
|
||||||
|
@@ -103,4 +103,41 @@ TaskHandle_t xTaskGetIdleTaskHandleForCPU( BaseType_t xCoreID );
|
|||||||
*/
|
*/
|
||||||
BaseType_t xTaskGetAffinity( TaskHandle_t xTask );
|
BaseType_t xTaskGetAffinity( TaskHandle_t xTask );
|
||||||
|
|
||||||
|
#if ( CONFIG_FREERTOS_TLSP_DELETION_CALLBACKS )
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prototype of local storage pointer deletion callback.
|
||||||
|
*/
|
||||||
|
typedef void (*TlsDeleteCallbackFunction_t)( int, void * );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set local storage pointer and deletion callback.
|
||||||
|
*
|
||||||
|
* Each task contains an array of pointers that is dimensioned by the
|
||||||
|
* configNUM_THREAD_LOCAL_STORAGE_POINTERS setting in FreeRTOSConfig.h.
|
||||||
|
* The kernel does not use the pointers itself, so the application writer
|
||||||
|
* can use the pointers for any purpose they wish.
|
||||||
|
*
|
||||||
|
* Local storage pointers set for a task can reference dynamically
|
||||||
|
* allocated resources. This function is similar to
|
||||||
|
* vTaskSetThreadLocalStoragePointer, but provides a way to release
|
||||||
|
* these resources when the task gets deleted. For each pointer,
|
||||||
|
* a callback function can be set. This function will be called
|
||||||
|
* when task is deleted, with the local storage pointer index
|
||||||
|
* and value as arguments.
|
||||||
|
*
|
||||||
|
* @param xTaskToSet Task to set thread local storage pointer for
|
||||||
|
* @param xIndex The index of the pointer to set, from 0 to
|
||||||
|
* configNUM_THREAD_LOCAL_STORAGE_POINTERS - 1.
|
||||||
|
* @param pvValue Pointer value to set.
|
||||||
|
* @param pvDelCallback Function to call to dispose of the local
|
||||||
|
* storage pointer when the task is deleted.
|
||||||
|
*/
|
||||||
|
void vTaskSetThreadLocalStoragePointerAndDelCallback(
|
||||||
|
TaskHandle_t xTaskToSet,
|
||||||
|
BaseType_t xIndex,
|
||||||
|
void *pvValue,
|
||||||
|
TlsDeleteCallbackFunction_t pvDelCallback);
|
||||||
|
#endif // CONFIG_FREERTOS_TLSP_DELETION_CALLBACKS
|
||||||
|
|
||||||
#endif // CONFIG_FREERTOS_SMP || __DOXYGEN__
|
#endif // CONFIG_FREERTOS_SMP || __DOXYGEN__
|
||||||
|
@@ -342,4 +342,20 @@ BaseType_t xTaskGetAffinity( TaskHandle_t xTask )
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if ( CONFIG_FREERTOS_TLSP_DELETION_CALLBACKS )
|
||||||
|
void vTaskSetThreadLocalStoragePointerAndDelCallback( TaskHandle_t xTaskToSet, BaseType_t xIndex, void *pvValue, TlsDeleteCallbackFunction_t pvDelCallback)
|
||||||
|
{
|
||||||
|
// Verify that the offsets of pvThreadLocalStoragePointers and pvDummy15 match.
|
||||||
|
// pvDummy15 is part of the StaticTask_t struct and is used to access the TLSPs
|
||||||
|
// while deletion.
|
||||||
|
_Static_assert(offsetof( StaticTask_t, pvDummy15 ) == offsetof( TCB_t, pvThreadLocalStoragePointers ), "Offset of pvDummy15 must match the offset of pvThreadLocalStoragePointers");
|
||||||
|
|
||||||
|
//Set the local storage pointer first
|
||||||
|
vTaskSetThreadLocalStoragePointer( xTaskToSet, xIndex, pvValue );
|
||||||
|
|
||||||
|
//Set the deletion callback at an offset of configNUM_THREAD_LOCAL_STORAGE_POINTERS/2
|
||||||
|
vTaskSetThreadLocalStoragePointer( xTaskToSet, ( xIndex + ( configNUM_THREAD_LOCAL_STORAGE_POINTERS / 2 ) ), pvDelCallback );
|
||||||
|
}
|
||||||
|
#endif // CONFIG_FREERTOS_TLSP_DELETION_CALLBACKS
|
||||||
|
|
||||||
#endif // CONFIG_FREERTOS_SMP
|
#endif // CONFIG_FREERTOS_SMP
|
||||||
|
Reference in New Issue
Block a user