diff options
author | px4dev <px4@purgatory.org> | 2013-01-23 23:56:24 -0800 |
---|---|---|
committer | px4dev <px4@purgatory.org> | 2013-01-23 23:56:24 -0800 |
commit | 35febbe8441d0932881940eb2633080ab23f1e28 (patch) | |
tree | 07e1c0217a19f3476bf82c7cda5910a21ff0da90 /nuttx/sched/task_reparent.c | |
parent | b60a744b773bb0752cb108b8d0bc2aad94c43b80 (diff) | |
parent | 63f8c0a954ef61ee416e78ea55899bc322aa313b (diff) | |
download | px4-firmware-35febbe8441d0932881940eb2633080ab23f1e28.tar.gz px4-firmware-35febbe8441d0932881940eb2633080ab23f1e28.tar.bz2 px4-firmware-35febbe8441d0932881940eb2633080ab23f1e28.zip |
Merge Nuttx r5554
Diffstat (limited to 'nuttx/sched/task_reparent.c')
-rw-r--r-- | nuttx/sched/task_reparent.c | 163 |
1 files changed, 163 insertions, 0 deletions
diff --git a/nuttx/sched/task_reparent.c b/nuttx/sched/task_reparent.c new file mode 100644 index 000000000..28d371bf1 --- /dev/null +++ b/nuttx/sched/task_reparent.c @@ -0,0 +1,163 @@ +/***************************************************************************** + * sched/task_reparent.c + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt <gnutt@nuttx.org> + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ + +/***************************************************************************** + * Included Files + *****************************************************************************/ + +#include <nuttx/config.h> + +#include <errno.h> + +#include "os_internal.h" + +#ifdef CONFIG_SCHED_HAVE_PARENT + +/***************************************************************************** + * Private Functions + *****************************************************************************/ + +/***************************************************************************** + * Public Functions + *****************************************************************************/ + +/***************************************************************************** + * Name: task_reparent + * + * Description: + * Change the parent of a task. + * + * Parameters: + * ppid - PID of the new parent task (0 for grandparent, i.e. the parent + * of the current parent task) + * chpid - PID of the child to be reparented. + * + * Return Value: + * 0 (OK) on success; A negated errno value on failure. + * + *****************************************************************************/ + +int task_reparent(pid_t ppid, pid_t chpid) +{ +#ifdef CONFIG_SCHED_CHILD_STATUS + FAR struct child_status_s *child; +#endif + _TCB *ptcb; + _TCB *chtcb; + _TCB *otcb; + pid_t opid; + irqstate_t flags; + int ret; + + /* Disable interrupts so that nothing can change in the relatinoship of + * the three task: Child, current parent, and new parent. + */ + + flags = irqsave(); + + /* Get the child tasks TCB (chtcb) */ + + chtcb = sched_gettcb(chpid); + if (!chtcb) + { + ret = -ECHILD; + goto errout_with_ints; + } + + /* Get the PID of the child task's parent (opid) */ + + opid = chtcb->parent; + + /* Get the TCB of the child task's parent (otcb) */ + + otcb = sched_gettcb(opid); + if (!otcb) + { + ret = -ESRCH; + goto errout_with_ints; + } + + /* If new parent task's PID (ppid) is zero, then new parent is the + * grandparent will be the new parent, i.e., the parent of the current + * parent task. + */ + + if (ppid == 0) + { + ppid = otcb->parent; + } + + /* Get the new parent task's TCB (ptcb) */ + + ptcb = sched_gettcb(ppid); + if (!ptcb) + { + ret = -ESRCH; + goto errout_with_ints; + } + + /* Then reparent the child */ + + chtcb->parent = ppid; /* The task specified by ppid is the new parent */ + +#ifdef CONFIG_SCHED_CHILD_STATUS + /* Remove the child status entry from old parent TCB */ + + child = task_removechild(otcb, chpid); + if (child) + { + /* Add the child status entry to the new parent TCB */ + + task_addchild(ptcb, child); + ret = OK; + } + else + { + ret = -ENOENT; + } +#else + DEBUGASSERT(otcb->nchildren > 0); + + otcb->nchildren--; /* The orignal parent now has one few children */ + ptcb->nchildren++; /* The new parent has one additional child */ + ret = OK; +#endif + +errout_with_ints: + irqrestore(flags); + return ret; +} + +#endif /* CONFIG_SCHED_HAVE_PARENT */ |