pthread: implement local storage using pvTaskGetThreadLocalStoragePointer

If static task cleanup option is enabled, then before invoking application
defined `vPortCleanUpTCB` hook, pthread specific cleanup is performed.

Signed-off-by: Mahavir Jain <mahavir@espressif.com>
This commit is contained in:
Mahavir Jain 2018-02-02 00:17:38 +08:00
parent 2d598d6fb7
commit 24ad64bfe4
2 changed files with 35 additions and 0 deletions

View File

@ -7,3 +7,7 @@ COMPONENT_SRCDIRS := .
COMPONENT_ADD_INCLUDEDIRS := include
COMPONENT_ADD_LDFLAGS := -lpthread
ifdef CONFIG_ENABLE_STATIC_TASK_CLEAN_UP_HOOK
COMPONENT_ADD_LDFLAGS += -Wl,--wrap=vPortCleanUpTCB
endif

View File

@ -142,6 +142,29 @@ static void pthread_local_storage_thread_deleted_callback(int index, void *v_tls
free(tls);
}
#if defined(CONFIG_ENABLE_STATIC_TASK_CLEAN_UP_HOOK)
/* 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
/* this function called from pthread_task_func for "early" cleanup of TLS in a pthread */
void pthread_internal_local_storage_destructor_callback()
{
@ -151,10 +174,14 @@ void pthread_internal_local_storage_destructor_callback()
/* remove the thread-local-storage pointer to avoid the idle task cleanup
calling it again...
*/
#if defined(CONFIG_ENABLE_STATIC_TASK_CLEAN_UP_HOOK)
vTaskSetThreadLocalStoragePointer(NULL, PTHREAD_TLS_INDEX, NULL);
#else
vTaskSetThreadLocalStoragePointerAndDelCallback(NULL,
PTHREAD_TLS_INDEX,
NULL,
NULL);
#endif
}
}
@ -196,10 +223,14 @@ int pthread_setspecific(pthread_key_t key, const void *value)
if (tls == NULL) {
return ENOMEM;
}
#if defined(CONFIG_ENABLE_STATIC_TASK_CLEAN_UP_HOOK)
vTaskSetThreadLocalStoragePointer(NULL, PTHREAD_TLS_INDEX, tls);
#else
vTaskSetThreadLocalStoragePointerAndDelCallback(NULL,
PTHREAD_TLS_INDEX,
tls,
pthread_local_storage_thread_deleted_callback);
#endif
}
value_entry_t *entry = find_value(tls, key);