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.c58
1 files changed, 44 insertions, 14 deletions
diff --git a/nuttx/sched/task_setup.c b/nuttx/sched/task_setup.c
index 43ed24b32..b770d46e6 100644
--- a/nuttx/sched/task_setup.c
+++ b/nuttx/sched/task_setup.c
@@ -1,7 +1,7 @@
/****************************************************************************
* sched/task_setup.c
*
- * Copyright (C) 2007-2012 Gregory Nutt. All rights reserved.
+ * Copyright (C) 2007-2013 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Redistribution and use in source and binary forms, with or without
@@ -49,6 +49,7 @@
#include <nuttx/arch.h>
#include "os_internal.h"
+#include "group_internal.h"
/****************************************************************************
* Definitions
@@ -150,7 +151,8 @@ static int task_assignpid(FAR _TCB *tcb)
* Name: task_saveparent
*
* Description:
- * Save the task ID of the parent task in the child task's TCB.
+ * Save the task ID of the parent task in the child task's TCB and allocate
+ * a child status structure to catch the child task's exit status.
*
* Parameters:
* tcb - The TCB of the new, child task.
@@ -170,31 +172,57 @@ static inline void task_saveparent(FAR _TCB *tcb, uint8_t ttype)
{
FAR _TCB *rtcb = (FAR _TCB*)g_readytorun.head;
+#if defined(HAVE_GROUP_MEMBERS) || defined(CONFIG_SCHED_CHILD_STATUS)
+ DEBUGASSERT(tcb && tcb->group && rtcb->group);
+#else
+#endif
+
+#ifdef HAVE_GROUP_MEMBERS
+ /* Save the ID of the parent tasks' task group in the child's task group.
+ * Do nothing for pthreads. The parent and the child are both members of
+ * the same task group.
+ */
+
+ if ((tcb->flags & TCB_FLAG_TTYPE_MASK) != TCB_FLAG_TTYPE_PTHREAD)
+ {
+ /* This is a new task in a new task group, we have to copy the ID from
+ * the parent's task group structure to child's task group.
+ */
+
+ tcb->group->tg_pgid = rtcb->group->tg_gid;
+ }
+
+#else
+ DEBUGASSERT(tcb);
+
/* 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;
+ tcb->ppid = rtcb->pid;
+#endif
- /* Exit status only needs to be retained for the case of tasks, however */
+#ifdef CONFIG_SCHED_CHILD_STATUS
+ /* Tasks can also suppress retention of their child status by applying
+ * the SA_NOCLDWAIT flag with sigaction().
+ */
- if (ttype == TCB_FLAG_TTYPE_TASK)
+ if ((rtcb->group->tg_flags && GROUP_FLAG_NOCLDWAIT) == 0)
{
-#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);
+ child = group_findchild(rtcb->group, tcb->pid);
DEBUGASSERT(!child);
if (!child)
{
/* Allocate a new status structure */
- child = task_allocchild();
+ child = group_allocchild();
}
/* Did we successfully find/allocate the child status structure? */
@@ -210,16 +238,16 @@ static inline void task_saveparent(FAR _TCB *tcb, uint8_t ttype)
/* Add the entry into the TCB list of children */
- task_addchild(rtcb, child);
+ group_addchild(rtcb->group, child);
}
+ }
#else
- DEBUGASSERT(rtcb->nchildren < UINT16_MAX);
- rtcb->nchildren++;
+ DEBUGASSERT(rtcb->nchildren < UINT16_MAX);
+ rtcb->nchildren++;
#endif
- }
}
#else
-# define task_saveparent(tcb, type)
+# define task_saveparent(tcb,ttype)
#endif
/****************************************************************************
@@ -318,7 +346,9 @@ int task_schedsetup(FAR _TCB *tcb, int priority, start_t start, main_t main,
tcb->flags &= ~TCB_FLAG_TTYPE_MASK;
tcb->flags |= ttype;
- /* Save the task ID of the parent task in the TCB */
+ /* Save the task ID of the parent task in the TCB and allocate
+ * a child status structure.
+ */
task_saveparent(tcb, ttype);