Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion fs/procfs/fs_procfsproc.c
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@
#endif

#include <nuttx/irq.h>
#include <nuttx/arch.h>
#include <nuttx/tls.h>
#include <nuttx/sched.h>
#include <nuttx/kmalloc.h>
#include <nuttx/environ.h>
Expand Down
9 changes: 0 additions & 9 deletions include/nuttx/arch.h
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,6 @@
#include <nuttx/compiler.h>
#include <nuttx/cache.h>
#include <nuttx/sched.h>
#include <nuttx/tls.h>

/****************************************************************************
* Pre-processor definitions
Expand Down Expand Up @@ -1826,14 +1825,6 @@ int up_timer_start(FAR const struct timespec *ts);
* implementation provided here assume the arch has a "push down" stack.
*/

#ifndef up_tls_info
# if defined(CONFIG_TLS_ALIGNED) && !defined(__KERNEL__)
# define up_tls_info() TLS_INFO((uintptr_t)up_getsp())
# else
# define up_tls_info() tls_get_info()
# endif
#endif

/****************************************************************************
* Name: up_tls_size
*
Expand Down
1 change: 1 addition & 0 deletions include/nuttx/pthread.h
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,7 @@ void nx_pthread_exit(FAR void *exit_value) noreturn_function;
****************************************************************************/

#ifdef CONFIG_PTHREAD_CLEANUP
struct tls_info_s;
void pthread_cleanup_popall(FAR struct tls_info_s *tls);
#endif

Expand Down
6 changes: 3 additions & 3 deletions include/nuttx/sched.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,18 +33,16 @@
#include <sched.h>
#include <signal.h>
#include <semaphore.h>
#include <pthread.h>
#include <time.h>

#include <nuttx/clock.h>
#include <nuttx/irq.h>
#include <nuttx/tls.h>
#include <nuttx/wdog.h>
#include <nuttx/mm/shm.h>
#include <nuttx/fs/fs.h>
#include <nuttx/net/net.h>

#include <arch/arch.h>

/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
Expand Down Expand Up @@ -393,6 +391,8 @@ struct stackinfo_s
* the struct task_group_s is free.
*/

struct task_info_s;

#ifndef CONFIG_DISABLE_PTHREAD
struct join_s; /* Forward reference */
/* Defined in sched/pthread/pthread.h */
Expand Down
89 changes: 6 additions & 83 deletions include/nuttx/tls.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@

#include <nuttx/config.h>

#include <nuttx/arch.h>
#include <nuttx/atexit.h>

#include <sys/types.h>
Expand Down Expand Up @@ -209,88 +210,6 @@ struct tls_info_s
* Public Function Prototypes
****************************************************************************/

/****************************************************************************
* Name: tls_alloc
*
* Description:
* Allocate a group-unique TLS data index
*
* Input Parameters:
* dtor - The destructor of TLS data element
*
* Returned Value:
* A TLS index that is unique for use within this task group.
*
****************************************************************************/

#if CONFIG_TLS_NELEM > 0
int tls_alloc(CODE void (*dtor)(FAR void *));
#endif

/****************************************************************************
* Name: tls_free
*
* Description:
* Release a group-unique TLS data index previous obtained by tls_alloc()
*
* Input Parameters:
* tlsindex - The previously allocated TLS index to be freed
*
* Returned Value:
* OK is returned on success; a negated errno value will be returned on
* failure:
*
* -EINVAL - the index to be freed is out of range.
*
****************************************************************************/

#if CONFIG_TLS_NELEM > 0
int tls_free(int tlsindex);
#endif

/****************************************************************************
* Name: tls_get_value
*
* Description:
* Return an the TLS data value associated with the 'tlsindx'
*
* Input Parameters:
* tlsindex - Index of TLS data element to return
*
* Returned Value:
* The value of TLS element associated with 'tlsindex'. Errors are not
* reported. Zero is returned in the event of an error, but zero may also
* be valid value and returned when there is no error. The only possible
* error would be if tlsindex < 0 or tlsindex >=CONFIG_TLS_NELEM.
*
****************************************************************************/

#if CONFIG_TLS_NELEM > 0
uintptr_t tls_get_value(int tlsindex);
#endif

/****************************************************************************
* Name: tls_set_value
*
* Description:
* Set the TLS element associated with the 'tlsindex' to 'tlsvalue'
*
* Input Parameters:
* tlsindex - Index of TLS data element to set
* tlsvalue - The new value of the TLS data element
*
* Returned Value:
* Zero is returned on success, a negated errno value is return on
* failure:
*
* EINVAL - tlsindex is not in range.
*
****************************************************************************/

#if CONFIG_TLS_NELEM > 0
int tls_set_value(int tlsindex, uintptr_t tlsvalue);
#endif

#if CONFIG_TLS_TASK_NELEM > 0

/****************************************************************************
Expand Down Expand Up @@ -383,7 +302,11 @@ uintptr_t task_tls_get_value(int tlsindex);
*
****************************************************************************/

#if !defined(CONFIG_TLS_ALIGNED) || defined(__KERNEL__)
#if defined(up_tls_info)
# define tls_get_info() up_tls_info()
#elif defined(CONFIG_TLS_ALIGNED)
# define tls_get_info() TLS_INFO(up_getsp())
#else
FAR struct tls_info_s *tls_get_info(void);
#endif

Expand Down
3 changes: 1 addition & 2 deletions libs/libc/errno/lib_errno.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@

#include <nuttx/config.h>

#include <nuttx/arch.h>
#include <nuttx/tls.h>

/****************************************************************************
Expand Down Expand Up @@ -57,7 +56,7 @@ FAR int *__errno(void)
{
/* Get the TLS tls_info_s structure instance for this thread */

FAR struct tls_info_s *tlsinfo = up_tls_info();
FAR struct tls_info_s *tlsinfo = tls_get_info();

/* And return the return refernce to the error number */

Expand Down
5 changes: 2 additions & 3 deletions libs/libc/pthread/pthread_cleanup.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@
#include <sched.h>
#include <assert.h>

#include <nuttx/arch.h>
#include <nuttx/sched.h>
#include <nuttx/tls.h>
#include <nuttx/pthread.h>
Expand Down Expand Up @@ -119,7 +118,7 @@ static void pthread_cleanup_pop_tls(FAR struct tls_info_s *tls, int execute)

void pthread_cleanup_pop(int execute)
{
FAR struct tls_info_s *tls = up_tls_info();
FAR struct tls_info_s *tls = tls_get_info();

DEBUGASSERT(tls != NULL);

Expand All @@ -135,7 +134,7 @@ void pthread_cleanup_pop(int execute)

void pthread_cleanup_push(pthread_cleanup_t routine, FAR void *arg)
{
FAR struct tls_info_s *tls = up_tls_info();
FAR struct tls_info_s *tls = tls_get_info();

DEBUGASSERT(tls != NULL);
DEBUGASSERT(tls->tos < CONFIG_PTHREAD_CLEANUP_STACKSIZE);
Expand Down
3 changes: 1 addition & 2 deletions libs/libc/pthread/pthread_exit.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@
#include <debug.h>
#include <sched.h>

#include <nuttx/arch.h>
#include <nuttx/pthread.h>
#include <nuttx/tls.h>

Expand Down Expand Up @@ -64,7 +63,7 @@ void pthread_exit(FAR void *exit_value)
#endif

#ifdef CONFIG_PTHREAD_CLEANUP
pthread_cleanup_popall(up_tls_info());
pthread_cleanup_popall(tls_get_info());
#endif

#if CONFIG_TLS_NELEM > 0
Expand Down
23 changes: 22 additions & 1 deletion libs/libc/pthread/pthread_getspecific.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,12 @@
#include <nuttx/config.h>

#include <pthread.h>
#include <assert.h>

#include <nuttx/tls.h>

#if CONFIG_TLS_NELEM > 0

/****************************************************************************
* Public Functions
****************************************************************************/
Expand Down Expand Up @@ -59,5 +62,23 @@

FAR void *pthread_getspecific(pthread_key_t key)
{
return (FAR void *)tls_get_value((int)key);
FAR struct tls_info_s *info;
FAR void *ret = NULL;

DEBUGASSERT(key >= 0 && key < CONFIG_TLS_NELEM);
if (key >= 0 && key < CONFIG_TLS_NELEM)
{
/* Get the TLS info structure from the current threads stack */

info = tls_get_info();
DEBUGASSERT(info != NULL);

/* Get the element value from the TLS info. */

ret = (FAR void *)info->tl_elem[key];
}

return ret;
}

#endif /* CONFIG_TLS_NELEM */
41 changes: 33 additions & 8 deletions libs/libc/pthread/pthread_keycreate.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,9 @@

#include <pthread.h>
#include <assert.h>
#include <errno.h>

#include <nuttx/semaphore.h>
#include <nuttx/tls.h>

#if CONFIG_TLS_NELEM > 0
Expand Down Expand Up @@ -70,23 +72,46 @@
int pthread_key_create(FAR pthread_key_t *key,
CODE void (*destructor)(FAR void *))
{
int tlsindex;
FAR struct task_info_s *info = task_get_info();
int candidate;
int ret;

DEBUGASSERT(key != NULL);
DEBUGASSERT(info != NULL);

/* Allocate a TLS index */
/* Search for an unused index. This is done in a critical section here to
* avoid concurrent modification of the group TLS index set.
*/

tlsindex = tls_alloc(destructor);
ret = _SEM_WAIT(&info->ta_sem);
Comment thread
pkarashchenko marked this conversation as resolved.

/* Check if found a TLS index. */
if (ret < 0)
{
ret = _SEM_ERRNO(ret);
return ret;
}
Comment thread
xiaoxiang781216 marked this conversation as resolved.

ret = EAGAIN;

if (tlsindex >= 0)
for (candidate = 0; candidate < CONFIG_TLS_NELEM; candidate++)
{
*key = tlsindex;
return OK;
/* Is this candidate index available? */

tls_ndxset_t mask = (tls_ndxset_t)1 << candidate;
if ((info->ta_tlsset & mask) == 0)
{
/* Yes.. allocate the index and break out of the loop */

info->ta_tlsset |= mask;
info->ta_tlsdtor[candidate] = destructor;
*key = candidate;
ret = OK;
break;
Comment thread
xiaoxiang781216 marked this conversation as resolved.
}
}

return -tlsindex;
_SEM_POST(&info->ta_sem);
return ret;
}

#endif /* CONFIG_TLS_NELEM */
36 changes: 33 additions & 3 deletions libs/libc/pthread/pthread_keydelete.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,14 @@
#include <nuttx/config.h>

#include <pthread.h>
#include <assert.h>
#include <errno.h>

#include <nuttx/semaphore.h>
#include <nuttx/tls.h>

#if CONFIG_TLS_NELEM > 0

/****************************************************************************
* Public Functions
****************************************************************************/
Expand All @@ -52,8 +57,33 @@

int pthread_key_delete(pthread_key_t key)
{
/* Free the TLS index */
FAR struct task_info_s *info = task_get_info();
tls_ndxset_t mask;
int ret = EINVAL;

DEBUGASSERT(info != NULL);
DEBUGASSERT(key >= 0 && key < CONFIG_TLS_NELEM);
if (key >= 0 && key < CONFIG_TLS_NELEM)
{
/* This is done while holding a semaphore here to avoid concurrent
* modification of the group TLS index set.
*/

int ret = tls_free((int)key);
return ret < 0 ? -ret : 0;
mask = (tls_ndxset_t)1 << key;
ret = _SEM_WAIT(&info->ta_sem);
Comment thread
xiaoxiang781216 marked this conversation as resolved.
if (ret == OK)
{
DEBUGASSERT((info->ta_tlsset & mask) != 0);
info->ta_tlsset &= ~mask;
_SEM_POST(&info->ta_sem);
}
else
{
ret = _SEM_ERRNO(ret);
}
}

return ret;
}

#endif /* CONFIG_TLS_NELEM */
Loading