sched: Refine tls_info_s and task_info_s
Signed-off-by: Huang Qi <huangqi3@xiaomi.com>
This commit is contained in:
parent
30fd340e74
commit
65fa11634b
@ -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 */
|
||||||
|
|
||||||
|
@ -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
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
@ -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;
|
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -76,7 +76,7 @@ void group_del_waiter(FAR struct task_group_s *group)
|
|||||||
* freed).
|
* freed).
|
||||||
*/
|
*/
|
||||||
|
|
||||||
kmm_free(group);
|
group_deallocate(group);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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?
|
||||||
|
@ -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 */
|
||||||
|
@ -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,
|
||||||
|
Loading…
Reference in New Issue
Block a user