]> granicus.if.org Git - esp-idf/commitdiff
'Merge branch 'thread_local_storage_delete_callbacks' into 'master'
authorJeroen Domburg <git@j0h.nl>
Wed, 24 Aug 2016 05:29:06 +0000 (13:29 +0800)
committerJeroen Domburg <git@j0h.nl>
Wed, 24 Aug 2016 05:30:30 +0000 (13:30 +0800)
The thread-local-storage feature in FreeRTOS attaches an application-usable array of pointers to a thread control block. These pointers usually point to a structure the thread allocates. When a thread gets (voluntarily or involuntarily) destroyed, this memory can leak. This merge adds a matching second array of user-settable pointers to destructor routines. As soon as the task gets cleaned up (which happens in the idle thread), the destructors get called and the memory can be freed.

See merge request !19

components/freertos/Kconfig
components/freertos/include/freertos/FreeRTOSConfig.h
components/freertos/include/freertos/task.h
components/freertos/readme_smp.txt
components/freertos/tasks.c
components/lwip/Kconfig

index 8c05199f81ab6903f9c775cd3db9b294b528a8c2..89227a7ddfde1904bc35625f4ffcae6da05e691d 100644 (file)
@@ -73,7 +73,7 @@ config FREERTOS_CHECK_STACKOVERFLOW_CANARY
                (configCHECK_FOR_STACK_OVERFLOW=2)
 endchoice
 
-config CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS
+config FREERTOS_THREAD_LOCAL_STORAGE_POINTERS
        int "Amount of thread local storage pointers"
        range 0 256
        default 0
index 78567d548b1c001b027b460931872a03e7b2b960..c0a86efed3fd42bbdfc85a0a3ec07eed6c3cb3d3 100644 (file)
@@ -97,6 +97,7 @@
 #endif
 
 #define configNUM_THREAD_LOCAL_STORAGE_POINTERS CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS
+#define configTHREAD_LOCAL_STORAGE_DELETE_CALLBACKS 1
 
 /* TODO: config freq by menuconfig */
 #define XT_CLOCK_FREQ 80000000
index d4b9d43c8245bbc82c4ea70dc1f3643c0b54d9ac..d771ca653921f762d2ed0e1630a9df60cdfeb938 100644 (file)
@@ -1175,6 +1175,11 @@ 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 ) 
+               typedef void (*TlsDeleteCallbackFunction_t)( int, void * ); 
+               void vTaskSetThreadLocalStoragePointerAndDelCallback( TaskHandle_t xTaskToSet, BaseType_t xIndex, void *pvValue , TlsDeleteCallbackFunction_t xDelCallback);
+       #endif
+
 #endif
 
 /**
index 0f7a66d74ff273c9f229b8b92be8fbdd56d1fd71..38f332416ab53fd099fbd0c4f8d21b743cce89e5 100644 (file)
@@ -24,3 +24,9 @@ means that when you set a handler for an interrupt, it will get triggered if
 the interrupt is triggered on both CPU0 as well as on CPU1. This is something
 we may change in future FreeRTOS-esp32 releases.
 
+- This FreeRTOS version has the task local storage backported from the 8.2.x
+versions. It, however, has an addition: you can also set a callback when you 
+set the pointer. This callback will be called by the idle task, with the 
+pointer as an argument, when the thread is destroyed. This depends on the idle
+task getting CPU time; when a thread is hogging the CPU without yielding,
+the idle thread won't be called and the delete callback won't be called either.
index f0e4fb120aa37403fa49489a321a07c237c6840f..fff7f49f8dc3afe488312b7d080cf8486c269abd 100644 (file)
@@ -180,6 +180,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 )
@@ -3045,7 +3048,10 @@ UBaseType_t x;
        {
                for( x = 0; x < ( UBaseType_t ) configNUM_THREAD_LOCAL_STORAGE_POINTERS; x++ )
                {
-                       pxNewTCB->pvThreadLocalStoragePointers[ x ] = NULL;
+                       pxTCB->pvThreadLocalStoragePointers[ x ] = NULL;
+                       #if ( configTHREAD_LOCAL_STORAGE_DELETE_CALLBACKS )
+                       pxTCB->pvThreadLocalStoragePointersDelCallback[ x ] = (TlsDeleteCallbackFunction_t)NULL;
+                       #endif
                }
        }
        #endif
@@ -3068,6 +3074,29 @@ UBaseType_t x;
 /*-----------------------------------------------------------*/
 #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 )
+               {
+                       pxTCB = prvGetTCBFromHandle( xTaskToSet );
+                       taskENTER_CRITICAL(&xTaskQueueMutex);
+                       pxTCB->pvThreadLocalStoragePointers[ xIndex ] = pvValue;
+                       pxTCB->pvThreadLocalStoragePointersDelCallback[ xIndex ] = xDelCallback;
+                       taskEXIT_CRITICAL(&xTaskQueueMutex);
+               }
+       }
+
+       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;
@@ -3078,6 +3107,7 @@ UBaseType_t x;
                        pxTCB->pvThreadLocalStoragePointers[ xIndex ] = pvValue;
                }
        }
+#endif /* configTHREAD_LOCAL_STORAGE_DELETE_CALLBACKS */
 
 #endif /* configNUM_THREAD_LOCAL_STORAGE_POINTERS */
 /*-----------------------------------------------------------*/
@@ -3181,7 +3211,19 @@ static void prvCheckTasksWaitingTermination( void )
                                        --uxTasksDeleted;
                                }
                                taskEXIT_CRITICAL(&xTaskQueueMutex);
-
+                               
+                               #if ( configNUM_THREAD_LOCAL_STORAGE_POINTERS > 0 ) && ( configTHREAD_LOCAL_STORAGE_DELETE_CALLBACKS )
+                               {
+                                       int x;
+                                       for( x = 0; x < ( UBaseType_t ) configNUM_THREAD_LOCAL_STORAGE_POINTERS; x++ )
+                                       {
+                                               if (pxTCB->pvThreadLocalStoragePointersDelCallback[ x ] != NULL)
+                                               {
+                                                       pxTCB->pvThreadLocalStoragePointersDelCallback[ x ](x, pxTCB->pvThreadLocalStoragePointers[ x ]);
+                                               }
+                                       }
+                               }
+                               #endif
                                prvDeleteTCB( pxTCB );
                        }
                        else
index ee6511e00cd6dbe7d80562d91dc4dc01bbb4621d..8f38ba93102f053fdaf680707a2be8d34c5976ea 100644 (file)
@@ -9,6 +9,13 @@ config LWIP_MAX_SOCKETS
                sockets to be open at the same time conserves memory. Specify
                the maximum amount of sockets here.
 
+config LWIP_THREAD_LOCAL_STORAGE_INDEX
+       int "Index for thread-local-storage pointer for lwip"
+       default 0
+       help
+               Specify the thread-local-storage-pointer index for lwip
+               use.
+
 endmenu