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