Deferred Allocation of Thread-Local Storage Blocks
In a dynamic TLS model, when a thread
t
needs to access a
TLS block for object
m
, the code updates the
dtv
t and performs
the initial allocation of the TLS block. The
thread library provides the following interface to provide for
dynamic TLS allocation.
typedef struct { unsigned long ti_moduleid; unsigned long ti_tlsoffset; } TLS_index; extern void *__tls_get_addr(TLS_index *ti); (SPARC and x64) extern void *___tls_get_addr(TLS_index *ti); (32-bit x86)
Note:
The SPARC and 64-bit x86 definitions of this function have the same function signature. However, the 32-bit x86 version does not use the default calling convention of passing arguments on the stack. Instead, the 32-bit x86 version passes its arguments by means of the%eax
register which is more
efficient. To denote that this alternate calling method is
used, the 32-bit x86 function name has three leading
underscores in its name.
Both versions of tls_get_addr
() check the
per-thread generation counter,
gen
t, to determine
whether the vector needs to be updated. If the vector
dtv
t is out of
date, the routine updates the vector, possibly reallocating the
vector to make room for more entries. The routine then checks to see
if the TLS block corresponding to
dtv
t,m has been
allocated. If the vector has not been allocated, the routine
allocates and initializes the block. The routine uses the
information in the list of initialization records provided by the
runtime linker. The pointer dtv
t,m is set to point to the allocated block.
The routine returns a pointer to the given offset within the
block.