Se we can either add something special just as for errno or use entries in that 
array (which would require establishing a minimum number of entries to satisfy 
the case of getopt en potentially others). I think it is better to somehow 
"reserve" space for the known required cases.

What i'm worried about is: how many other cases like this there could be? Maybe 
there will be a considerable number of this entries added to TLS structure 
(yes, four bytes, but they can add up quickly). I would personally prefer to 
use reentrant versions when they are available, instead of increasing memory 
use of every thread. Not sure what is really best here...

On Wed, Mar 24, 2021, at 11:51, Gregory Nutt wrote:
> 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.
> 
> 
> 
> 

Reply via email to