sched/group: move task group into task_tcb_s to improve performance

move task group into task_tcb_s to avoid access allocator to improve performance

for Task Termination, the time consumption will be reduced ~2us (Tricore TC397 300MHZ):
15.97(us) -> 13.55(us)

Signed-off-by: chao an <anchao@lixiang.com>
This commit is contained in:
chao an 2024-03-04 09:19:27 +08:00 committed by Alan Carvalho de Assis
parent 615c4bc6e9
commit 29e50ffa73
11 changed files with 72 additions and 41 deletions

View File

@ -125,7 +125,7 @@ void mm_map_unlock(void);
* Name: mm_map_initialize
*
* Description:
* Initialization function, called only by group_initialize
* Initialization function, called only by group_postinitialize
*
* Input Parameters:
* mm - Pointer to the mm_map structure to be initialized

View File

@ -680,6 +680,10 @@ struct task_tcb_s
struct tcb_s cmn; /* Common TCB fields */
/* Task Group *************************************************************/
struct task_group_s group; /* Pointer to shared task group data */
/* Task Management Fields *************************************************/
#ifdef CONFIG_SCHED_STARTHOOK

View File

@ -56,8 +56,8 @@ void task_initialize(void);
/* Task group data structure management */
int group_allocate(FAR struct task_tcb_s *tcb, uint8_t ttype);
void group_initialize(FAR struct task_tcb_s *tcb);
int group_initialize(FAR struct task_tcb_s *tcb, uint8_t ttype);
void group_postinitialize(FAR struct task_tcb_s *tcb);
#ifndef CONFIG_DISABLE_PTHREAD
int group_bind(FAR struct pthread_tcb_s *tcb);
int group_join(FAR struct pthread_tcb_s *tcb);

View File

@ -88,7 +88,7 @@ static inline void group_inherit_identity(FAR struct task_group_s *group)
****************************************************************************/
/****************************************************************************
* Name: group_allocate
* Name: group_initialize
*
* Description:
* Create and a new task group structure for the specified TCB. This
@ -96,8 +96,8 @@ static inline void group_inherit_identity(FAR struct task_group_s *group)
* allocated and zeroed, but otherwise uninitialized. The full creation
* of the group of a two step process: (1) First, this function allocates
* group structure early in the task creation sequence in order to provide
* a group container, then (2) group_initialize() is called to set up the
* group membership.
* a group container, then (2) group_postinitialize() is called to set up
* the group membership.
*
* Input Parameters:
* tcb - The tcb in need of the task group.
@ -112,7 +112,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_initialize(FAR struct task_tcb_s *tcb, uint8_t ttype)
{
FAR struct task_group_s *group;
int ret;
@ -121,11 +121,7 @@ int group_allocate(FAR struct task_tcb_s *tcb, uint8_t ttype)
/* Allocate the group structure and assign it to the TCB */
group = kmm_zalloc(sizeof(struct task_group_s));
if (!group)
{
return -ENOMEM;
}
group = &tcb->group;
#if defined(CONFIG_MM_KERNEL_HEAP)
/* If this group is being created for a privileged thread, then all
@ -161,7 +157,7 @@ int group_allocate(FAR struct task_tcb_s *tcb, uint8_t ttype)
ret = task_init_info(group);
if (ret < 0)
{
goto errout_with_group;
return ret;
}
#ifndef CONFIG_DISABLE_PTHREAD
@ -177,20 +173,17 @@ int group_allocate(FAR struct task_tcb_s *tcb, uint8_t ttype)
#endif
return OK;
errout_with_group:
kmm_free(group);
return ret;
}
/****************************************************************************
* Name: group_initialize
* Name: group_postinitialize
*
* Description:
* Add the task as the initial member of the group. The full creation of
* the group of a two step process: (1) First, this group structure is
* allocated by group_allocate() early in the task creation sequence, then
* (2) this function is called to set up the initial group membership.
* allocated by group_initialize() early in the task creation sequence,
* then (2) this function is called to set up the initial group
* membership.
*
* Input Parameters:
* tcb - The tcb in need of the task group.
@ -204,7 +197,7 @@ errout_with_group:
*
****************************************************************************/
void group_initialize(FAR struct task_tcb_s *tcb)
void group_postinitialize(FAR struct task_tcb_s *tcb)
{
FAR struct task_group_s *group;

View File

@ -62,7 +62,7 @@ int group_foreachchild(FAR struct task_group_s *group,
{
FAR sq_entry_t *curr;
FAR sq_entry_t *next;
int ret;
int ret = OK;
DEBUGASSERT(group);

View File

@ -29,6 +29,7 @@
#include <errno.h>
#include <debug.h>
#include <nuttx/nuttx.h>
#include <nuttx/irq.h>
#include <nuttx/fs/fs.h>
#include <nuttx/net/net.h>
@ -67,7 +68,8 @@
*
****************************************************************************/
static inline void group_release(FAR struct task_group_s *group)
static inline void
group_release(FAR struct task_group_s *group, uint8_t ttype)
{
task_uninit_info(group);
@ -124,7 +126,12 @@ static inline void group_release(FAR struct task_group_s *group)
/* Then drop the group freeing the allocated memory */
group_drop(group);
#ifndef CONFIG_DISABLE_PTHREAD
if (ttype == TCB_FLAG_TTYPE_PTHREAD)
{
group_drop(group);
}
#endif
}
/****************************************************************************
@ -166,6 +173,12 @@ void group_leave(FAR struct tcb_s *tcb)
group = tcb->group;
if (group)
{
/* In any event, we can detach the group from the TCB so that we won't
* do this again.
*/
tcb->group = NULL;
/* Remove the member from group. */
#ifdef HAVE_GROUP_MEMBERS
@ -180,14 +193,8 @@ void group_leave(FAR struct tcb_s *tcb)
{
/* Yes.. Release all of the resource held by the task group */
group_release(group);
group_release(group, tcb->flags & TCB_FLAG_TTYPE_MASK);
}
/* In any event, we can detach the group from the TCB so that we won't
* do this again.
*/
tcb->group = NULL;
}
}
@ -214,6 +221,8 @@ void group_leave(FAR struct tcb_s *tcb)
void group_drop(FAR struct task_group_s *group)
{
FAR struct task_tcb_s *tcb;
#if defined(CONFIG_SCHED_WAITPID) && !defined(CONFIG_SCHED_HAVE_PARENT)
/* If there are threads waiting for this group to be freed, then we cannot
* yet free the memory resources. Instead just mark the group deleted
@ -228,13 +237,17 @@ void group_drop(FAR struct task_group_s *group)
}
else
#endif
/* Finally, if no one needs the group and it has been deleted, remove it */
if (group->tg_flags & GROUP_FLAG_DELETED)
{
tcb = container_of(group, struct task_tcb_s, group);
/* Release the group container itself */
kmm_free(group);
if (tcb->cmn.flags & TCB_FLAG_FREE_TCB)
{
kmm_free(tcb);
}
}
}

View File

@ -516,7 +516,7 @@ void nx_start(void)
/* Allocate the IDLE group */
DEBUGVERIFY(group_allocate(&g_idletcb[i], g_idletcb[i].cmn.flags));
DEBUGVERIFY(group_initialize(&g_idletcb[i], g_idletcb[i].cmn.flags));
g_idletcb[i].cmn.group->tg_info->ta_argv = &g_idleargv[i][0];
#ifdef CONFIG_SMP
@ -543,7 +543,7 @@ void nx_start(void)
* of child status in the IDLE group.
*/
group_initialize(&g_idletcb[i]);
group_postinitialize(&g_idletcb[i]);
g_idletcb[i].cmn.group->tg_flags = GROUP_FLAG_NOCLDWAIT |
GROUP_FLAG_PRIVILEGED;
}

View File

@ -208,8 +208,7 @@ int nx_pthread_create(pthread_trampoline_t trampoline, FAR pthread_t *thread,
/* Allocate a TCB for the new task. */
ptcb = (FAR struct pthread_tcb_s *)
kmm_zalloc(sizeof(struct pthread_tcb_s));
ptcb = kmm_zalloc(sizeof(struct pthread_tcb_s));
if (!ptcb)
{
serr("ERROR: Failed to allocate TCB\n");

View File

@ -97,6 +97,9 @@ static void nxsched_releasepid(pid_t pid)
int nxsched_release_tcb(FAR struct tcb_s *tcb, uint8_t ttype)
{
#ifndef CONFIG_DISABLE_PTHREAD
FAR struct task_tcb_s *ttcb;
#endif
int ret = OK;
if (tcb)
@ -161,6 +164,23 @@ int nxsched_release_tcb(FAR struct tcb_s *tcb, uint8_t ttype)
group_leave(tcb);
/* Kernel thread and group still reference by pthread */
#ifndef CONFIG_DISABLE_PTHREAD
if (ttype != TCB_FLAG_TTYPE_PTHREAD)
{
ttcb = (FAR struct task_tcb_s *)tcb;
if (!sq_empty(&ttcb->group.tg_members)
#if defined(CONFIG_SCHED_WAITPID) && !defined(CONFIG_SCHED_HAVE_PARENT)
|| ttcb->group.tg_nwaiters > 0
#endif
)
{
return ret;
}
}
#endif
/* And, finally, release the TCB itself */
if (tcb->flags & TCB_FLAG_FREE_TCB)

View File

@ -142,9 +142,11 @@ FAR struct task_tcb_s *nxtask_setup_fork(start_t retaddr)
goto errout;
}
child->cmn.flags |= TCB_FLAG_FREE_TCB;
/* Allocate a new task group with the same privileges as the parent */
ret = group_allocate(child, ttype);
ret = group_initialize(child, ttype);
if (ret < 0)
{
goto errout_with_tcb;
@ -214,7 +216,7 @@ FAR struct task_tcb_s *nxtask_setup_fork(start_t retaddr)
/* Now we have enough in place that we can join the group */
group_initialize(child);
group_postinitialize(child);
sinfo("parent=%p, returning child=%p\n", parent, child);
return child;

View File

@ -111,7 +111,7 @@ int nxtask_init(FAR struct task_tcb_s *tcb, const char *name, int priority,
/* Create a new task group */
ret = group_allocate(tcb, tcb->cmn.flags);
ret = group_initialize(tcb, tcb->cmn.flags);
if (ret < 0)
{
sched_trace_end();
@ -179,7 +179,7 @@ int nxtask_init(FAR struct task_tcb_s *tcb, const char *name, int priority,
/* Now we have enough in place that we can join the group */
group_initialize(tcb);
group_postinitialize(tcb);
sched_trace_end();
return ret;