sched/task: unify task initialization
1. nxthread_create() Reduce code duplication 2. nxtask_init(): support stack allocation from internal Change-Id: Ib495a6efb032d9caa9b03113a0763b71486d14ea Signed-off-by: chao.an <anchao@xiaomi.com>
This commit is contained in:
parent
ac1641dc1b
commit
62b777b1cd
@ -72,92 +72,41 @@ static int nxthread_create(FAR const char *name, uint8_t ttype,
|
|||||||
int priority, int stack_size, main_t entry,
|
int priority, int stack_size, main_t entry,
|
||||||
FAR char * const argv[])
|
FAR char * const argv[])
|
||||||
{
|
{
|
||||||
FAR struct task_tcb_s *tcb;
|
FAR struct tcb_s *tcb;
|
||||||
pid_t pid;
|
pid_t pid;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
/* Allocate a TCB for the new task. */
|
/* Allocate a TCB for the new task. */
|
||||||
|
|
||||||
tcb = (FAR struct task_tcb_s *)kmm_zalloc(sizeof(struct task_tcb_s));
|
tcb = (FAR struct tcb_s *)kmm_zalloc(sizeof(struct task_tcb_s));
|
||||||
if (!tcb)
|
if (!tcb)
|
||||||
{
|
{
|
||||||
serr("ERROR: Failed to allocate TCB\n");
|
serr("ERROR: Failed to allocate TCB\n");
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Allocate a new task group with privileges appropriate for the parent
|
/* Setup the task type */
|
||||||
* thread type.
|
|
||||||
*/
|
|
||||||
|
|
||||||
ret = group_allocate(tcb, ttype);
|
tcb->flags = ttype;
|
||||||
if (ret < 0)
|
|
||||||
{
|
|
||||||
goto errout_with_tcb;
|
|
||||||
}
|
|
||||||
|
|
||||||
#if 0 /* No... there are side effects */
|
/* Initialize the task */
|
||||||
/* Associate file descriptors with the new task. Exclude kernel threads;
|
|
||||||
* kernel threads do not have file or socket descriptors. They must use
|
|
||||||
* SYSLOG for output and the low-level psock interfaces for network I/O.
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (ttype != TCB_FLAG_TTYPE_KERNEL)
|
ret = nxtask_init(tcb, name, priority, NULL, stack_size, entry, argv);
|
||||||
#endif
|
|
||||||
{
|
|
||||||
ret = group_setuptaskfiles(tcb);
|
|
||||||
if (ret < OK)
|
if (ret < OK)
|
||||||
{
|
{
|
||||||
goto errout_with_tcb;
|
kmm_free(tcb);
|
||||||
}
|
return ret;
|
||||||
}
|
|
||||||
|
|
||||||
/* Allocate the stack for the TCB */
|
|
||||||
|
|
||||||
ret = up_create_stack((FAR struct tcb_s *)tcb, stack_size, ttype);
|
|
||||||
if (ret < OK)
|
|
||||||
{
|
|
||||||
goto errout_with_tcb;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Initialize the task control block */
|
|
||||||
|
|
||||||
ret = nxtask_setup_scheduler(tcb, priority, nxtask_start, entry, ttype);
|
|
||||||
if (ret < OK)
|
|
||||||
{
|
|
||||||
goto errout_with_tcb;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Setup to pass parameters to the new task */
|
|
||||||
|
|
||||||
nxtask_setup_arguments(tcb, name, argv);
|
|
||||||
|
|
||||||
/* Now we have enough in place that we can join the group */
|
|
||||||
|
|
||||||
ret = group_initialize(tcb);
|
|
||||||
if (ret < 0)
|
|
||||||
{
|
|
||||||
goto errout_with_active;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Get the assigned pid before we start the task */
|
/* Get the assigned pid before we start the task */
|
||||||
|
|
||||||
pid = (int)tcb->cmn.pid;
|
pid = tcb->pid;
|
||||||
|
|
||||||
/* Activate the task */
|
/* Activate the task */
|
||||||
|
|
||||||
nxtask_activate((FAR struct tcb_s *)tcb);
|
nxtask_activate(tcb);
|
||||||
return pid;
|
|
||||||
|
|
||||||
errout_with_active:
|
return (int)pid;
|
||||||
/* The TCB was added to the inactive task list by
|
|
||||||
* nxtask_setup_scheduler().
|
|
||||||
*/
|
|
||||||
|
|
||||||
dq_rem((FAR dq_entry_t *)tcb, (FAR dq_queue_t *)&g_inactivetasks);
|
|
||||||
|
|
||||||
errout_with_tcb:
|
|
||||||
nxsched_release_tcb((FAR struct tcb_s *)tcb, ttype);
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
|
@ -87,13 +87,13 @@ int nxtask_init(FAR struct tcb_s *tcb, const char *name, int priority,
|
|||||||
main_t entry, FAR char * const argv[])
|
main_t entry, FAR char * const argv[])
|
||||||
{
|
{
|
||||||
FAR struct task_tcb_s *ttcb = (FAR struct task_tcb_s *)tcb;
|
FAR struct task_tcb_s *ttcb = (FAR struct task_tcb_s *)tcb;
|
||||||
|
uint8_t ttype = tcb->flags & TCB_FLAG_TTYPE_MASK;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
/* Only tasks and kernel threads can be initialized in this way */
|
/* Only tasks and kernel threads can be initialized in this way */
|
||||||
|
|
||||||
#ifndef CONFIG_DISABLE_PTHREAD
|
#ifndef CONFIG_DISABLE_PTHREAD
|
||||||
DEBUGASSERT(tcb &&
|
DEBUGASSERT(tcb && ttype != TCB_FLAG_TTYPE_PTHREAD);
|
||||||
(tcb->flags & TCB_FLAG_TTYPE_MASK) != TCB_FLAG_TTYPE_PTHREAD);
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Create a new task group */
|
/* Create a new task group */
|
||||||
@ -101,7 +101,7 @@ int nxtask_init(FAR struct tcb_s *tcb, const char *name, int priority,
|
|||||||
ret = group_allocate(ttcb, tcb->flags);
|
ret = group_allocate(ttcb, tcb->flags);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
{
|
{
|
||||||
goto errout;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Associate file descriptors with the new task */
|
/* Associate file descriptors with the new task */
|
||||||
@ -112,14 +112,28 @@ int nxtask_init(FAR struct tcb_s *tcb, const char *name, int priority,
|
|||||||
goto errout_with_group;
|
goto errout_with_group;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Configure the user provided stack region */
|
if (stack)
|
||||||
|
{
|
||||||
|
/* Use pre-allocated stack */
|
||||||
|
|
||||||
up_use_stack(tcb, stack, stack_size);
|
ret = up_use_stack(tcb, stack, stack_size);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Allocate the stack for the TCB */
|
||||||
|
|
||||||
|
ret = up_create_stack(tcb, stack_size, ttype);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ret < OK)
|
||||||
|
{
|
||||||
|
goto errout_with_group;
|
||||||
|
}
|
||||||
|
|
||||||
/* Initialize the task control block */
|
/* Initialize the task control block */
|
||||||
|
|
||||||
ret = nxtask_setup_scheduler(ttcb, priority, nxtask_start, entry,
|
ret = nxtask_setup_scheduler(ttcb, priority, nxtask_start,
|
||||||
TCB_FLAG_TTYPE_TASK);
|
entry, ttype);
|
||||||
if (ret < OK)
|
if (ret < OK)
|
||||||
{
|
{
|
||||||
goto errout_with_group;
|
goto errout_with_group;
|
||||||
@ -132,17 +146,41 @@ int nxtask_init(FAR struct tcb_s *tcb, const char *name, int priority,
|
|||||||
/* Now we have enough in place that we can join the group */
|
/* Now we have enough in place that we can join the group */
|
||||||
|
|
||||||
ret = group_initialize(ttcb);
|
ret = group_initialize(ttcb);
|
||||||
if (ret < 0)
|
if (ret == OK)
|
||||||
{
|
{
|
||||||
goto errout_with_group;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
return OK;
|
/* The TCB was added to the inactive task list by
|
||||||
|
* nxtask_setup_scheduler().
|
||||||
|
*/
|
||||||
|
|
||||||
|
dq_rem((FAR dq_entry_t *)tcb, (FAR dq_queue_t *)&g_inactivetasks);
|
||||||
|
|
||||||
errout_with_group:
|
errout_with_group:
|
||||||
|
|
||||||
|
if (!stack && tcb->stack_alloc_ptr)
|
||||||
|
{
|
||||||
|
#ifdef CONFIG_BUILD_KERNEL
|
||||||
|
/* If the exiting thread is not a kernel thread, then it has an
|
||||||
|
* address environment. Don't bother to release the stack memory
|
||||||
|
* in this case... There is no point since the memory lies in the
|
||||||
|
* user memory region that will be destroyed anyway (and the
|
||||||
|
* address environment has probably already been destroyed at
|
||||||
|
* this point.. so we would crash if we even tried it). But if
|
||||||
|
* this is a privileged group, when we still have to release the
|
||||||
|
* memory using the kernel allocator.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (ttype == TCB_FLAG_TTYPE_KERNEL)
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
up_release_stack(tcb, ttype);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
group_leave(tcb);
|
group_leave(tcb);
|
||||||
|
|
||||||
errout:
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user