sched: Refine tls_info_s and task_info_s

Signed-off-by: Huang Qi <huangqi3@xiaomi.com>
This commit is contained in:
Huang Qi 2021-06-29 18:35:42 +08:00 committed by Xiang Xiao
parent 30fd340e74
commit 65fa11634b
10 changed files with 82 additions and 47 deletions

View File

@ -430,6 +430,8 @@ struct exitinfo_s
#endif #endif
}; };
struct task_info_s;
/* struct task_group_s ******************************************************/ /* struct task_group_s ******************************************************/
/* All threads created by pthread_create belong in the same task group (along /* All threads created by pthread_create belong in the same task group (along
@ -533,6 +535,8 @@ struct task_group_s
/* Thread local storage ***************************************************/ /* Thread local storage ***************************************************/
FAR struct task_info_s *tg_info;
#if CONFIG_TLS_NELEM > 0 #if CONFIG_TLS_NELEM > 0
tls_ndxset_t tg_tlsset; /* Set of TLS indexes allocated */ tls_ndxset_t tg_tlsset; /* Set of TLS indexes allocated */

View File

@ -61,6 +61,13 @@
* Public Types * Public Types
****************************************************************************/ ****************************************************************************/
struct task_info_s
{
#ifndef CONFIG_BUILD_KERNEL
struct getopt_s ta_getopt; /* Globals used by getopt() */
#endif
};
/* When TLS is enabled, up_createstack() will align allocated stacks to the /* When TLS is enabled, up_createstack() will align allocated stacks to the
* TLS_STACK_ALIGN value. An instance of the following structure will be * TLS_STACK_ALIGN value. An instance of the following structure will be
* implicitly positioned at the "lower" end of the stack. Assuming a * implicitly positioned at the "lower" end of the stack. Assuming a
@ -78,10 +85,10 @@
* *
* Push Down Push Up * Push Down Push Up
* +-------------+ +-------------+ <- Stack memory allocation * +-------------+ +-------------+ <- Stack memory allocation
* | TLS Data | | TLS Data |
* +-------------+ +-------------+
* | Task Data* | | Task Data* | * | Task Data* | | Task Data* |
* +-------------+ +-------------+ * +-------------+ +-------------+
* | TLS Data | | TLS Data |
* +-------------+ +-------------+
* | Arguments | | Arguments | * | Arguments | | Arguments |
* +-------------+ +-------------+ | * +-------------+ +-------------+ |
* | | | | v * | | | | v
@ -92,11 +99,12 @@
* | | ^ | | * | | ^ | |
* +-------------+ | +-------------+ * +-------------+ | +-------------+
* *
* Task data is allocated in the main's thread's stack only * Task data is a pointer that pointed to a user space memory region.
*/ */
struct tls_info_s struct tls_info_s
{ {
FAR struct task_info_s * tl_task;
#if CONFIG_TLS_NELEM > 0 #if CONFIG_TLS_NELEM > 0
uintptr_t tl_elem[CONFIG_TLS_NELEM]; /* TLS elements */ uintptr_t tl_elem[CONFIG_TLS_NELEM]; /* TLS elements */
#endif #endif
@ -113,14 +121,6 @@ struct tls_info_s
int tl_errno; /* Per-thread error number */ int tl_errno; /* Per-thread error number */
}; };
struct task_info_s
{
struct tls_info_s ta_tls; /* Must be first field */
#ifndef CONFIG_BUILD_KERNEL
struct getopt_s ta_getopt; /* Globals used by getopt() */
#endif
};
/**************************************************************************** /****************************************************************************
* Public Function Prototypes * Public Function Prototypes
****************************************************************************/ ****************************************************************************/

View File

@ -26,6 +26,7 @@
#include <nuttx/sched.h> #include <nuttx/sched.h>
#include <nuttx/tls.h> #include <nuttx/tls.h>
#include <arch/tls.h>
/**************************************************************************** /****************************************************************************
* Public Functions * Public Functions
@ -48,15 +49,7 @@
FAR struct task_info_s *task_get_info(void) FAR struct task_info_s *task_get_info(void)
{ {
FAR struct task_info_s *info = NULL; FAR struct tls_info_s *info = up_tls_info();
struct stackinfo_s stackinfo;
int ret;
ret = nxsched_get_stackinfo(-1, &stackinfo); return info->tl_task;
if (ret >= 0)
{
info = (FAR struct task_info_s *)stackinfo.stack_alloc_ptr;
}
return info;
} }

View File

@ -73,6 +73,7 @@ void weak_function task_initialize(void);
/* Task group data structure management */ /* Task group data structure management */
int group_allocate(FAR struct task_tcb_s *tcb, uint8_t ttype); int group_allocate(FAR struct task_tcb_s *tcb, uint8_t ttype);
void group_deallocate(FAR struct task_group_s *group);
int group_initialize(FAR struct task_tcb_s *tcb); int group_initialize(FAR struct task_tcb_s *tcb);
#ifndef CONFIG_DISABLE_PTHREAD #ifndef CONFIG_DISABLE_PTHREAD
int group_bind(FAR struct pthread_tcb_s *tcb); int group_bind(FAR struct pthread_tcb_s *tcb);

View File

@ -33,6 +33,7 @@
#include <nuttx/kmalloc.h> #include <nuttx/kmalloc.h>
#include <nuttx/semaphore.h> #include <nuttx/semaphore.h>
#include <nuttx/sched.h> #include <nuttx/sched.h>
#include <nuttx/tls.h>
#include "environ/environ.h" #include "environ/environ.h"
#include "sched/sched.h" #include "sched/sched.h"
@ -126,7 +127,7 @@ static inline void group_inherit_identity(FAR struct task_group_s *group)
int group_allocate(FAR struct task_tcb_s *tcb, uint8_t ttype) int group_allocate(FAR struct task_tcb_s *tcb, uint8_t ttype)
{ {
FAR struct task_group_s *group; FAR struct task_group_s *group;
int ret; int ret = -ENOMEM;
DEBUGASSERT(tcb && !tcb->cmn.group); DEBUGASSERT(tcb && !tcb->cmn.group);
@ -138,7 +139,7 @@ int group_allocate(FAR struct task_tcb_s *tcb, uint8_t ttype)
return -ENOMEM; return -ENOMEM;
} }
#if defined(CONFIG_FILE_STREAM) && defined(CONFIG_MM_KERNEL_HEAP) #if defined(CONFIG_MM_KERNEL_HEAP)
/* If this group is being created for a privileged thread, then all /* If this group is being created for a privileged thread, then all
* elements of the group must be created for privileged access. * elements of the group must be created for privileged access.
*/ */
@ -148,6 +149,8 @@ int group_allocate(FAR struct task_tcb_s *tcb, uint8_t ttype)
group->tg_flags |= GROUP_FLAG_PRIVILEGED; group->tg_flags |= GROUP_FLAG_PRIVILEGED;
} }
# if defined(CONFIG_FILE_STREAM)
/* In a flat, single-heap build. The stream list is allocated with the /* In a flat, single-heap build. The stream list is allocated with the
* group structure. But in a kernel build with a kernel allocator, it * group structure. But in a kernel build with a kernel allocator, it
* must be separately allocated using a user-space allocator. * must be separately allocated using a user-space allocator.
@ -161,11 +164,21 @@ int group_allocate(FAR struct task_tcb_s *tcb, uint8_t ttype)
if (!group->tg_streamlist) if (!group->tg_streamlist)
{ {
kmm_free(group); goto errout_with_group;
return -ENOMEM;
} }
#endif # endif /* defined(CONFIG_FILE_STREAM) */
#endif /* defined(CONFIG_MM_KERNEL_HEAP) */
/* Alloc task info for group */
group->tg_info = (FAR struct task_info_s *)
group_zalloc(group, sizeof(struct task_info_s));
if (!group->tg_info)
{
goto errout_with_stream;
}
/* Attach the group to the TCB */ /* Attach the group to the TCB */
@ -180,12 +193,8 @@ int group_allocate(FAR struct task_tcb_s *tcb, uint8_t ttype)
ret = env_dup(group); ret = env_dup(group);
if (ret < 0) if (ret < 0)
{ {
#if defined(CONFIG_FILE_STREAM) && defined(CONFIG_MM_KERNEL_HEAP)
group_free(group, group->tg_streamlist);
#endif
kmm_free(group);
tcb->cmn.group = NULL; tcb->cmn.group = NULL;
return ret; goto errout_with_group;
} }
#ifndef CONFIG_DISABLE_PTHREAD #ifndef CONFIG_DISABLE_PTHREAD
@ -206,6 +215,38 @@ int group_allocate(FAR struct task_tcb_s *tcb, uint8_t ttype)
#endif #endif
return OK; return OK;
errout_with_stream:
#if defined(CONFIG_FILE_STREAM) && defined(CONFIG_MM_KERNEL_HEAP)
group_free(group, group->tg_streamlist);
#endif
errout_with_group:
group_deallocate(group);
return ret;
}
/****************************************************************************
* Name: group_deallocate
*
* Description:
* Free an existing task group structure.
*
* Input Parameters:
* group = The group structure
*
****************************************************************************/
void group_deallocate(FAR struct task_group_s *group)
{
if (group)
{
if (group->tg_info)
{
group_free(group, group->tg_info);
}
kmm_free(group);
}
} }
/**************************************************************************** /****************************************************************************
@ -245,7 +286,7 @@ int group_initialize(FAR struct task_tcb_s *tcb)
group->tg_members = kmm_malloc(GROUP_INITIAL_MEMBERS * sizeof(pid_t)); group->tg_members = kmm_malloc(GROUP_INITIAL_MEMBERS * sizeof(pid_t));
if (!group->tg_members) if (!group->tg_members)
{ {
kmm_free(group); group_deallocate(group);
tcb->cmn.group = NULL; tcb->cmn.group = NULL;
return -ENOMEM; return -ENOMEM;
} }

View File

@ -250,7 +250,7 @@ static inline void group_release(FAR struct task_group_s *group)
{ {
/* Release the group container itself */ /* Release the group container itself */
kmm_free(group); group_deallocate(group);
} }
} }

View File

@ -76,7 +76,7 @@ void group_del_waiter(FAR struct task_group_s *group)
* freed). * freed).
*/ */
kmm_free(group); group_deallocate(group);
} }
} }

View File

@ -336,6 +336,10 @@ int nx_pthread_create(pthread_trampoline_t trampoline, FAR pthread_t *thread,
DEBUGASSERT(info == ptcb->cmn.stack_alloc_ptr); DEBUGASSERT(info == ptcb->cmn.stack_alloc_ptr);
/* Attach per-task info in group to TLS */
info->tl_task = ptcb->cmn.group->tg_info;
/* Should we use the priority and scheduler specified in the pthread /* Should we use the priority and scheduler specified in the pthread
* attributes? Or should we use the current thread's priority and * attributes? Or should we use the current thread's priority and
* scheduler? * scheduler?

View File

@ -69,16 +69,6 @@ int nxsched_get_stackinfo(pid_t pid, FAR struct stackinfo_s *stackinfo)
qtcb = rtcb; qtcb = rtcb;
} }
else if (pid == -1)
{
/* We can always query our main thread */
qtcb = nxsched_get_tcb(rtcb->group->tg_pid);
if (qtcb == NULL)
{
return -ENOENT;
}
}
else else
{ {
/* Get the task to be queried */ /* Get the task to be queried */

View File

@ -86,7 +86,7 @@ int nxtask_init(FAR struct task_tcb_s *tcb, const char *name, int priority,
main_t entry, FAR char * const argv[]) main_t entry, FAR char * const argv[])
{ {
uint8_t ttype = tcb->cmn.flags & TCB_FLAG_TTYPE_MASK; uint8_t ttype = tcb->cmn.flags & TCB_FLAG_TTYPE_MASK;
FAR struct task_info_s *info; FAR struct tls_info_s *info;
int ret; int ret;
#ifndef CONFIG_DISABLE_PTHREAD #ifndef CONFIG_DISABLE_PTHREAD
@ -122,7 +122,7 @@ int nxtask_init(FAR struct task_tcb_s *tcb, const char *name, int priority,
/* Allocate the stack for the TCB */ /* Allocate the stack for the TCB */
ret = up_create_stack(&tcb->cmn, ret = up_create_stack(&tcb->cmn,
sizeof(struct task_info_s) + stack_size, sizeof(struct tls_info_s) + stack_size,
ttype); ttype);
} }
@ -133,7 +133,7 @@ int nxtask_init(FAR struct task_tcb_s *tcb, const char *name, int priority,
/* Initialize thread local storage */ /* Initialize thread local storage */
info = up_stack_frame(&tcb->cmn, sizeof(struct task_info_s)); info = up_stack_frame(&tcb->cmn, sizeof(struct tls_info_s));
if (info == NULL) if (info == NULL)
{ {
ret = -ENOMEM; ret = -ENOMEM;
@ -142,6 +142,8 @@ int nxtask_init(FAR struct task_tcb_s *tcb, const char *name, int priority,
DEBUGASSERT(info == tcb->cmn.stack_alloc_ptr); DEBUGASSERT(info == tcb->cmn.stack_alloc_ptr);
info->tl_task = tcb->cmn.group->tg_info;
/* Initialize the task control block */ /* Initialize the task control block */
ret = nxtask_setup_scheduler(tcb, priority, nxtask_start, ret = nxtask_setup_scheduler(tcb, priority, nxtask_start,