Linux's Thread Local Storage Implementation

Linux's thread local storage implementation

It's a little complicated (this document explains it in great detail), but it's basically neither. Instead the compiler puts a special .tdata section in the executable, which contains all the thread-local variables. At runtime, a new data section for each thread is created with a copy of the data in the (read-only) .tdata section, and when threads are switched at runtime, the section is also switched automatically.

The end result is that __thread variables are just as fast as regular variables, and they don't take up extra stack space, either.

Implementation of Thread-local storage (TLS) in C/C++ (multithreading)

TLS is implemented as a data array within each thread object. Each thread object has its own local copy of the array, and each array is the same size. When you declare a global/static variable as using TLS, it is associated with an index into those arrays (that is how the compiler/OS knows how many array slots to allocate). Thus, when you access the variable at runtime, you are really accessing the associated slot in the data array of the thread context that is accessing the variable.

TLS may be a new native feature in C++11, but it has been available in various OS APIs for a long time.

TLS is implemented on Windows using the Win32 API TlsAlloc(), TlsGetValue(), TlsSetValue(), and TlsFree() functions. Here is an overview of how it works: Thread Local Storage

Here is an overview of how TLS works on Linux: ELF Handling For Thread-Local Storage

Thread Specific Data vs Thread Local Storage

The pthread_key_create and friends are much older, and thus supported on more systems.

The __thread is a relative newcomer, is generally much more convenient to use, and (according to Wikipedia) is supported on most POSIX systems that still matter: Solaris Studio C/C++, IBM XL C/C++, GNU C, Clang and Intel C++ Compiler (Linux systems).

The __thread also has a significant advantage that it is usable from signal handlers (with the exception of using __thread from dlopened shared library, see this bug), because its use does not involve malloc (with the same exception).



Related Topics



Leave a reply



Submit