doc: add info about using thread local storage

Adds a simple document on thread local storage.

Signed-off-by: Daniel Leung <daniel.leung@intel.com>
This commit is contained in:
Daniel Leung 2020-10-06 13:04:45 -07:00 committed by Andrew Boie
parent e95d14ae9b
commit 3c79b565fe
3 changed files with 86 additions and 0 deletions

View file

@ -35,3 +35,4 @@ User and Developer Guides
west/index
optimizations/index
zephyr_cmake_package.rst
thread_local_storage.rst

View file

@ -301,6 +301,30 @@ This means implementing an architecture-specific version of
:option:`CONFIG_ARCH_HAS_THREAD_ABORT` as needed for the architecture (e.g. see
:zephyr_file:`arch/arm/core/aarch32/cortex_m/Kconfig`).
Thread Local Storage
********************
To enable thread local storage on a new architecture:
#. Implement :c:func:`arch_tls_stack_setup` to setup the TLS storage area in
stack. Refer to the toolchain documentation on how the storage area needs
to be structured. Some helper functions can be used:
* Function :c:func:`z_tls_data_size` returns the size
needed for thread local variables (excluding any extra data required by
toolchain and architecture).
* Function :c:func:`z_tls_copy` prepares the TLS storage area for
thread local variables. This only copies the variable themselves and
does not do architecture and/or toolchain specific data.
#. In the context switching, grab the ``tls`` field inside the new thread's
``struct k_thread`` and put it into an appropriate register (or some
other variable) for access to the TLS storage area. Refer to toolchain
and architecture documentation on which registers to use.
#. In kconfig, add ``select CONFIG_ARCH_HAS_THREAD_LOCAL_STORAGE`` to
kconfig related to the new architecture.
#. Run the ``tests/kernel/threads/tls`` to make sure the new code works.
Device Drivers
**************
@ -845,6 +869,9 @@ Threads
.. doxygengroup:: arch-threads
:project: Zephyr
.. doxygengroup:: arch-tls
:project: Zephyr
Power Management
================

View file

@ -0,0 +1,58 @@
.. _thread_local_storage:
Thread Local Storage (TLS)
##########################
Thread Local Storage (TLS) allows variables to be allocated on a per-thread
basis. These variables are stored in the thread stack which means every
thread has its own copy of these variables.
Zephyr currently requires toolchain support for TLS.
Configuration
*************
To enable thread local storage in Zephyr, :option:`CONFIG_THREAD_LOCAL_STORAGE`
needs to be enabled. Note that this option may not be available if
the architecture or the SoC does not have the hidden option
:option:`CONFIG_ARCH_HAS_THREAD_LOCAL_STORAGE` enabled, which means
the architecture or the SoC does not have the necessary code to support
thread local storage and/or the toolchain does not support TLS.
:option:`CONFIG_ERRNO_IN_TLS` can be enabled together with
:option:`CONFIG_ERRNO` to let the variable ``errno`` be a thread local
variable. This allows user threads to access the value of ``errno`` without
making a system call.
Declaring and Using Thread Local Variables
******************************************
The keyword ``__thread`` can be used to declare thread local variables.
For example, to declare a thread local variable in header files:
.. code-block:: c
extern __thread int i;
And to declare the actual variable in source files:
.. code-block:: c
__thread int i;
Keyword ``static`` can also be used to limit the variable within a source file:
.. code-block:: c
static __thread int j;
Using the thread local variable is the same as using other variable, for example:
.. code-block:: c
void testing(void) {
i = 10;
}