aboutsummaryrefslogtreecommitdiff
path: root/nuttx/sched/task_setup.c
diff options
context:
space:
mode:
Diffstat (limited to 'nuttx/sched/task_setup.c')
-rw-r--r--nuttx/sched/task_setup.c68
1 files changed, 61 insertions, 7 deletions
diff --git a/nuttx/sched/task_setup.c b/nuttx/sched/task_setup.c
index 92897f0ae..80aefded3 100644
--- a/nuttx/sched/task_setup.c
+++ b/nuttx/sched/task_setup.c
@@ -153,7 +153,8 @@ static int task_assignpid(FAR _TCB *tcb)
* Save the task ID of the parent task in the child task's TCB.
*
* Parameters:
- * tcb - The TCB of the new, child task.
+ * tcb - The TCB of the new, child task.
+ * ttype - Type of the new thread: task, pthread, or kernel thread
*
* Returned Value:
* None
@@ -165,13 +166,57 @@ static int task_assignpid(FAR _TCB *tcb)
****************************************************************************/
#ifdef CONFIG_SCHED_HAVE_PARENT
-static inline void task_saveparent(FAR _TCB *tcb)
+static inline void task_saveparent(FAR _TCB *tcb, uint8_t ttype)
{
FAR _TCB *rtcb = (FAR _TCB*)g_readytorun.head;
- DEBUGASSERT(rtcb->nchildren < UINT16_MAX);
+ /* Save the parent task's ID in the child task's TCB. I am not sure if
+ * this makes sense for the case of pthreads or not, but I don't think it
+ * is harmful in any event.
+ */
+
tcb->parent = rtcb->pid;
- rtcb->nchildren++;
+
+ /* Exit status only needs to be retained for the case of tasks, however */
+
+ if (ttype == TCB_FLAG_TTYPE_TASK)
+ {
+#ifdef CONFIG_SCHED_CHILD_STATUS
+ FAR struct child_status_s *child;
+
+ /* Make sure that there is not already a structure for this PID in the
+ * parent TCB. There should not be.
+ */
+
+ child = task_findchild(rtcb, tcb->pid);
+ DEBUGASSERT(!child);
+ if (!child)
+ {
+ /* Allocate a new status structure */
+
+ child = task_allocchild();
+ }
+
+ /* Did we successfully find/allocate the child status structure? */
+
+ DEBUGASSERT(child);
+ if (child)
+ {
+ /* Yes.. Initialize the structure */
+
+ child->ch_flags = ttype;
+ child->ch_pid = tcb->pid;
+ child->ch_status = 0;
+
+ /* Add the entry into the TCB list of children */
+
+ task_addchild(rtcb, child);
+ }
+#else
+ DEBUGASSERT(rtcb->nchildren < UINT16_MAX);
+ rtcb->nchildren++;
+#endif
+ }
}
#else
# define task_saveparent(tcb)
@@ -235,7 +280,7 @@ static inline void task_dupdspace(FAR _TCB *tcb)
* priority - Priority of the new task
* entry - Entry point of a new task
* main - Application start point of the new task
- * type - Type of the new thread: task, pthread, or kernel thread
+ * ttype - Type of the new thread: task, pthread, or kernel thread
*
* Return Value:
* OK on success; ERROR on failure.
@@ -245,7 +290,8 @@ static inline void task_dupdspace(FAR _TCB *tcb)
*
****************************************************************************/
-int task_schedsetup(FAR _TCB *tcb, int priority, start_t start, main_t main)
+int task_schedsetup(FAR _TCB *tcb, int priority, start_t start, main_t main,
+ uint8_t ttype)
{
int ret;
@@ -264,9 +310,17 @@ int task_schedsetup(FAR _TCB *tcb, int priority, start_t start, main_t main)
tcb->start = start;
tcb->entry.main = main;
+ /* Save the thrad type. This setting will be needed in
+ * up_initial_state() is called.
+ */
+
+ ttype &= TCB_FLAG_TTYPE_MASK;
+ tcb->flags &= ~TCB_FLAG_TTYPE_MASK;
+ tcb->flags |= ttype;
+
/* Save the task ID of the parent task in the TCB */
- task_saveparent(tcb);
+ task_saveparent(tcb, ttype);
/* exec(), pthread_create(), task_create(), and vfork() all
* inherit the signal mask of the parent thread.