JavaScript is required to for searching.
Skip Navigation Links
Exit Print View
Oracle Solaris 11.1 Linkers and Libraries Guide     Oracle Solaris 11.1 Information Library
search filter icon
search icon

Document Information


Part I Using the Link-Editor and Runtime Linker

1.  Introduction to the Oracle Solaris Link Editors

2.  Link-Editor

3.  Runtime Linker

4.  Shared Objects

Part II Quick Reference

5.  Link-Editor Quick Reference

Part III Advanced Topics

6.  Direct Bindings

7.  Building Objects to Optimize System Performance

8.  Mapfiles

9.  Interfaces and Versioning

10.  Establishing Dependencies with Dynamic String Tokens

11.  Extensibility Mechanisms

Part IV ELF Application Binary Interface

12.  Object File Format

13.  Program Loading and Dynamic Linking

14.  Thread-Local Storage

C/C++ Programming Interface

Thread-Local Storage Section

Runtime Allocation of Thread-Local Storage

Program Startup

Thread Creation

Post-Startup Dynamic Loading

Deferred Allocation of Thread-Local Storage Blocks

Thread-Local Storage Access Models

SPARC: Thread-Local Variable Access

SPARC: General Dynamic (GD)

SPARC: Local Dynamic (LD)

32-bit SPARC: Initial Executable (IE)

64-bit SPARC: Initial Executable (IE)

SPARC: Local Executable (LE)

SPARC: Thread-Local Storage Relocation Types

32-bit x86: Thread-Local Variable Access

32-bit x86: General Dynamic (GD)

x86: Local Dynamic (LD)

32-bit x86: Initial Executable (IE)

32-bit x86: Local Executable (LE)

32-bit x86: Thread-Local Storage Relocation Types

x64: Thread-Local Variable Access

x64: General Dynamic (GD)

x64: Local Dynamic (LD)

x64: Initial Executable (IE)

x64: Local Executable (LE)

x64: Thread-Local Storage Relocation Types

Part V Appendices

A.  Linker and Libraries Updates and New Features

B.  System V Release 4 (Version 1) Mapfiles


C/C++ Programming Interface

Variables are declared thread-local using the __thread keyword, as in the following examples.

__thread int i;
__thread char *p;
__thread struct state s;

During loop optimizations, the compiler can choose to create thread-local temporaries as needed.

The __thread keyword can be applied to any global, file-scoped static, or function-scoped static variable. It has no effect on automatic variables, which are always thread-local.

In C++, a thread-local variable can not be initialized if the initialization requires a static constructor. Otherwise, a thread-local variable can be initialized to any value that would be legal for an ordinary static variable.

No variable, thread-local or otherwise, can be statically initialized to the address of a thread-local variable.


Thread-local variables can be declared externally and referenced externally. Thread-local variables are subject to the same interposition rules as normal symbols.

Dynamic loading restrictions

Various TLS access models are available. See Thread-Local Storage Access Models. Shared object developers should be aware of the restrictions imposed by some of these access models in relation to object loading. A shared object can be dynamically loaded during process startup, or after process startup by means of lazy loading, filters, or dlopen(3C). At the completion of process startup, the thread pointer for the main thread is established. All static TLS storage requirements are calculated before the thread pointer is established.

Shared objects that reference thread-local variables, should insure that every translation unit containing the reference is compiled with a dynamic TLS model. This model of access provides the greatest flexibility for loading shared objects. However, static TLS models can generate faster code. Shared objects that use a static TLS model can be loaded as part of process initialization. However, after process initialization, shared objects that use a static TLS model can only be loaded if sufficient backup TLS storage is available. See Program Startup.

Address-of operator

The address-of operator, &, can be applied to a thread-local variable. This operator is evaluated at runtime, and returns the address of the variable within the current thread. The address obtained by this operator can be used freely by any thread in the process as long as the thread that evaluated the address remains in existence. When a thread terminates, any pointers to thread-local variables in that thread become invalid.

When dlsym(3C) is used to obtain the address of a thread-local variable, the address that is returned is the address of the instance of that variable in the thread that called dlsym().