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:
parent
615c4bc6e9
commit
29e50ffa73
@ -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
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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");
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user