Linker and Libraries Guide

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 dtvt 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)
extern void * ___tls_get_addr(TLS_index * ti);    (x86)

Note –

The SPARC and x86 definitions of this function have the same function signature. However, the x86 version does not use the default x86 calling convention of passing arguments on the stack. Instead, the x86 version passes it's argument via the %eax register which is more efficient. To denote that this alternate calling method is used, the x86 function name has three leading underscores in its name.


Both versions of tls_get_addr() check the per-thread generation counter, gent, to determine whether the vector needs to be updated. If the vector dtvt is out of date, the routine updates the vector, possibly reallocating it to make room for more entries. The routine then checks to see if the TLS block corresponding to dtvt,m has been allocated. If it has not been allocated, the routine allocates and initializes the block, using the information in the list of initialization records provided by the runtime linker. The pointer dtvt,m is set to point to the allocated block. The routine returns a pointer to the given offset within the block.