Thread Local Storage

Overview

Thread Local Storage (TLS) refers to variables that are private to a thread.

The C11 standard began supporting thread local storage, introducing the _Thread_local keyword. The C2X standard introduces the thread_local keyword. The gcc and clang compilers also introduce the __thread keyword.

When global variables are defined using the above keywords, each thread gets a copy of this global variable and accesses its own copy.

TLS Models

There are four TLS models in gcc and clang’s implementation:

  • -ftls-model=global-dynamic: Used for dynamic linking. Must be combined with the compilation option -fpic to be effective. Requires a definition of __tls_get_addr(). Without -fpic, it will actually become -ftls-model=initial-exec;
  • -ftls-model=local-dynamic: Used for dynamic linking. Must be combined with the compilation option -fpic to be effective. Requires a definition of __tls_get_addr(). Without -fpic, it will actually become -ftls-model=initial-exec;
  • -ftls-model=initial-exec: Used for static linking. Requires a definition of __aeabi_read_tp(), which returns the base address of the thread’s .tdata section. The OFFSET of the TLS variable is obtained from the .got section, i.e., OFFSET = GOT[name]. Ultimately, the variable’s address is __aeabi_read_tp() + OFFSET.
  • -ftls-model=local-exec: Used for static linking. Requires a definition of __aeabi_read_tp(), which returns the base address of the thread’s .tdata section. The OFFSET of the TLS variable is obtained as an immediate value. Ultimately, the variable’s address is __aeabi_read_tp() + OFFSET. Compared to -ftls-model=initial-exec, it saves one memory access operation, making it the most efficient of the four models.

XWOS TLS Implementation

XWOS supports both -ftls-model=initial-exec and -ftls-model=local-exec. Therefore, the .got section must be included in the linker script:

        .got : {
                *(.got.plt) *(.igot.plt) *(.got) *(.igot)
        } > code_mr AT> code_mr