nuttx/tls: Remove the max key limiatation in task_tls_alloc and pthread_key_create

Signed-off-by: cuiziwei <cuiziwei@xiaomi.com>
This commit is contained in:
cuiziwei 2023-07-11 10:52:32 +08:00 committed by Xiang Xiao
parent 5334c065b4
commit 7c8bb8c293
6 changed files with 61 additions and 62 deletions

View File

@ -73,38 +73,14 @@ extern "C"
#define EXTERN extern
#endif
/* type tls_ndxset_t & tls_dtor_t *******************************************/
/* type tls_dtor_t **********************************************************/
/* Smallest addressable type that can hold the entire configured number of
* TLS data indexes.
*/
#if CONFIG_TLS_NELEM > 0
# if CONFIG_TLS_NELEM > 64
# error Too many TLS elements
# elif CONFIG_TLS_NELEM > 32
typedef uint64_t tls_ndxset_t;
# elif CONFIG_TLS_NELEM > 16
typedef uint32_t tls_ndxset_t;
# elif CONFIG_TLS_NELEM > 8
typedef uint16_t tls_ndxset_t;
# else
typedef uint8_t tls_ndxset_t;
# endif
#endif
#if CONFIG_TLS_TASK_NELEM > 0
# if CONFIG_TLS_TASK_NELEM > 64
# error Too many TLS elements
# elif CONFIG_TLS_TASK_NELEM > 32
typedef uint64_t tls_task_ndxset_t;
# elif CONFIG_TLS_TASK_NELEM > 16
typedef uint32_t tls_task_ndxset_t;
# elif CONFIG_TLS_TASK_NELEM > 8
typedef uint16_t tls_task_ndxset_t;
# else
typedef uint8_t tls_task_ndxset_t;
# endif
typedef CODE void (*tls_dtor_t)(FAR void *);
#endif
typedef CODE void (*tls_dtor_t)(FAR void *);
@ -149,7 +125,6 @@ struct task_info_s
uintptr_t ta_telem[CONFIG_TLS_TASK_NELEM]; /* Task local storage elements */
#endif
#if CONFIG_TLS_NELEM > 0
tls_ndxset_t ta_tlsset; /* Set of TLS indexes allocated */
tls_dtor_t ta_tlsdtor[CONFIG_TLS_NELEM]; /* List of TLS destructors */
#endif
#ifndef CONFIG_BUILD_KERNEL

View File

@ -33,6 +33,19 @@
#if CONFIG_TLS_NELEM > 0
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* Name: pthread_destructor
****************************************************************************/
static void pthread_destructor(FAR void *arg)
{
UNUSED(arg);
}
/****************************************************************************
* Public Functions
****************************************************************************/
@ -95,13 +108,19 @@ int pthread_key_create(FAR pthread_key_t *key,
{
/* Is this candidate index available? */
tls_ndxset_t mask = (tls_ndxset_t)1 << candidate;
if ((info->ta_tlsset & mask) == 0)
if (info->ta_tlsdtor[candidate] == NULL)
{
/* Yes.. allocate the index and break out of the loop */
info->ta_tlsset |= mask;
if (destructor)
{
info->ta_tlsdtor[candidate] = destructor;
}
else
{
info->ta_tlsdtor[candidate] = pthread_destructor;
}
*key = candidate;
ret = OK;
break;

View File

@ -58,7 +58,6 @@
int pthread_key_delete(pthread_key_t key)
{
FAR struct task_info_s *info = task_get_info();
tls_ndxset_t mask;
int ret = EINVAL;
DEBUGASSERT(info != NULL);
@ -69,12 +68,10 @@ int pthread_key_delete(pthread_key_t key)
* modification of the group TLS index set.
*/
mask = (tls_ndxset_t)1 << key;
ret = nxmutex_lock(&info->ta_lock);
if (ret == OK)
{
DEBUGASSERT((info->ta_tlsset & mask) != 0);
info->ta_tlsset &= ~mask;
info->ta_tlsdtor[key] = NULL;
nxmutex_unlock(&info->ta_lock);
}
else

View File

@ -45,7 +45,7 @@ config TLS_LOG2_MAXSTACK
config TLS_NELEM
int "Number of TLS elements"
default 0
range 0 64
range 0 255
---help---
The number of unique TLS elements. These can be accessed with
the user library functions tls_get_value() and tls_set_value()
@ -57,7 +57,7 @@ config TLS_NELEM
config TLS_TASK_NELEM
int "Number of Task Local Storage elements"
default 0
range 0 64
range 0 255
---help---
The number of unique Task Local Storage elements similar with
Thread Local Storage.

View File

@ -54,26 +54,20 @@ void tls_destruct(void)
FAR struct tls_info_s *tls = tls_get_info();
FAR void *tls_elem_ptr = NULL;
tls_dtor_t destructor;
tls_ndxset_t tlsset;
int candidate;
DEBUGASSERT(info != NULL);
tlsset = info->ta_tlsset;
for (candidate = CONFIG_TLS_NELEM - 1; candidate >= 0; candidate--)
{
/* Is this candidate index available? */
tls_ndxset_t mask = (tls_ndxset_t)1 << candidate;
if (tlsset & mask)
{
tls_elem_ptr = (FAR void *)tls->tl_elem[candidate];
destructor = info->ta_tlsdtor[candidate];
if (tls_elem_ptr && destructor)
{
destructor(tls_elem_ptr);
}
}
tls->tl_elem[candidate] = 0;
}

View File

@ -36,10 +36,22 @@
#if CONFIG_TLS_TASK_NELEM > 0
static tls_task_ndxset_t g_tlsset;
static mutex_t g_tlslock = NXMUTEX_INITIALIZER;
static tls_dtor_t g_tlsdtor[CONFIG_TLS_TASK_NELEM];
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* Name: tls_dtor
****************************************************************************/
static void tls_dtor(FAR void *arg)
{
UNUSED(arg);
}
/****************************************************************************
* Public Functions
****************************************************************************/
@ -73,11 +85,17 @@ int task_tls_alloc(tls_dtor_t dtor)
for (candidate = 0; candidate < CONFIG_TLS_TASK_NELEM; candidate++)
{
tls_task_ndxset_t mask = (tls_task_ndxset_t)1 << candidate;
if ((g_tlsset & mask) == 0)
if (g_tlsdtor[candidate] == NULL)
{
if (dtor)
{
g_tlsset |= mask;
g_tlsdtor[candidate] = dtor;
}
else
{
g_tlsdtor[candidate] = tls_dtor;
}
ret = candidate;
break;
}
@ -109,20 +127,16 @@ void task_tls_destruct(void)
FAR struct task_info_s *info = task_get_info();
for (candidate = CONFIG_TLS_TASK_NELEM - 1; candidate >= 0; candidate--)
{
tls_task_ndxset_t mask = (tls_task_ndxset_t)1 << candidate;
if ((g_tlsset & mask) != 0)
{
elem = info->ta_telem[candidate];
dtor = g_tlsdtor[candidate];
if (dtor != NULL && elem != 0)
{
dtor((void *)elem);
dtor((FAR void *)elem);
}
info->ta_telem[candidate] = 0;
}
}
}
#endif