mirror of
https://github.com/espressif/esp-idf.git
synced 2025-08-10 04:43:33 +00:00
pthread: Remove pthread TLS cleanup dependency on FreeRTOS Static Task Cleanup Hook
This commit removes the need to define the vTaskCleanupTCB hook in pthread to cleanup the thread-specific data before a thread is deleted.
This commit is contained in:
@@ -15,6 +15,11 @@
|
||||
|
||||
#include "pthread_internal.h"
|
||||
|
||||
/* Sanity check to ensure that the number of FreeRTOS TLSPs is at least 1 */
|
||||
#if (CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS < 1)
|
||||
#error "CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS cannot be 0 for pthread TLS"
|
||||
#endif
|
||||
|
||||
#define PTHREAD_TLS_INDEX 0
|
||||
|
||||
typedef void (*pthread_destructor_t)(void*);
|
||||
@@ -117,7 +122,7 @@ int pthread_key_delete(pthread_key_t key)
|
||||
- The destructor is always called in the context of the thread itself - which is important if the task then calls
|
||||
pthread_getspecific() or pthread_setspecific() to update the state further, as allowed for in the spec.
|
||||
*/
|
||||
static void pthread_local_storage_thread_deleted_callback(int index, void *v_tls)
|
||||
static void pthread_cleanup_thread_specific_data_callback(int index, void *v_tls)
|
||||
{
|
||||
values_list_t *tls = (values_list_t *)v_tls;
|
||||
assert(tls != NULL);
|
||||
@@ -142,46 +147,23 @@ static void pthread_local_storage_thread_deleted_callback(int index, void *v_tls
|
||||
free(tls);
|
||||
}
|
||||
|
||||
#if CONFIG_FREERTOS_ENABLE_STATIC_TASK_CLEAN_UP && !CONFIG_FREERTOS_SMP // IDF-4955
|
||||
/* Called from FreeRTOS task delete hook */
|
||||
void pthread_local_storage_cleanup(TaskHandle_t task)
|
||||
{
|
||||
void *tls = pvTaskGetThreadLocalStoragePointer(task, PTHREAD_TLS_INDEX);
|
||||
if (tls != NULL) {
|
||||
pthread_local_storage_thread_deleted_callback(PTHREAD_TLS_INDEX, tls);
|
||||
vTaskSetThreadLocalStoragePointer(task, PTHREAD_TLS_INDEX, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
void __real_vPortCleanUpTCB(void *tcb);
|
||||
|
||||
/* If static task cleanup hook is defined then its applications responsibility to define `vPortCleanUpTCB`.
|
||||
Here we are wrapping it, so that we can do pthread specific TLS cleanup and then invoke application
|
||||
real specific `vPortCleanUpTCB` */
|
||||
void __wrap_vPortCleanUpTCB(void *tcb)
|
||||
{
|
||||
pthread_local_storage_cleanup(tcb);
|
||||
__real_vPortCleanUpTCB(tcb);
|
||||
}
|
||||
#endif // CONFIG_FREERTOS_ENABLE_STATIC_TASK_CLEAN_UP && !CONFIG_FREERTOS_SMP
|
||||
|
||||
/* this function called from pthread_task_func for "early" cleanup of TLS in a pthread */
|
||||
void pthread_internal_local_storage_destructor_callback(void)
|
||||
void pthread_internal_local_storage_destructor_callback(TaskHandle_t handle)
|
||||
{
|
||||
void *tls = pvTaskGetThreadLocalStoragePointer(NULL, PTHREAD_TLS_INDEX);
|
||||
void *tls = pvTaskGetThreadLocalStoragePointer(handle, PTHREAD_TLS_INDEX);
|
||||
if (tls != NULL) {
|
||||
pthread_local_storage_thread_deleted_callback(PTHREAD_TLS_INDEX, tls);
|
||||
pthread_cleanup_thread_specific_data_callback(PTHREAD_TLS_INDEX, tls);
|
||||
/* remove the thread-local-storage pointer to avoid the idle task cleanup
|
||||
calling it again...
|
||||
*/
|
||||
#if CONFIG_FREERTOS_ENABLE_STATIC_TASK_CLEAN_UP && !CONFIG_FREERTOS_SMP // IDF-4955
|
||||
#if !defined(CONFIG_FREERTOS_TLSP_DELETION_CALLBACKS)
|
||||
vTaskSetThreadLocalStoragePointer(NULL, PTHREAD_TLS_INDEX, NULL);
|
||||
#else
|
||||
vTaskSetThreadLocalStoragePointerAndDelCallback(NULL,
|
||||
PTHREAD_TLS_INDEX,
|
||||
NULL,
|
||||
NULL);
|
||||
#endif // CONFIG_FREERTOS_ENABLE_STATIC_TASK_CLEAN_UP && !CONFIG_FREERTOS_SMP
|
||||
#endif /* CONFIG_FREERTOS_TLSP_DELETION_CALLBACKS */
|
||||
}
|
||||
}
|
||||
|
||||
@@ -223,14 +205,14 @@ int pthread_setspecific(pthread_key_t key, const void *value)
|
||||
if (tls == NULL) {
|
||||
return ENOMEM;
|
||||
}
|
||||
#if defined(CONFIG_FREERTOS_ENABLE_STATIC_TASK_CLEAN_UP)
|
||||
#if !defined(CONFIG_FREERTOS_TLSP_DELETION_CALLBACKS)
|
||||
vTaskSetThreadLocalStoragePointer(NULL, PTHREAD_TLS_INDEX, tls);
|
||||
#else
|
||||
vTaskSetThreadLocalStoragePointerAndDelCallback(NULL,
|
||||
PTHREAD_TLS_INDEX,
|
||||
tls,
|
||||
pthread_local_storage_thread_deleted_callback);
|
||||
#endif
|
||||
pthread_cleanup_thread_specific_data_callback);
|
||||
#endif /* CONFIG_FREERTOS_TLSP_DELETION_CALLBACKS */
|
||||
}
|
||||
|
||||
value_entry_t *entry = find_value(tls, key);
|
||||
@@ -255,7 +237,7 @@ int pthread_setspecific(pthread_key_t key, const void *value)
|
||||
// a destructor may call pthread_setspecific() to add a new non-NULL value
|
||||
// to the list, and this should be processed after all other entries.
|
||||
//
|
||||
// See pthread_local_storage_thread_deleted_callback()
|
||||
// See pthread_cleanup_thread_specific_data_callback()
|
||||
value_entry_t *last_entry = NULL;
|
||||
value_entry_t *it;
|
||||
SLIST_FOREACH(it, tls, next) {
|
||||
|
Reference in New Issue
Block a user