You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by je...@apache.org on 2020/06/30 06:26:46 UTC

[incubator-nuttx] 01/03: sched/task: unify task initialization

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 <an...@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 <an...@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;
 }