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
/**
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.
#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 )
{
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
/*-----------------------------------------------------------*/
#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;
pxTCB->pvThreadLocalStoragePointers[ xIndex ] = pvValue;
}
}
+#endif /* configTHREAD_LOCAL_STORAGE_DELETE_CALLBACKS */
#endif /* configNUM_THREAD_LOCAL_STORAGE_POINTERS */
/*-----------------------------------------------------------*/
--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