From 5f2443b7d14e32bf693d29c05e31e7b33f35593e Mon Sep 17 00:00:00 2001 From: Darian Leung Date: Tue, 22 Aug 2023 23:41:20 +0800 Subject: [PATCH 1/2] refactor(freertos): Remove portCLEAN_UP_COPROC() portCLEAN_UP_COPROC() was an IDF specific addition to FreeRTOS, where the macro was called from prvDeleteTCB() to clean up the coprocessor context of a deleted task. This commit removes portCLEAN_UP_COPROC(). The coprocessor cleanup routine (i.e., vPortCleanUpCoprocArea()) is now called via portCLEAN_UP_TCB()-> vPortTCBPreDeleteHook(). This removes a minor code difference between IDF FreeRTOS and upstream. --- .../xtensa/include/freertos/portmacro.h | 7 --- .../FreeRTOS-Kernel/portable/xtensa/port.c | 46 ++++++++++--------- components/freertos/FreeRTOS-Kernel/tasks.c | 4 -- components/freertos/linker.lf | 4 +- 4 files changed, 27 insertions(+), 34 deletions(-) diff --git a/components/freertos/FreeRTOS-Kernel/portable/xtensa/include/freertos/portmacro.h b/components/freertos/FreeRTOS-Kernel/portable/xtensa/include/freertos/portmacro.h index 5a19389fcf..6a44c2817a 100644 --- a/components/freertos/FreeRTOS-Kernel/portable/xtensa/include/freertos/portmacro.h +++ b/components/freertos/FreeRTOS-Kernel/portable/xtensa/include/freertos/portmacro.h @@ -647,13 +647,6 @@ FORCE_INLINE_ATTR BaseType_t xPortGetCoreID(void) * - These are not part of the FreeRTOS porting interface, but are used by other FreeRTOS dependent components * ------------------------------------------------------------------------------------------------------------------ */ -// -------------------- Co-Processor ----------------------- - -#if XCHAL_CP_NUM > 0 -void vPortCleanUpCoprocArea(void *pvTCB); -#define portCLEAN_UP_COPROC(pvTCB) vPortCleanUpCoprocArea(pvTCB) -#endif - // -------------------- Heap Related ----------------------- /** diff --git a/components/freertos/FreeRTOS-Kernel/portable/xtensa/port.c b/components/freertos/FreeRTOS-Kernel/portable/xtensa/port.c index ab4120e267..5ab57f22d0 100644 --- a/components/freertos/FreeRTOS-Kernel/portable/xtensa/port.c +++ b/components/freertos/FreeRTOS-Kernel/portable/xtensa/port.c @@ -607,6 +607,25 @@ void vPortSetStackWatchpoint( void *pxStackStart ) // --------------------- TCB Cleanup ----------------------- +#if ( XCHAL_CP_NUM > 0 ) +static void vPortCleanUpCoprocArea(void *pvTCB) +{ + UBaseType_t uxCoprocArea; + BaseType_t xTargetCoreID; + + /* Get a pointer to the task's coprocessor save area */ + uxCoprocArea = ( UBaseType_t ) ( ( ( StaticTask_t * ) pvTCB )->pxDummy8 ); /* Get TCB_t.pxEndOfStack */ + uxCoprocArea = STACKPTR_ALIGN_DOWN(16, uxCoprocArea - XT_CP_SIZE); + + /* Get xTargetCoreID from the TCB.xCoreID */ + xTargetCoreID = ( ( StaticTask_t * ) pvTCB )->xDummyCoreID; + + /* If task has live floating point registers somewhere, release them */ + void _xt_coproc_release(volatile void *coproc_sa_base, BaseType_t xTargetCoreID); + _xt_coproc_release( (void *)uxCoprocArea, xTargetCoreID ); +} +#endif /* XCHAL_CP_NUM > 0 */ + void vPortTCBPreDeleteHook( void *pxTCB ) { #if ( CONFIG_FREERTOS_TASK_PRE_DELETION_HOOK ) @@ -624,26 +643,9 @@ void vPortTCBPreDeleteHook( void *pxTCB ) extern void vPortCleanUpTCB( void * pxTCB ); vPortCleanUpTCB( pxTCB ); #endif /* CONFIG_FREERTOS_ENABLE_STATIC_TASK_CLEAN_UP */ + + #if ( XCHAL_CP_NUM > 0 ) + /* Cleanup coproc save area */ + vPortCleanUpCoprocArea( pxTCB ); + #endif /* XCHAL_CP_NUM > 0 */ } - -// -------------------- Co-Processor ----------------------- - -#if XCHAL_CP_NUM > 0 -void _xt_coproc_release(volatile void *coproc_sa_base, BaseType_t xTargetCoreID); - -void vPortCleanUpCoprocArea(void *pvTCB) -{ - UBaseType_t uxCoprocArea; - BaseType_t xTargetCoreID; - - /* Get a pointer to the task's coprocessor save area */ - uxCoprocArea = ( UBaseType_t ) ( ( ( StaticTask_t * ) pvTCB )->pxDummy8 ); /* Get TCB_t.pxEndOfStack */ - uxCoprocArea = STACKPTR_ALIGN_DOWN(16, uxCoprocArea - XT_CP_SIZE); - - /* Get xTargetCoreID from the TCB.xCoreID */ - xTargetCoreID = ( ( StaticTask_t * ) pvTCB )->xDummyCoreID; - - /* If task has live floating point registers somewhere, release them */ - _xt_coproc_release( (void *)uxCoprocArea, xTargetCoreID ); -} -#endif /* XCHAL_CP_NUM > 0 */ diff --git a/components/freertos/FreeRTOS-Kernel/tasks.c b/components/freertos/FreeRTOS-Kernel/tasks.c index 0c68ee8357..88fd618de6 100644 --- a/components/freertos/FreeRTOS-Kernel/tasks.c +++ b/components/freertos/FreeRTOS-Kernel/tasks.c @@ -4951,10 +4951,6 @@ BaseType_t xTaskGetAffinity( TaskHandle_t xTask ) vPortReleaseTaskMPUSettings( &( pxTCB->xMPUSettings ) ); #endif - #ifdef portCLEAN_UP_COPROC - portCLEAN_UP_COPROC( ( void * ) pxTCB ); - #endif - #if ( ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 0 ) && ( portUSING_MPU_WRAPPERS == 0 ) ) { /* The task can only have been allocated dynamically - free both diff --git a/components/freertos/linker.lf b/components/freertos/linker.lf index 9e83b142fa..e7e75a3845 100644 --- a/components/freertos/linker.lf +++ b/components/freertos/linker.lf @@ -233,9 +233,10 @@ entries: port:xPortStartScheduler (default) port:vPortEndScheduler (default) port:pxPortInitialiseStack (default) + port:xPortGetTickRateHz (default) if IDF_TARGET_ESP32 = y || IDF_TARGET_ESP32S3 = y : port:vPortCleanUpCoprocArea (default) - port:xPortGetTickRateHz (default) + port:vPortTCBPreDeleteHook (default) # -------------------------------------------------------------------------------------------------------------- # portable/riscv/port.c # - Most functions are called from an ISR context, except for scheduler/task init/deinit functions @@ -245,3 +246,4 @@ entries: port:vPortEndScheduler (default) port:pxPortInitialiseStack (default) port:xPortGetTickRateHz (default) + port:vPortTCBPreDeleteHook (default) From 57eb41ce83f27b3c976e9cea3b770dc6800ceb06 Mon Sep 17 00:00:00 2001 From: Darian Leung Date: Wed, 23 Aug 2023 00:45:54 +0800 Subject: [PATCH 2/2] refactor(freertos): Call TLSP deletion callback from portCLEAN_UP_TCB() Previously, TLSP deletion callbacks were... - Stored in a seprate TCB member "pvThreadLocalStoragePointersDelCallback" - Called separately via multipole prvDeleteTLS() insertions in tasks.c This commit refactors how TLSP deletion callbacks are stored and called: - TLSP deletion callbacks are now stored in "pvThreadLocalStoragePointers" directly. configNUM_THREAD_LOCAL_STORAGE_POINTERS is doubled in size so that the deletion callbacks are stored in the latter half of the array - The callbacks are now called via "portCLEAN_UP_TCB()". As such, the prvDeleteTLS() additions are no longer needed and the function can be removed - Removed some legacy TLSP tests using the old method of storing the callback pointers. This commit reduces the source code diff between IDF FreeRTOS and upstream vanilla FreeRTOS, in preparation for v10.5.1 upgrade. --- .../include/freertos/FreeRTOS.h | 3 - .../FreeRTOS-Kernel/portable/riscv/port.c | 33 ++++++++++ .../FreeRTOS-Kernel/portable/xtensa/port.c | 34 ++++++++++ components/freertos/FreeRTOS-Kernel/tasks.c | 63 +++++------------- .../config/include/freertos/FreeRTOSConfig.h | 15 +++-- components/freertos/linker.lf | 5 +- .../freertos/port/test_tlsp_del_cb.c | 65 ------------------- .../kernel_tests/port/test_tlsp_del_cb.c | 64 ------------------ 8 files changed, 97 insertions(+), 185 deletions(-) diff --git a/components/freertos/FreeRTOS-Kernel/include/freertos/FreeRTOS.h b/components/freertos/FreeRTOS-Kernel/include/freertos/FreeRTOS.h index 4df12a4031..e6b6916ab9 100644 --- a/components/freertos/FreeRTOS-Kernel/include/freertos/FreeRTOS.h +++ b/components/freertos/FreeRTOS-Kernel/include/freertos/FreeRTOS.h @@ -1247,9 +1247,6 @@ typedef struct xSTATIC_TCB #endif #if ( configNUM_THREAD_LOCAL_STORAGE_POINTERS > 0 ) void * pvDummy15[ configNUM_THREAD_LOCAL_STORAGE_POINTERS ]; - #if ( configTHREAD_LOCAL_STORAGE_DELETE_CALLBACKS == 1 ) - void * pvDummyLocalStorageCallBack[ configNUM_THREAD_LOCAL_STORAGE_POINTERS ]; - #endif #endif #if ( configGENERATE_RUN_TIME_STATS == 1 ) uint32_t ulDummy16; diff --git a/components/freertos/FreeRTOS-Kernel/portable/riscv/port.c b/components/freertos/FreeRTOS-Kernel/portable/riscv/port.c index fda5f44e0d..3682aa7aa8 100644 --- a/components/freertos/FreeRTOS-Kernel/portable/riscv/port.c +++ b/components/freertos/FreeRTOS-Kernel/portable/riscv/port.c @@ -591,6 +591,34 @@ void vPortSetStackWatchpoint(void *pxStackStart) // --------------------- TCB Cleanup ----------------------- +#if ( CONFIG_FREERTOS_TLSP_DELETION_CALLBACKS ) +static 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 */ + void vPortTCBPreDeleteHook( void *pxTCB ) { #if ( CONFIG_FREERTOS_TASK_PRE_DELETION_HOOK ) @@ -608,6 +636,11 @@ void vPortTCBPreDeleteHook( void *pxTCB ) extern void vPortCleanUpTCB( void * pxTCB ); vPortCleanUpTCB( pxTCB ); #endif /* CONFIG_FREERTOS_ENABLE_STATIC_TASK_CLEAN_UP */ + + #if ( CONFIG_FREERTOS_TLSP_DELETION_CALLBACKS ) + /* Call TLS pointers deletion callbacks */ + vPortTLSPointersDelCb( pxTCB ); + #endif /* CONFIG_FREERTOS_TLSP_DELETION_CALLBACKS */ } /* ---------------------------------------------- Misc Implementations ------------------------------------------------- diff --git a/components/freertos/FreeRTOS-Kernel/portable/xtensa/port.c b/components/freertos/FreeRTOS-Kernel/portable/xtensa/port.c index 5ab57f22d0..92b7174141 100644 --- a/components/freertos/FreeRTOS-Kernel/portable/xtensa/port.c +++ b/components/freertos/FreeRTOS-Kernel/portable/xtensa/port.c @@ -607,6 +607,35 @@ void vPortSetStackWatchpoint( void *pxStackStart ) // --------------------- TCB Cleanup ----------------------- +#if ( CONFIG_FREERTOS_TLSP_DELETION_CALLBACKS ) +static 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 ] ) ) { + // We call EARLY log here as currently portCLEAN_UP_TCB() is called in a critical section + ESP_EARLY_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 */ + #if ( XCHAL_CP_NUM > 0 ) static void vPortCleanUpCoprocArea(void *pvTCB) { @@ -644,6 +673,11 @@ void vPortTCBPreDeleteHook( void *pxTCB ) vPortCleanUpTCB( pxTCB ); #endif /* CONFIG_FREERTOS_ENABLE_STATIC_TASK_CLEAN_UP */ + #if ( CONFIG_FREERTOS_TLSP_DELETION_CALLBACKS ) + /* Call TLS pointers deletion callbacks */ + vPortTLSPointersDelCb( pxTCB ); + #endif /* CONFIG_FREERTOS_TLSP_DELETION_CALLBACKS */ + #if ( XCHAL_CP_NUM > 0 ) /* Cleanup coproc save area */ vPortCleanUpCoprocArea( pxTCB ); diff --git a/components/freertos/FreeRTOS-Kernel/tasks.c b/components/freertos/FreeRTOS-Kernel/tasks.c index 88fd618de6..9487213e2a 100644 --- a/components/freertos/FreeRTOS-Kernel/tasks.c +++ b/components/freertos/FreeRTOS-Kernel/tasks.c @@ -379,9 +379,6 @@ typedef struct tskTaskControlBlock /* The old naming convention is used to #if ( configNUM_THREAD_LOCAL_STORAGE_POINTERS > 0 ) void * pvThreadLocalStoragePointers[ configNUM_THREAD_LOCAL_STORAGE_POINTERS ]; - #if ( configTHREAD_LOCAL_STORAGE_DELETE_CALLBACKS == 1 ) - TlsDeleteCallbackFunction_t pvThreadLocalStoragePointersDelCallback[ configNUM_THREAD_LOCAL_STORAGE_POINTERS ]; - #endif #endif #if ( configGENERATE_RUN_TIME_STATS == 1 ) @@ -572,13 +569,6 @@ static portTASK_FUNCTION_PROTO( prvIdleTask, pvParameters ) PRIVILEGED_FUNCTION; #endif -/* Function to call the Thread Local Storage Pointer Deletion Callbacks. Will be - * called during task deletion before prvDeleteTCB is called. - */ -#if ( configNUM_THREAD_LOCAL_STORAGE_POINTERS > 0 ) && ( configTHREAD_LOCAL_STORAGE_DELETE_CALLBACKS == 1 ) - static void prvDeleteTLS( TCB_t * pxTCB ); -#endif - /* * Used only by the idle task. This checks to see if anything has been placed * in the list of tasks waiting to be deleted. If so the task is cleaned up @@ -1167,9 +1157,6 @@ static void prvInitialiseNewTask( TaskFunction_t pxTaskCode, for( x = 0; x < ( UBaseType_t ) configNUM_THREAD_LOCAL_STORAGE_POINTERS; x++ ) { pxNewTCB->pvThreadLocalStoragePointers[ x ] = NULL; - #if ( configTHREAD_LOCAL_STORAGE_DELETE_CALLBACKS == 1 ) - pxNewTCB->pvThreadLocalStoragePointersDelCallback[ x ] = NULL; - #endif } } #endif @@ -1514,10 +1501,6 @@ static void prvAddNewTaskToReadyList( TCB_t * pxNewTCB ) if( xFreeNow == pdTRUE ) { - #if ( configNUM_THREAD_LOCAL_STORAGE_POINTERS > 0 ) && ( configTHREAD_LOCAL_STORAGE_DELETE_CALLBACKS == 1 ) - prvDeleteTLS( pxTCB ); - #endif - prvDeleteTCB( pxTCB ); } @@ -4468,7 +4451,11 @@ static portTASK_FUNCTION( prvIdleTask, pvParameters ) { TCB_t * pxTCB; - if( xIndex < configNUM_THREAD_LOCAL_STORAGE_POINTERS ) + /* If TLSP deletion callbacks are enabled, then + * configNUM_THREAD_LOCAL_STORAGE_POINTERS is doubled in size so + * that the latter half of the pvThreadLocalStoragePointers stores + * the deletion callbacks. */ + if( xIndex < ( configNUM_THREAD_LOCAL_STORAGE_POINTERS / 2 ) ) { #if ( configNUM_CORES > 1 ) @@ -4479,8 +4466,11 @@ static portTASK_FUNCTION( prvIdleTask, pvParameters ) #endif /* ( configNUM_CORES > 1 ) */ pxTCB = prvGetTCBFromHandle( xTaskToSet ); + /* Store the TLSP by indexing the first half of the array */ pxTCB->pvThreadLocalStoragePointers[ xIndex ] = pvValue; - pxTCB->pvThreadLocalStoragePointersDelCallback[ xIndex ] = xDelCallback; + /* Store the TLSP deletion callback by indexing the second half + * of the array. */ + pxTCB->pvThreadLocalStoragePointers[ ( xIndex + ( configNUM_THREAD_LOCAL_STORAGE_POINTERS / 2 ) ) ] = ( void * ) xDelCallback; #if ( configNUM_CORES > 1 ) /* Release the previously taken kernel lock. */ @@ -4537,7 +4527,15 @@ static portTASK_FUNCTION( prvIdleTask, pvParameters ) void * pvReturn = NULL; TCB_t * pxTCB; - if( xIndex < configNUM_THREAD_LOCAL_STORAGE_POINTERS ) + #if ( configTHREAD_LOCAL_STORAGE_DELETE_CALLBACKS == 1 ) + /* If TLSP deletion callbacks are enabled, then + * configNUM_THREAD_LOCAL_STORAGE_POINTERS is doubled in size so + * that the latter half of the pvThreadLocalStoragePointers stores + * the deletion callbacks. */ + if( xIndex < ( configNUM_THREAD_LOCAL_STORAGE_POINTERS / 2 ) ) + #else /* configTHREAD_LOCAL_STORAGE_DELETE_CALLBACKS == 1 */ + if( xIndex < configNUM_THREAD_LOCAL_STORAGE_POINTERS ) + #endif /* configTHREAD_LOCAL_STORAGE_DELETE_CALLBACKS == 1 */ { pxTCB = prvGetTCBFromHandle( xTaskToQuery ); pvReturn = pxTCB->pvThreadLocalStoragePointers[ xIndex ]; @@ -4648,9 +4646,6 @@ static void prvCheckTasksWaitingTermination( void ) if ( pxTCB != NULL ) { - #if ( configNUM_THREAD_LOCAL_STORAGE_POINTERS > 0 ) && ( configTHREAD_LOCAL_STORAGE_DELETE_CALLBACKS == 1 ) - prvDeleteTLS( pxTCB ); - #endif prvDeleteTCB( pxTCB ); } else @@ -4668,9 +4663,6 @@ static void prvCheckTasksWaitingTermination( void ) } taskEXIT_CRITICAL( &xKernelLock ); - #if ( configNUM_THREAD_LOCAL_STORAGE_POINTERS > 0 ) && ( configTHREAD_LOCAL_STORAGE_DELETE_CALLBACKS == 1 ) - prvDeleteTLS( pxTCB ); - #endif prvDeleteTCB( pxTCB ); #endif /* configNUM_CORES > 1 */ } @@ -4990,25 +4982,6 @@ BaseType_t xTaskGetAffinity( TaskHandle_t xTask ) #endif /* INCLUDE_vTaskDelete */ /*-----------------------------------------------------------*/ -#if ( configNUM_THREAD_LOCAL_STORAGE_POINTERS > 0 ) && ( configTHREAD_LOCAL_STORAGE_DELETE_CALLBACKS == 1 ) - - static void prvDeleteTLS( TCB_t * pxTCB ) - { - configASSERT( pxTCB ); - - 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 /* ( configNUM_THREAD_LOCAL_STORAGE_POINTERS > 0 ) && ( configTHREAD_LOCAL_STORAGE_DELETE_CALLBACKS == 1 ) */ -/*-----------------------------------------------------------*/ - - static void prvResetNextTaskUnblockTime( void ) { TCB_t * pxTCB; diff --git a/components/freertos/config/include/freertos/FreeRTOSConfig.h b/components/freertos/config/include/freertos/FreeRTOSConfig.h index 26cec5b97b..6a7ccf6d19 100644 --- a/components/freertos/config/include/freertos/FreeRTOSConfig.h +++ b/components/freertos/config/include/freertos/FreeRTOSConfig.h @@ -109,15 +109,16 @@ #define configMAX_TASK_NAME_LEN CONFIG_FREERTOS_MAX_TASK_NAME_LEN -/* The distinciton between Amazon SMP FreeRTOS and IDF FreeRTOS is necessary because in IDF FreeRTOS, - * TLSP deletion callbacks can be added directly to the TCB, which is not allowed in Amazon SMP FreeRTOS. - * In the latter, the TLSP number is simply doubled to accomodate space for a deletion callback of each TLSP. - */ -#if CONFIG_FREERTOS_SMP +/* If deletion callbacks are enabled, the number of TLSP's are doubled (i.e., + * the length of the TCB's pvThreadLocalStoragePointersThis array). This allows + * the latter half of the array to store the deletion callback pointers (whereas + * the first half stores the TLSPs themselves). */ +#if CONFIG_FREERTOS_TLSP_DELETION_CALLBACKS #define configNUM_THREAD_LOCAL_STORAGE_POINTERS ( CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS * 2 ) -#else /* CONFIG_FREERTOS_SMP */ +#else /* CONFIG_FREERTOS_TLSP_DELETION_CALLBACKS */ #define configNUM_THREAD_LOCAL_STORAGE_POINTERS CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS -#endif /* CONFIG_FREERTOS_SMP */ +#endif /* CONFIG_FREERTOS_TLSP_DELETION_CALLBACKS */ + #define configSTACK_DEPTH_TYPE uint32_t #if CONFIG_FREERTOS_ENABLE_BACKWARD_COMPATIBILITY #define configENABLE_BACKWARD_COMPATIBILITY 1 diff --git a/components/freertos/linker.lf b/components/freertos/linker.lf index e7e75a3845..f23fac8bfe 100644 --- a/components/freertos/linker.lf +++ b/components/freertos/linker.lf @@ -153,7 +153,6 @@ entries: tasks:prvIdleTask (default) if FREERTOS_TLSP_DELETION_CALLBACKS = y: tasks:vTaskSetThreadLocalStoragePointerAndDelCallback (default) - tasks:prvDeleteTLS (default) if FREERTOS_THREAD_LOCAL_STORAGE_POINTERS != 0: tasks:vTaskSetThreadLocalStoragePointer (default) tasks:pvTaskGetThreadLocalStoragePointer (default) @@ -234,6 +233,8 @@ entries: port:vPortEndScheduler (default) port:pxPortInitialiseStack (default) port:xPortGetTickRateHz (default) + if FREERTOS_TLSP_DELETION_CALLBACKS = y: + port:vPortTLSPointersDelCb (default) if IDF_TARGET_ESP32 = y || IDF_TARGET_ESP32S3 = y : port:vPortCleanUpCoprocArea (default) port:vPortTCBPreDeleteHook (default) @@ -246,4 +247,6 @@ entries: port:vPortEndScheduler (default) port:pxPortInitialiseStack (default) port:xPortGetTickRateHz (default) + if FREERTOS_TLSP_DELETION_CALLBACKS = y: + port:vPortTLSPointersDelCb (default) port:vPortTCBPreDeleteHook (default) diff --git a/components/freertos/test_apps/freertos/port/test_tlsp_del_cb.c b/components/freertos/test_apps/freertos/port/test_tlsp_del_cb.c index 4c3082fbd9..66eec9223c 100644 --- a/components/freertos/test_apps/freertos/port/test_tlsp_del_cb.c +++ b/components/freertos/test_apps/freertos/port/test_tlsp_del_cb.c @@ -6,8 +6,6 @@ #include "sdkconfig.h" -#if CONFIG_FREERTOS_SMP - #include "freertos/FreeRTOS.h" #include "freertos/task.h" #include "unity.h" @@ -79,66 +77,3 @@ TEST_CASE("Test TLSP deletion callbacks", "[freertos]") } } } - -#else // CONFIG_FREERTOS_SMP - -// Todo: Remove IDF FreeRTOS Test Case - -#include "freertos/FreeRTOS.h" -#include "freertos/task.h" -#include "freertos/semphr.h" -#include "unity.h" -#include "test_utils.h" - -/* --------Test backported thread local storage pointer and deletion cb feature---------- - * vTaskSetThreadLocalStoragePointerAndDelCallback() - * pvTaskGetThreadLocalStoragePointer(), - * - * This test creates a task and set's the task's TLSPs. The task is then deleted - * which should trigger the deletion cb. - */ - -#define NO_OF_TLSP configNUM_THREAD_LOCAL_STORAGE_POINTERS -#define TLSP_SET_BASE 0x0F //0b1111 to be bit shifted by index -#define TLSP_DEL_BASE 0x05 //0b0101 to be bit shifted by index - -//The variables pointed to by Thread Local Storage Pointer -static uint32_t task_storage[portNUM_PROCESSORS][NO_OF_TLSP] = {0}; - -static void del_cb(int index, void *ptr) -{ - *((uint32_t *)ptr) = (TLSP_DEL_BASE << index); //Indicate deletion by setting task storage element to a unique value -} - -static void task_cb(void *arg) -{ - int core = xPortGetCoreID(); - for(int i = 0; i < NO_OF_TLSP; i++){ - task_storage[core][i] = (TLSP_SET_BASE << i); //Give each element of task_storage a unique number - vTaskSetThreadLocalStoragePointerAndDelCallback(NULL, i, (void *)&task_storage[core][i], del_cb); //Set each TLSP to point to a task storage element - } - - for(int i = 0; i < NO_OF_TLSP; i++){ - uint32_t * tlsp = (uint32_t *)pvTaskGetThreadLocalStoragePointer(NULL, i); - TEST_ASSERT_EQUAL(*tlsp, (TLSP_SET_BASE << i)); //Check if TLSP points to the correct task storage element by checking unique value - } - - vTaskDelete(NULL); //Delete Task to Trigger TSLP deletion callback -} - -TEST_CASE("Test FreeRTOS thread local storage pointers and del cb", "[freertos]") -{ - //Create Task - for(int core = 0; core < portNUM_PROCESSORS; core++){ - xTaskCreatePinnedToCore(task_cb, "task", 1024, NULL, UNITY_FREERTOS_PRIORITY+1, NULL, core); - } - vTaskDelay(10); //Delay long enough for tasks to run to completion - - for(int core = 0; core < portNUM_PROCESSORS; core++){ - for(int i = 0; i < NO_OF_TLSP; i++){ - TEST_ASSERT_EQUAL((TLSP_DEL_BASE << i), task_storage[core][i]); //Check del_cb ran by checking task storage for unique value - } - } -} - -#endif // CONFIG_FREERTOS_SMP diff --git a/tools/test_apps/linux_compatible/linux_freertos/components/kernel_tests/port/test_tlsp_del_cb.c b/tools/test_apps/linux_compatible/linux_freertos/components/kernel_tests/port/test_tlsp_del_cb.c index 289b86df44..7de13ae355 100644 --- a/tools/test_apps/linux_compatible/linux_freertos/components/kernel_tests/port/test_tlsp_del_cb.c +++ b/tools/test_apps/linux_compatible/linux_freertos/components/kernel_tests/port/test_tlsp_del_cb.c @@ -6,8 +6,6 @@ #include "sdkconfig.h" -#if CONFIG_FREERTOS_SMP - #include "freertos/FreeRTOS.h" #include "freertos/task.h" #include "unity.h" @@ -78,65 +76,3 @@ TEST_CASE("Test TLSP deletion callbacks", "[freertos]") } } } - -#else // CONFIG_FREERTOS_SMP - -// Todo: Remove IDF FreeRTOS Test Case - -#include "freertos/FreeRTOS.h" -#include "freertos/task.h" -#include "freertos/semphr.h" -#include "unity.h" - -/* --------Test backported thread local storage pointer and deletion cb feature---------- - * vTaskSetThreadLocalStoragePointerAndDelCallback() - * pvTaskGetThreadLocalStoragePointer(), - * - * This test creates a task and set's the task's TLSPs. The task is then deleted - * which should trigger the deletion cb. - */ - -#define NO_OF_TLSP configNUM_THREAD_LOCAL_STORAGE_POINTERS -#define TLSP_SET_BASE 0x0F //0b1111 to be bit shifted by index -#define TLSP_DEL_BASE 0x05 //0b0101 to be bit shifted by index - -//The variables pointed to by Thread Local Storage Pointer -static uint32_t task_storage[portNUM_PROCESSORS][NO_OF_TLSP] = {0}; - -static void del_cb(int index, void *ptr) -{ - *((uint32_t *)ptr) = (TLSP_DEL_BASE << index); //Indicate deletion by setting task storage element to a unique value -} - -static void task_cb(void *arg) -{ - int core = xPortGetCoreID(); - for(int i = 0; i < NO_OF_TLSP; i++){ - task_storage[core][i] = (TLSP_SET_BASE << i); //Give each element of task_storage a unique number - vTaskSetThreadLocalStoragePointerAndDelCallback(NULL, i, (void *)&task_storage[core][i], del_cb); //Set each TLSP to point to a task storage element - } - - for(int i = 0; i < NO_OF_TLSP; i++){ - uint32_t * tlsp = (uint32_t *)pvTaskGetThreadLocalStoragePointer(NULL, i); - TEST_ASSERT_EQUAL(*tlsp, (TLSP_SET_BASE << i)); //Check if TLSP points to the correct task storage element by checking unique value - } - - vTaskDelete(NULL); //Delete Task to Trigger TSLP deletion callback -} - -TEST_CASE("Test FreeRTOS thread local storage pointers and del cb", "[freertos]") -{ - //Create Task - for(int core = 0; core < portNUM_PROCESSORS; core++){ - xTaskCreatePinnedToCore(task_cb, "task", 1024, NULL, CONFIG_UNITY_FREERTOS_PRIORITY+1, NULL, core); - } - vTaskDelay(10); //Delay long enough for tasks to run to completion - - for(int core = 0; core < portNUM_PROCESSORS; core++){ - for(int i = 0; i < NO_OF_TLSP; i++){ - TEST_ASSERT_EQUAL((TLSP_DEL_BASE << i), task_storage[core][i]); //Check del_cb ran by checking task storage for unique value - } - } -} - -#endif // CONFIG_FREERTOS_SMP