<html><head><title>Thread-Local Storage</title>
<body><h1>Thread-Local Storage</h1>

Lawrence Crowl, 2005-08-25, N1874=05-0134

<h2>Introduction</a></h2>

<p> In multi-threaded applications,
there often arises the need to maintain data
that is unique to a thread.
We call this thread-local storage.

<p> Several techniques have been used to accomplish this task.
Notable among them is the POSIX
<tt>getthreadspecific</tt> and <tt>setthreadspecific</tt> facility.
Unfortunately, this facility is clumsy and slow.
In addition, the facility is not particularly helpful
when converting a single-threaded application
to a multi-threaded application.

<p> Several vendors have provided a language extension
for a new storage class that indicates that a variable has thread duration.
Use of thread variables is relatively easy and
access to thread variables is relatively fast.
In addition,
the conversion of a single-threaded application using static-duration variables 
to a multi-threaded application using thread-duration variables
requires less wholesale program restructuring.

<p> Roughly equivalent extensions are available from

<table>

<tr>
<td><a href="http://www.gnu.org/">GNU</a>
<td><a href="http://gcc.gnu.org/onlinedocs/gcc-3.3.1/gcc/Thread-Local.html#Thread-Local">Thread-Local Storage</a></td>
</tr>

<tr>
<td><a href="http://www.hp.com/">Hewlett-Packard</a>
<td><a href="http://h30097.www3.hp.com/docs/base_doc/DOCUMENTATION/V51B_HTML/ARH9VDTE/THRDSCHP.HTM#anch_1024">Using Thread Local Storage</a></td>
</tr>

<tr>
<td><a href="http://www.hp.com/">Hewlett-Packard</a>
<td><a href="http://devrsrc1.external.hp.com/STKT/impacts/i320.html">Tru64 UNIX to HP-UX STK: critical Impact: TLS - feature differences (CrCh320)</a></td>
</tr>

<tr>
<td><a href="http://www.intel.com/">Intel</a>
<td><a href="http://www.intel.com/software/products/compilers/clin/docs/ug_cpp/lin1057.htm">Thread-local Storage</a></td>
</tr>

<tr>
<td><a href="http://www.microsoft.com/">Microsoft</a>
<td><a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vccelng/htm/decla_44.asp">Thread Local Storage</a></td>
</tr>

<tr>
<td><a href="http://www.sun.com/">Sun Microsystems</a>
<td><a href="http://docs.sun.com/source/817-5070/Language_Extensions.html#pgfId-997650">Thread-Local Storage</a></td>
</tr>

</table>

<p> The C++ standard should adopt existing practice for thread-local storage.
In addition, the C++ standard should extend existing practice
to enable broader use.

<h2>Proposal</h2>

<p> The specification outline is as follows.
We defer detailed changes to the text of the standard
pending adoption of the proposal in principle.

<h3>Thread Storage Duration</h3>

<p> Add a new storage duration called thread duration.
Objects with thread duration are unique to each thread.

<p> Those objects which may have static duration
may have thread duration instead.
These objects include
file global variables, file static variables,
function local static variables, and class static member variables.

<h3>Storage Class <tt>__thread</tt></h3>

<p> Add <tt>__thread</tt>,
a new keyword and storage class specifier.
The <tt>__thread</tt> specifier
indicates that the variable has thread duration.

<p> Variables declared with the <code>__thread</code> specifier
are bound as they would be without the <code>__thread</code> specifier.

<h3>Addresses of Thread Variable</h3>

<p> The address-of operator (<code>&amp;</code>),
when applied to a thread variable,
is evaluated at run time
and returns the address of the current thread's variable.
Therefore, the address of a thread variable is not a constant.

<p> Thread-local storage defines lifetime and scope, not accessibility.
That is, one may take the address of a thread-local variable
and pass it to other threads.

<p> The address of a thread variable is stable
for the lifetime of the corresponding thread.
The address of a thread variable
may be freely used during the variable's lifetime
by any thread in the program.
When a thread terminates,
all addresses of that thread's variables are invalid
and may not be used.

<h3>Thread Variable Initialization</h3>

<p> A thread variable may be statically initialized
as would any other static-duration variable.

<p> At present, all implementations of thread-local storage
do not support dynamic initalization (and presumably non-trivial destructors).
Standardization of existing practice would include this restriction.
However, generality implies dynamic initialization
and destructor execution on thread termination.

<h2>Other Issues</h2>

<p> There are some other issues that deserve mention
even though they are not properly part of the C++ standard
because they affect real programs.

<h3>Dynamic Libraries</h3>

<p> The allocation of thread-local storage
for the full product of threads and dynamic libraries
could result in very large storage requirements.
The Sun Microsystems implementation
only allocates thread-local storage for a dynamic library
when the thread uses a variable from that library.
That is, the Sun implementation
allocates memory lazily for each thread and dynamic library pair.
To avoid bloated programs,
the language definition must permit this optimization.

<p> The system may immediately deallocate
the storage associated with a thread and dynamic library pair
when either the thread terminates or the library is closed.
The system is not required to deallocate immediately.
However, the system is required to not leak storage.
Thread-local storage for a thread must be reclaimed
no later than a subsequent thread creation.
Thread-local storage for a library within a thread
must be reclaimed no later than a subsequent open of that library.
(Opening another library does not require storage reclamation,
though doing so would ceratinly reduce storage consumption.)

<h3>System Interface</h2>

<p> When <tt>dlsym()</tt> is used on a thread variable,
the address returned
will be the address of the currently executing thread's variable.

</body></html>
