This is an automated email from the ASF dual-hosted git repository. jerpelea pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/incubator-nuttx.git
commit 62b777b1cd581f7dc4f8781a1fedd1254fca3f96 Author: chao.an <anc...@xiaomi.com> AuthorDate: Mon Jun 29 10:44:33 2020 +0800 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 <anc...@xiaomi.com> --- sched/task/task_create.c | 73 ++++++++---------------------------------------- sched/task/task_init.c | 60 +++++++++++++++++++++++++++++++-------- 2 files changed, 60 insertions(+), 73 deletions(-) diff --git a/sched/task/task_create.c b/sched/task/task_create.c index c2259be..ea640f0 100644 --- a/sched/task/task_create.c +++ b/sched/task/task_create.c @@ -72,92 +72,41 @@ static int nxthread_create(FAR const char *name, uint8_t ttype, int priority, int stack_size, main_t entry, FAR char * const argv[]) { - FAR struct task_tcb_s *tcb; + FAR struct tcb_s *tcb; pid_t pid; int ret; /* 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) { serr("ERROR: Failed to allocate TCB\n"); return -ENOMEM; } - /* Allocate a new task group with privileges appropriate for the parent - * thread type. - */ + /* Setup the task type */ - ret = group_allocate(tcb, ttype); - if (ret < 0) - { - goto errout_with_tcb; - } - -#if 0 /* No... there are side effects */ - /* 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) -#endif - { - ret = group_setuptaskfiles(tcb); - if (ret < OK) - { - goto errout_with_tcb; - } - } + tcb->flags = ttype; - /* Allocate the stack for the TCB */ + /* Initialize the task */ - ret = up_create_stack((FAR struct tcb_s *)tcb, stack_size, ttype); + ret = nxtask_init(tcb, name, priority, NULL, stack_size, entry, argv); 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; + kmm_free(tcb); + return ret; } /* Get the assigned pid before we start the task */ - pid = (int)tcb->cmn.pid; + pid = tcb->pid; /* Activate the task */ - nxtask_activate((FAR struct tcb_s *)tcb); - return pid; - -errout_with_active: - /* The TCB was added to the inactive task list by - * nxtask_setup_scheduler(). - */ + nxtask_activate(tcb); - 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; + return (int)pid; } /**************************************************************************** diff --git a/sched/task/task_init.c b/sched/task/task_init.c index 1d097a0..1d0b2f7 100644 --- a/sched/task/task_init.c +++ b/sched/task/task_init.c @@ -87,13 +87,13 @@ int nxtask_init(FAR struct tcb_s *tcb, const char *name, int priority, main_t entry, FAR char * const argv[]) { FAR struct task_tcb_s *ttcb = (FAR struct task_tcb_s *)tcb; + uint8_t ttype = tcb->flags & TCB_FLAG_TTYPE_MASK; int ret; /* Only tasks and kernel threads can be initialized in this way */ #ifndef CONFIG_DISABLE_PTHREAD - DEBUGASSERT(tcb && - (tcb->flags & TCB_FLAG_TTYPE_MASK) != TCB_FLAG_TTYPE_PTHREAD); + DEBUGASSERT(tcb && ttype != TCB_FLAG_TTYPE_PTHREAD); #endif /* 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); if (ret < 0) { - goto errout; + return ret; } /* 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; } - /* Configure the user provided stack region */ + if (stack) + { + /* Use pre-allocated stack */ + + ret = up_use_stack(tcb, stack, stack_size); + } + else + { + /* Allocate the stack for the TCB */ - up_use_stack(tcb, stack, stack_size); + ret = up_create_stack(tcb, stack_size, ttype); + } + + if (ret < OK) + { + goto errout_with_group; + } /* Initialize the task control block */ - ret = nxtask_setup_scheduler(ttcb, priority, nxtask_start, entry, - TCB_FLAG_TTYPE_TASK); + ret = nxtask_setup_scheduler(ttcb, priority, nxtask_start, + entry, ttype); if (ret < OK) { 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 */ 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: + + 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); -errout: return ret; }