From 94fc5d6276c347e65bb78839ef1753f2007359e0 Mon Sep 17 00:00:00 2001 From: Dong Heng Date: Mon, 14 May 2018 16:55:15 +0800 Subject: [PATCH] feat(freertos): Add FreeRTOS private data API --- components/freertos/freertos/tasks.c | 54 ++++++++++++++++++- components/freertos/include/freertos/task.h | 31 +++++++++++ .../include/port/freertos/FreeRTOSConfig.h | 3 ++ 3 files changed, 87 insertions(+), 1 deletion(-) diff --git a/components/freertos/freertos/tasks.c b/components/freertos/freertos/tasks.c index 7571d23a..685ea320 100644 --- a/components/freertos/freertos/tasks.c +++ b/components/freertos/freertos/tasks.c @@ -304,6 +304,9 @@ typedef struct tskTaskControlBlock #if( configNUM_THREAD_LOCAL_STORAGE_POINTERS > 0 ) void *pvThreadLocalStoragePointers[ configNUM_THREAD_LOCAL_STORAGE_POINTERS ]; + #if ( configTHREAD_LOCAL_STORAGE_DELETE_CALLBACKS ) + TlsDeleteCallbackFunction_t pvThreadLocalStoragePointersDelCallback[ configNUM_THREAD_LOCAL_STORAGE_POINTERS ]; + #endif #endif #if( configGENERATE_RUN_TIME_STATS == 1 ) @@ -973,6 +976,9 @@ UBaseType_t x; 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 @@ -1107,6 +1113,22 @@ static void prvAddNewTaskToReadyList( TCB_t *pxNewTCB ) } /*-----------------------------------------------------------*/ +#if ( configNUM_THREAD_LOCAL_STORAGE_POINTERS > 0 ) && ( configTHREAD_LOCAL_STORAGE_DELETE_CALLBACKS ) + + static void prvDeleteTLS( TCB_t *pxTCB ) + { + configASSERT( pxTCB ); + for( int x = 0; x < ( UBaseType_t ) 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 ) */ + #if ( INCLUDE_vTaskDelete == 1 ) void vTaskDelete( TaskHandle_t xTaskToDelete ) @@ -1169,6 +1191,9 @@ static void prvAddNewTaskToReadyList( TCB_t *pxNewTCB ) else { --uxCurrentNumberOfTasks; +#if ( configNUM_THREAD_LOCAL_STORAGE_POINTERS > 0 ) && ( configTHREAD_LOCAL_STORAGE_DELETE_CALLBACKS ) + prvDeleteTLS( pxTCB ); +#endif prvDeleteTCB( pxTCB ); /* Reset the next expected unblock time in case it referred to @@ -3380,6 +3405,29 @@ static portTASK_FUNCTION( prvIdleTask, pvParameters ) #if ( configNUM_THREAD_LOCAL_STORAGE_POINTERS != 0 ) +#if ( configTHREAD_LOCAL_STORAGE_DELETE_CALLBACKS ) + + void vTaskSetThreadLocalStoragePointerAndDelCallback( TaskHandle_t xTaskToSet, BaseType_t xIndex, void *pvValue , TlsDeleteCallbackFunction_t xDelCallback) + { + TCB_t *pxTCB; + + if( xIndex < configNUM_THREAD_LOCAL_STORAGE_POINTERS ) + { + taskENTER_CRITICAL(); + pxTCB = prvGetTCBFromHandle( xTaskToSet ); + pxTCB->pvThreadLocalStoragePointers[ xIndex ] = pvValue; + pxTCB->pvThreadLocalStoragePointersDelCallback[ xIndex ] = xDelCallback; + taskEXIT_CRITICAL(); + } + } + + void vTaskSetThreadLocalStoragePointer( TaskHandle_t xTaskToSet, BaseType_t xIndex, void *pvValue ) + { + vTaskSetThreadLocalStoragePointerAndDelCallback( xTaskToSet, xIndex, pvValue, (TlsDeleteCallbackFunction_t)NULL ); + } + +#else + void vTaskSetThreadLocalStoragePointer( TaskHandle_t xTaskToSet, BaseType_t xIndex, void *pvValue ) { TCB_t *pxTCB; @@ -3391,6 +3439,8 @@ static portTASK_FUNCTION( prvIdleTask, pvParameters ) } } +#endif /* configTHREAD_LOCAL_STORAGE_DELETE_CALLBACKS */ + #endif /* configNUM_THREAD_LOCAL_STORAGE_POINTERS */ /*-----------------------------------------------------------*/ @@ -3486,7 +3536,9 @@ static void prvCheckTasksWaitingTermination( void ) --uxDeletedTasksWaitingCleanUp; } taskEXIT_CRITICAL(); - +#if ( configNUM_THREAD_LOCAL_STORAGE_POINTERS > 0 ) && ( configTHREAD_LOCAL_STORAGE_DELETE_CALLBACKS ) + prvDeleteTLS( pxTCB ); +#endif prvDeleteTCB( pxTCB ); } } diff --git a/components/freertos/include/freertos/task.h b/components/freertos/include/freertos/task.h index d0ee0681..60267ae8 100644 --- a/components/freertos/include/freertos/task.h +++ b/components/freertos/include/freertos/task.h @@ -1459,6 +1459,37 @@ constant. */ void vTaskSetThreadLocalStoragePointer( TaskHandle_t xTaskToSet, BaseType_t xIndex, void *pvValue ) PRIVILEGED_FUNCTION; void *pvTaskGetThreadLocalStoragePointer( TaskHandle_t xTaskToQuery, BaseType_t xIndex ) PRIVILEGED_FUNCTION; + #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 #endif /** diff --git a/components/freertos/include/port/freertos/FreeRTOSConfig.h b/components/freertos/include/port/freertos/FreeRTOSConfig.h index 89deb9a3..4fc24fe6 100644 --- a/components/freertos/include/port/freertos/FreeRTOSConfig.h +++ b/components/freertos/include/port/freertos/FreeRTOSConfig.h @@ -140,5 +140,8 @@ configKERNEL_INTERRUPT_PRIORITY setting. Here 15 corresponds to the lowest NVIC value of 255. */ #define configLIBRARY_KERNEL_INTERRUPT_PRIORITY 15 +#define configNUM_THREAD_LOCAL_STORAGE_POINTERS 1 +#define configTHREAD_LOCAL_STORAGE_DELETE_CALLBACKS 1 + #endif /* FREERTOS_CONFIG_H */