]> granicus.if.org Git - esp-idf/commitdiff
pthread: implement local storage using pvTaskGetThreadLocalStoragePointer
authorMahavir Jain <mahavir@espressif.com>
Thu, 1 Feb 2018 16:17:38 +0000 (00:17 +0800)
committerMahavir Jain <mahavir@espressif.com>
Thu, 19 Apr 2018 12:58:55 +0000 (18:28 +0530)
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>
components/pthread/component.mk
components/pthread/pthread_local_storage.c

index 97ace4b78cdd73b79bf5ba50a4333a9ed01a88b1..0dd23948107e5b49bd032180fb1b84287260076a 100644 (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
index da59726a357aaa522fd651466dff0888375120a9..f87f698d8bcd89507ca237f68f743ed974ccc028 100644 (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);