On 3/24/2021 8:38 AM, Matias N. wrote:
So, if I follow correctly, we could maybe have one TLS pointer pointing to a
struct of pointers, one per each group of globals (one of this groups, would be
the set of variables used by getopt()), like:
struct task_globals_s
{
struct getopt_globals_s *getopt_globals;
/* ...others */
};
Then getopt globals would only be allocated once for each task, and only when
getopt() is called.
Something like that?
Yes, that is a possibility. But that is already implemented just as you
describe as POSIX thread-specific data.
The TLS data structure is defined in include/nuttx/tls.h as following.
it is just an array of pointer size things and the errno variable.
struct tls_info_s
{
#if CONFIG_TLS_NELEM > 0
uintptr_t tl_elem[CONFIG_TLS_NELEM]; /* TLS elements */
#endif
int tl_errno; /* Per-thread error number */
};
This structure lies at the "bottom" of stack of every thread in user space.
The standard pthread_getspecific() is then implemented as:
FAR void *pthread_getspecific(pthread_key_t key)
{
return (FAR void *)tls_get_value((int)key);
}
Where
uintptr_t tls_get_value(int tlsindex)
{
FAR struct tls_info_s *info;
uintptr_t ret = 0;
DEBUGASSERT(tlsindex >= 0 && tlsindex < CONFIG_TLS_NELEM);
if (tlsindex >= 0 && tlsindex < CONFIG_TLS_NELEM)
{
/* Get the TLS info structure from the current threads stack */
info = up_tls_info();
DEBUGASSERT(info != NULL);
/* Get the element value from the TLS info. */
ret = info->tl_elem[tlsindex];
}
return ret;
}
The POSIX interface supports a pthread_key_create() to manage the indexing.