1Thread Local Storage
2====================
3
4Overview
5--------
6
7Thread-local storage (TLS) is a mechanism by which variables are allocated such that there
8is one instance of the variable per extant thread. ESP-IDF provides three ways to make use
9of such variables:
10
11 - :ref:`freertos-native`: ESP-IDF FreeRTOS native API.
12 - :ref:`pthread-api`: ESP-IDF's pthread API.
13 - :ref:`c11-std`: C11 standard introduces special keyword to declare variables as thread local.
14
15.. _freertos-native:
16
17FreeRTOS Native API
18--------------------
19
20The ESP-IDF FreeRTOS provides the following API to manage thread local variables:
21
22 - :cpp:func:`vTaskSetThreadLocalStoragePointer`
23 - :cpp:func:`pvTaskGetThreadLocalStoragePointer`
24 - :cpp:func:`vTaskSetThreadLocalStoragePointerAndDelCallback`
25
26In this case maximum number of variables that can be allocated is limited by
27``configNUM_THREAD_LOCAL_STORAGE_POINTERS`` macro. Variables are kept in the task control block (TCB)
28and accessed by their index. Note that index 0 is reserved for ESP-IDF internal uses.
29Using that API user can allocate thread local variables of an arbitrary size and assign them to any number of tasks.
30Different tasks can have different sets of TLS variables.
31If size of the variable is more then 4 bytes then user is responsible for allocating/deallocating memory for it.
32Variable's deallocation is initiated by FreeRTOS when task is deleted, but user must provide function (callback)
33to do proper cleanup.
34
35.. _pthread-api:
36
37Pthread API
38----------------
39
40The ESP-IDF provides the following pthread API to manage thtread local variables:
41
42 - :cpp:func:`pthread_key_create`
43 - :cpp:func:`pthread_key_delete`
44 - :cpp:func:`pthread_getspecific`
45 - :cpp:func:`pthread_setspecific`
46
47This API has all benefits of the one above, but eliminates some its limits. The number of variables is
48limited only by size of available memory on the heap.
49Due to the dynamic nature this API introduces additional performance overhead compared to the native one.
50
51.. _c11-std:
52
53C11 Standard
54------------
55
56The ESP-IDF FreeRTOS supports thread local variables according to C11 standard (ones specified with ``__thread`` keyword).
57For details on this GCC feature please see https://gcc.gnu.org/onlinedocs/gcc-5.5.0/gcc/Thread-Local.html#Thread-Local.
58Storage for that kind of variables is allocated on the task's stack.
59Note that area for all such variables in the program will be allocated on the stack of
60every task in the system even if that task does not use such variables at all. For example
61ESP-IDF system tasks (like ``ipc``, ``timer`` tasks etc.) will also have that extra stack space allocated.
62So this feature should be used with care. There is a tradeoff: C11 thread local variables are quite handy
63to use in programming and can be accessed using just a few Xtensa instructions, but this benefit goes
64with the cost of additional stack usage for all tasks in the system.
65Due to static nature of variables allocation all tasks in the system have the same sets of C11 thread local variables.
66