11.10.3 Putting it all together
Given an application that has the following declarations:
__thread int errno;
__thread int active_thread = -1;
The language tool will allocate the two 'int' sized objects into separate data space and
initialize them at startup to be 0 (errno) and -1
(active_thread).
At the main the TLS context will be initialized to access the two
variables declared.
A new context may be created and intilialised using the following sequence:
void *create_thread_context(void) {
void *tls_data;
void *aligned_tls_data;
int tls_size = _tls_size();
int tls_alignment = _tls_align(void);
// allocate some aligned data
tls_data = malloc(tls_size + (tls_alignment-1));
// align the result
aligned_tls_data = (tls_data + (tls_alignment-1)) & (~(tls_alignment-1));
// initialise the new tls space to the default initial values
// these will be the same as main()'s default values
_init_tls(aligned_tls_data);
// if you wish to 'free' the space later, record tls_data and free that
// return the allocated space
return aligned_tls_data;
}
Once the space has been allocated, it may be activated at any time. Likely this would be on a context switch of some sort. It may also be that the current TLS context would like to be preserved for later restoration.
// __current_tcb is used by the language tool to access TLS data
// this may be recorded
extern void * __current_tcb;
void *caller_tls_context = __current_tcb;
// record current active thread_id, if this is called from the main thread
// this value will come from the main TLS block
int current_thread = ++active_thread;
// create and and initialise a new context
void *my_context = create_thread_context();
if (my_context == NULL) abort();
_set_tls(my_context);
// set the active_thread id in the current TLS block; this will not update
// any other versions of the 'active_thread' TLS variable
active_thread = current_thread;
execute_thread();
// restore context to the previous (possibly the main TLS thread)
_set_tls(caller_tls_context);
