lpc1788 update from Rommel Marcelo; Beginning of logic to retain child exit status

git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@5549 42af7a65-404d-4744-a932-0658087f49c3
This commit is contained in:
patacongo
2013-01-22 23:42:51 +00:00
parent be066e6fa6
commit 21817ecc38
12 changed files with 1331 additions and 828 deletions
File diff suppressed because it is too large Load Diff
@@ -97,7 +97,7 @@
/* -0x40023fff: Reserved */
#define LPC17_RTC_BASE 0x40024000 /* -0x40027fff: RTC + backup registers */
#define LPC17_GPIOINT_BASE 0x40028000 /* -0x4002bfff: GPIO interrupts */
#define LPC17_PINCONN_BASE 0x4002c000 /* -0x4002ffff: Pin connect block */
#define LPC17_IOCON_BASE 0x4002c000 /* -0x4002ffff: Pin connect block */
#define LPC17_SSP1_BASE 0x40030000 /* -0x40033fff: SSP 1 */
#define LPC17_ADC_BASE 0x40034000 /* -0x40037fff: ADC */
#define LPC17_CANAFRAM_BASE 0x40038000 /* -0x4003bfff: CAN acceptance filter (AF) RAM */
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+28 -24
View File
@@ -171,19 +171,36 @@
#elif defined(LPC178x)
/* Encoding: TT FFFF MMOV PPPN NNNN
Encoding: TTTT TTTT FFFF MMOV PPPN NNNN
*/
/* Encoding: FFFF MMOV PPPN NNNN
*
* Pin Function: FFFF
* Pin Mode bits: MM
* Open drain: O (output pins)
* Initial value: V (output pins)
* Port number: PPP (0-4)
* Pin number: NNNNN (0-31)
/* Encoding: TTTT TTTT FFFF MMOV PPPN NNNN
*
* Special Pin Functions: TTTT TTTT
* Pin Function: FFFF
* Pin Mode bits: MM
* Open drain: O (output pins)
* Initial value: V (output pins)
* Port number: PPP (0-4)
* Pin number: NNNNN (0-31)
*/
/* Special Pin Functions
* For pins that has ADC/DAC, USB, I2C
*/
#define GPIO_IOCON_TYPE_D_MASK (0x0000067f) /* All port except where ADC/DAC, USB, I2C is present */
#define GPIO_IOCON_TYPE_A_MASK (0x000105df) /* USB/ADC/DAC P0:12 to 13, P0:23 to 26, P1:30 to 31 */
#define GPIO_IOCON_TYPE_U_MASK (0x00000007) /* USB P0:29 to 31 */
#define GPIO_IOCON_TYPE_I_MASK (0x00000347) /* I2C/USB P0:27 to 28, P5:2 to 3 */
#define GPIO_IOCON_TYPE_W_MASK (0x000007ff) /* I2S P0:7 to 9 */
# define GPIO_HYS (1 << 16) /* Bit 16: HYSTERESIS: 0-Disable, 1-Enabled */
# define GPIO_INV (1 << 17) /* Bit 17: Input: 0-Not Inverted, 1-Inverted */
# define GPIO_SLEW (1 << 18) /* Bit 18: Rate Control: 0-Standard mode, 1-Fast mode */
# define GPIO_ADMODE (1 << 19) /* Bit 19: A/D Modes: 0-Analog, 1-Digital */
# define GPIO_FILTER (1 << 20) /* Bit 20: Filter: 0-Off, 1-ON */
# define GPIO_DACEN (1 << 21) /* Bit 21: DAC: 0-Disabled, 1-Enabled, P0:26 only */
# define GPIO_I2CHS (1 << 22) /* Bit 22: Filter and Rate Control: 0-Enabled, 1-Disabled */
# define GPIO_HIDRIVE (1 << 23) /* Bit 23: Current Sink: 0-4mA, 1-20mA P5:2 and P5:3 only,*/
/* Pin Function bits: FFFF
* Only meaningful when the GPIO function is GPIO_PIN
*/
@@ -198,24 +215,11 @@
# define GPIO_ALT1 (5 << GPIO_FUNC_SHIFT) /* 0101 Alternate function 1 */
# define GPIO_ALT2 (6 << GPIO_FUNC_SHIFT) /* 0110 Alternate function 2 */
# define GPIO_ALT3 (7 << GPIO_FUNC_SHIFT) /* 0111 Alternate function 3 */
# define GPIO_ALT4 (8 << GPIO_FUNC_SHIFT) /* 1000 Alternate function 4 */
# define GPIO_ALT5 (9 << GPIO_FUNC_SHIFT) /* 1001 Alternate function 5 */
# define GPIO_ALT6 (10 << GPIO_FUNC_SHIFT) /* 1010 Alternate function 6 */
# define GPIO_ALT7 (11 << GPIO_FUNC_SHIFT) /* 1011 Alternate function 7 */
/* Options for each IOCON Types */
//~ #define GPIO_TYPE_SHIFT (16)
//~ #define GPIO_TYPE_MASK (3 << GPIO_TYPE_SHIFT)
//~ # define GPIO_HYSTERIS (<< 0 << )
//~ # define GPIO_INVERTED (<< 1 << )
//~ # define GPIO_SLEW (<< 2 << )
//~ # define GPIO_ADMODE (<< 3 << )
//~ # define GPIO_FILTER (<< 4 << )
//~ # define GPIO_DACEN (<< 5 << )
//~ # define GPIO_I2CHS (<< 6 << )
//~ # define GPIO_HIDRIVE (<< 7 << )
#define GPIO_EDGE_SHIFT (13) /* Bits 13-14: Interrupt edge bits */
#define GPIO_EDGE_MASK (3 << GPIO_EDGE_SHIFT)
+52 -18
View File
@@ -62,21 +62,30 @@
/* This is the maximum number of times that a lock can be set */
#define MAX_LOCK_COUNT 127
#define MAX_LOCK_COUNT 127
/* Values for the _TCB flags flag bits */
#define TCB_FLAG_TTYPE_SHIFT (0) /* Bits 0-1: thread type */
#define TCB_FLAG_TTYPE_MASK (3 << TCB_FLAG_TTYPE_SHIFT)
# define TCB_FLAG_TTYPE_TASK (0 << TCB_FLAG_TTYPE_SHIFT) /* Normal user task */
# define TCB_FLAG_TTYPE_PTHREAD (1 << TCB_FLAG_TTYPE_SHIFT) /* User pthread */
# define TCB_FLAG_TTYPE_KERNEL (2 << TCB_FLAG_TTYPE_SHIFT) /* Kernel thread */
#define TCB_FLAG_NONCANCELABLE (1 << 2) /* Bit 2: Pthread is non-cancelable */
#define TCB_FLAG_CANCEL_PENDING (1 << 3) /* Bit 3: Pthread cancel is pending */
#define TCB_FLAG_ROUND_ROBIN (1 << 4) /* Bit 4: Round robin sched enabled */
#define TCB_FLAG_TTYPE_SHIFT (0) /* Bits 0-1: thread type */
#define TCB_FLAG_TTYPE_MASK (3 << TCB_FLAG_TTYPE_SHIFT)
# define TCB_FLAG_TTYPE_TASK (0 << TCB_FLAG_TTYPE_SHIFT) /* Normal user task */
# define TCB_FLAG_TTYPE_PTHREAD (1 << TCB_FLAG_TTYPE_SHIFT) /* User pthread */
# define TCB_FLAG_TTYPE_KERNEL (2 << TCB_FLAG_TTYPE_SHIFT) /* Kernel thread */
#define TCB_FLAG_NONCANCELABLE (1 << 2) /* Bit 2: Pthread is non-cancelable */
#define TCB_FLAG_CANCEL_PENDING (1 << 3) /* Bit 3: Pthread cancel is pending */
#define TCB_FLAG_ROUND_ROBIN (1 << 4) /* Bit 4: Round robin sched enabled */
/* Values for struct child_status_s ch_flags */
#define CHILD_FLAG_TTYPE_SHIFT (0) /* Bits 0-1: child thread type */
#define CHILD_FLAG_TTYPE_MASK (3 << CHILD_FLAG_TTYPE_SHIFT)
# define CHILD_FLAG_TTYPE_TASK (0 << CHILD_FLAG_TTYPE_SHIFT) /* Normal user task */
# define CHILD_FLAG_TTYPE_PTHREAD (1 << CHILD_FLAG_TTYPE_SHIFT) /* User pthread */
# define CHILD_FLAG_TTYPE_KERNEL (2 << CHILD_FLAG_TTYPE_SHIFT) /* Kernel thread */
#define CHILD_FLAG_EXITED (1 << 0) /* Bit 2: The child thread has exit'ed */
/********************************************************************************
* Global Type Definitions
* Public Type Definitions
********************************************************************************/
#ifndef __ASSEMBLY__
@@ -163,6 +172,22 @@ typedef struct environ_s environ_t;
# define SIZEOF_ENVIRON_T(alloc) (sizeof(environ_t) + alloc - 1)
#endif
/* This structure is used to maintin information about child tasks.
* pthreads work differently, they have join information. This is
* only for child tasks.
*/
#ifdef CONFIG_SCHED_CHILD_STATUS
struct child_status_s
{
FAR struct child_status_s *flink;
uint8_t ch_flags; /* Child status: See CHILD_FLAG_* definitions */
pid_y ch_pid; /* Child task ID */
int ch_status; /* Child exit status */
};
#endif
/* This structure describes a reference counted D-Space region. This must be a
* separately allocated "break-away" structure that can be owned by a task and
* any pthreads created by the task.
@@ -202,9 +227,13 @@ struct _TCB
/* Task Management Fields *****************************************************/
pid_t pid; /* This is the ID of the thread */
#ifdef CONFIG_SCHED_HAVE_PARENT
#ifdef CONFIG_SCHED_HAVE_PARENT /* Support parent-child relationship */
pid_t parent; /* This is the ID of the parent thread */
#ifdef CONFIG_SCHED_CHILD_STATUS /* Retain child thread status */
FAR struct child_status_s *children; /* Head of a list of child status */
#else
uint16_t nchildren; /* This is the number active children */
#endif
#endif
start_t start; /* Thread start function */
entry_t entry; /* Entry Point into the thread */
@@ -357,33 +386,38 @@ typedef void (*sched_foreach_t)(FAR _TCB *tcb, FAR void *arg);
#endif /* __ASSEMBLY__ */
/********************************************************************************
* Global Function Prototypes
* Public Data
********************************************************************************/
#ifndef __ASSEMBLY__
#undef EXTERN
#if defined(__cplusplus)
#define EXTERN extern "C"
extern "C" {
extern "C"
{
#else
#define EXTERN extern
#endif
/********************************************************************************
* Public Function Prototypes
********************************************************************************/
/* TCB helpers */
EXTERN FAR _TCB *sched_self(void);
FAR _TCB *sched_self(void);
/* File system helpers */
#if CONFIG_NFILE_DESCRIPTORS > 0
EXTERN FAR struct filelist *sched_getfiles(void);
FAR struct filelist *sched_getfiles(void);
#if CONFIG_NFILE_STREAMS > 0
EXTERN FAR struct streamlist *sched_getstreams(void);
FAR struct streamlist *sched_getstreams(void);
#endif /* CONFIG_NFILE_STREAMS */
#endif /* CONFIG_NFILE_DESCRIPTORS */
#if CONFIG_NSOCKET_DESCRIPTORS > 0
EXTERN FAR struct socketlist *sched_getsockets(void);
FAR struct socketlist *sched_getsockets(void);
#endif /* CONFIG_NSOCKET_DESCRIPTORS */
/* Internal vfork support.The overall sequence is:
@@ -417,7 +451,7 @@ void task_vforkabort(FAR _TCB *child, int errcode);
* will be disabled throughout this enumeration!
*/
EXTERN void sched_foreach(sched_foreach_t handler, FAR void *arg);
void sched_foreach(sched_foreach_t handler, FAR void *arg);
#undef EXTERN
#if defined(__cplusplus)
+35 -30
View File
@@ -79,7 +79,7 @@
#endif
/********************************************************************************
* Global Type Definitions
* Public Type Definitions
********************************************************************************/
/* This is the POSIX-like scheduling parameter structure */
@@ -90,56 +90,61 @@ struct sched_param
};
/********************************************************************************
* Global Function Prototypes
* Public Data
********************************************************************************/
#ifndef __ASSEMBLY__
#undef EXTERN
#if defined(__cplusplus)
#define EXTERN extern "C"
extern "C" {
extern "C"
{
#else
#define EXTERN extern
#endif
/********************************************************************************
* Public Function Prototypes
********************************************************************************/
/* Task Control Interfaces (non-standard) */
#ifndef CONFIG_CUSTOM_STACK
EXTERN int task_init(FAR _TCB *tcb, const char *name, int priority,
FAR uint32_t *stack, uint32_t stack_size,
main_t entry, const char *argv[]);
int task_init(FAR _TCB *tcb, const char *name, int priority,
FAR uint32_t *stack, uint32_t stack_size, main_t entry,
FAR const char *argv[]);
#else
EXTERN int task_init(FAR _TCB *tcb, const char *name, int priority,
main_t entry, const char *argv[]);
int task_init(FAR _TCB *tcb, const char *name, int priority, main_t entry,
FAR const char *argv[]);
#endif
EXTERN int task_activate(FAR _TCB *tcb);
int task_activate(FAR _TCB *tcb);
#ifndef CONFIG_CUSTOM_STACK
EXTERN int task_create(const char *name, int priority, int stack_size,
main_t entry, const char *argv[]);
int task_create(FAR const char *name, int priority, int stack_size, main_t entry,
FAR const char *argv[]);
#else
EXTERN int task_create(const char *name, int priority,
main_t entry, const char *argv[]);
int task_create(FAR const char *name, int priority, main_t entry,
FAR const char *argv[]);
#endif
EXTERN int task_delete(pid_t pid);
EXTERN int task_restart(pid_t pid);
int task_delete(pid_t pid);
int task_restart(pid_t pid);
/* Task Scheduling Interfaces (based on POSIX APIs) */
EXTERN int sched_setparam(pid_t pid, const struct sched_param *param);
EXTERN int sched_getparam(pid_t pid, struct sched_param *param);
EXTERN int sched_setscheduler(pid_t pid, int policy,
const struct sched_param *param);
EXTERN int sched_getscheduler(pid_t pid);
EXTERN int sched_yield(void);
EXTERN int sched_get_priority_max(int policy);
EXTERN int sched_get_priority_min(int policy);
EXTERN int sched_rr_get_interval(pid_t pid, struct timespec *interval);
int sched_setparam(pid_t pid, const struct sched_param *param);
int sched_getparam(pid_t pid, struct sched_param *param);
int sched_setscheduler(pid_t pid, int policy,
FAR const struct sched_param *param);
int sched_getscheduler(pid_t pid);
int sched_yield(void);
int sched_get_priority_max(int policy);
int sched_get_priority_min(int policy);
int sched_rr_get_interval(pid_t pid, FAR struct timespec *interval);
/* Task Switching Interfaces (non-standard) */
EXTERN int sched_lock(void);
EXTERN int sched_unlock(void);
EXTERN int sched_lockcount(void);
int sched_lock(void);
int sched_unlock(void);
int sched_lockcount(void);
/* If instrumentation of the scheduler is enabled, then some outboard logic
* must provide the following interfaces.
@@ -147,9 +152,9 @@ EXTERN int sched_lockcount(void);
#ifdef CONFIG_SCHED_INSTRUMENTATION
EXTERN void sched_note_start(FAR _TCB *tcb);
EXTERN void sched_note_stop(FAR _TCB *tcb);
EXTERN void sched_note_switch(FAR _TCB *pFromTcb, FAR _TCB *pToTcb);
void sched_note_start(FAR _TCB *tcb);
void sched_note_stop(FAR _TCB *tcb);
void sched_note_switch(FAR _TCB *pFromTcb, FAR _TCB *pToTcb);
#else
# define sched_note_start(t)
+4 -1
View File
@@ -74,7 +74,10 @@ SCHED_SRCS += sched_reprioritize.c
endif
ifeq ($(CONFIG_SCHED_HAVE_PARENT),y)
SCHED_SRCS += task_reparent.c
SCHED_SRCS += task_reparent.c
ifeq ($(CONFIG_SCHED_CHILD_STATUS),y)
SCHED_SRCS += task_childstatus.c
endif
endif
ifeq ($(CONFIG_SCHED_WAITPID),y)
+11 -1
View File
@@ -1,7 +1,7 @@
/****************************************************************************
* sched/os_internal.h
*
* 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
@@ -269,6 +269,16 @@ int task_argsetup(FAR _TCB *tcb, FAR const char *name, FAR const char *argv[]);
void task_exithook(FAR _TCB *tcb, int status);
int task_deletecurrent(void);
#ifdef CONFIG_SCHED_HAVE_PARENT
#ifdef CONFIG_SCHED_CHILD_STATUS
void weak_functiontask_initialize(void);
FAR struct child_status_s *task_allocchild(void);
void task_freechild(FAR struct child_status_s *status);
FAR struct child_status_s *task_addchild(FAR _TCB *tcb, pid_t pid, int status,
uint8_t flags);
FAR struct child_status_s *task_findchild(FAR _TCB *tcb, pid_t pid);
FAR struct child_status_s *task_removechild(FAR _TCB *tcb, pid_t pid);
void task_removechildren(FAR _TCB *tcb);
#endif
int task_reparent(pid_t ppid, pid_t chpid);
#endif
#ifndef CONFIG_CUSTOM_STACK
+11
View File
@@ -314,6 +314,17 @@ void os_start(void)
kmm_initialize((void*)CONFIG_HEAP_BASE, CONFIG_HEAP_SIZE);
#endif
/* Initialize tasking data structures */
#if defined(CONFIG_SCHED_HAVE_PARENT) && defined(CONFIG_SCHED_CHILD_STATUS)
#ifdef CONFIG_HAVE_WEAKFUNCTIONS
if (task_initialize != NULL)
#endif
{
task_initialize();
}
#endif
/* Initialize the interrupt handling subsystem (if included) */
#ifdef CONFIG_HAVE_WEAKFUNCTIONS
+1 -1
View File
@@ -155,7 +155,7 @@ int waitid(idtype_t idtype, id_t id, siginfo_t *info, int options)
sched_lock();
/* Verify that this task actually has children and that the the requeste
/* Verify that this task actually has children and that the the requested
* TCB is actually a child of this task.
*/
+365
View File
@@ -0,0 +1,365 @@
/*****************************************************************************
* sched/task_childstatus.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"
#if defined(CONFIG_SCHED_HAVE_PARENT) && defined(CONFIG_SCHED_CHILD_STATUS)
/*****************************************************************************
* Private Types
*****************************************************************************/
/* Globals are maintained in a structure to minimize name collisions. Note
* that there cannot be more that CONFIG_MAX_TASKS tasks in total. So using
* CONFIG_MAX_TASKS should be sufficient (at least one task, the IDLE thread,
* will have no parent).
*/
struct child_pool_s
{
struct child_status_s alloc[CONFIG_MAX_TASKS];
FAR struct child_status_s *freelist;
};
/*****************************************************************************
* Private Data
*****************************************************************************/
static struct child_pool_s g_child_pool;
/*****************************************************************************
* Private Functions
*****************************************************************************/
/*****************************************************************************
* Public Functions
*****************************************************************************/
/*****************************************************************************
* Name: task_initialize
*
* Description:
* Initialize task related status. At present, this includes only the
* initialize of the child status pool.
*
* Parameters:
* None.
*
* Return Value:
* None.
*
* Assumptions:
* Called early in initializatin. No special precautions are required.
*
*****************************************************************************/
void task_initialize(void)
{
FAR struct child_status_s *curr;
FAR struct child_status_s *prev;
int i;
/* Save all of the child status structures in a free list */
prev = &g_child_pool.alloc[0];
g_child_pool.freelist = prev;
for (i = 0; i < CONFIG_MAX_TASKS; i++)
{
curr = &g_child_pool.alloc[i]
prev->flink = curr;
prev = curr;
}
}
/*****************************************************************************
* Name: task_allocchild
*
* Description:
* Allocate a child status structure by removing the next entry from a
* free list.
*
* Parameters:
* None.
*
* Return Value:
* On success, a non-NULL pointer to a child status structure. NULL is
* returned if there are no remaining, pre-allocated child status structures.
*
* Assumptions:
* Called during task creation in a safe context. No special precautions
* are required here.
*
*****************************************************************************/
FAR struct child_status_s *task_allocchild(void)
{
FAR struct child_status_s *ret;
/* Return the status block at the head of the free list */
ret = g_child_pool.freelist;
if (ret)
{
g_child_pool.freelist = ret->flink;
ret->flink = NULL;
}
return ret;
}
/*****************************************************************************
* Name: task_freechild
*
* Description:
* Release a child status structure by returning it to a free list.
*
* Parameters:
* status - The child status structure to be freed.
*
* Return Value:
* None.
*
* Assumptions:
* Called during task creation in a safe context. No special precautions
* are required here.
*
*****************************************************************************/
void task_freechild(FAR struct child_status_s *child)
{
/* Return the child status structure to the free list */
if (child)
{
child->flink = g_child_pool.freelist;
g_child_pool.freelist = child;
}
}
/*****************************************************************************
* Name: task_addchild
*
* Description:
* Find a child status structure in the given TCB.
*
* Parameters:
* tcb - The TCB of the parent task to containing the child status.
* pid - The ID of the child to create
* status - Child exit status (should be zero)
* flags - Child flags (see CHILD_FLAGS_* defininitions)
*
* Return Value:
* On success, a non-NULL pointer to a child status structure. NULL is
* returned if (1) there are no free status structures, or (2) an entry
* with this PID already exists.
*
* Assumptions:
* Called during task creation processing in a safe context. No special
* precautions are required here.
*
*****************************************************************************/
FAR struct child_status_s *task_addchild(FAR _TCB *tcb, pid_t pid, int status,
uint8_t flags)
{
FAR struct child_status_s *child;
/* Make sure that there is not already a structure for this PID */
child = task_findchild(tcb, pid);
if (child)
{
return NULL;
}
/* Allocate a new status structure */
child = task_allocchild(void);
if (child)
{
/* Initialize the structure */
child->ch_flags = flags;
child->ch_pid = pid;
child->ch_status = status;
/* Add the entry into the TCB list of children */
status->flink = tcb->children;
tcb->childen = status;
}
return child;
}
/*****************************************************************************
* Name: task_findchild
*
* Description:
* Find a child status structure in the given TCB. A reference to the
* child structure is returned, but the child remains the the TCB's list
* of children.
*
* Parameters:
* tcb - The TCB of the parent task to containing the child status.
* pid - The ID of the child to find.
*
* Return Value:
* On success, a non-NULL pointer to a child status structure. NULL is
* returned if there is child status structure for that pid in the TCB.
*
* Assumptions:
* Called during SIGCHLD processing in a safe context. No special precautions
* are required here.
*
*****************************************************************************/
FAR struct child_status_s *task_findchild(FAR _TCB *tcb, pid_t pid)
{
FAR struct child_status_s *child;
/* Find the status structure with the matching PID */
for (child = tcb->children; child; child = child->flink)
{
if (child->ch_pid == pid)
{
return child;
}
}
return NULL;
}
/*****************************************************************************
* Name: task_removechild
*
* Description:
* Remove one child structure from the TCB. The child is removed, but is
* not yet freed. task_freechild must be called in order to free the child
* status structure.
*
* Parameters:
* tcb - The TCB of the parent task to containing the child status.
* pid - The ID of the child to find.
*
* Return Value:
* On success, a non-NULL pointer to a child status structure. NULL is
* returned if there is child status structure for that pid in the TCB.
*
* Assumptions:
* Called during SIGCHLD processing in a safe context. No special precautions
* are required here.
*
*****************************************************************************/
FAR struct child_status_s *task_removechild(FAR _TCB *tcb, pid_t pid)
{
FAR struct child_status_s *curr;
FAR struct child_status_s *prev;
/* Find the status structure with the matching PID */
for (prev = NULL, curr = tcb->children;
curr;
prev = curr, curr = curr->flink)
{
if (curr->ch_pid == pid)
{
break;
}
}
/* Did we find it? If so, remove it from the TCB. */
if (curr)
{
/* Do we remove it from mid-list? Or from the head of the list? */
if (prev)
{
prev->flink = curr->flink;
}
else
{
tcb->children = curr->flink;
}
curr->flink = NULL;
}
return curr;
}
/*****************************************************************************
* Name: task_removechildren
*
* Description:
* Remove and free all child structure from the TCB.
*
* Parameters:
* tcb - The TCB of the parent task to containing the child status.
*
* Return Value:
* None.
*
* Assumptions:
* Called during task exit processing in a safe context. No special
* precautions are required here.
*
*****************************************************************************/
void task_removechildren(FAR _TCB *tcb)
{
FAR struct child_status_s *curr;
FAR struct child_status_s *next;
/* Remove all child structures for the TCB and return them to the freelist */
for (curr = tcb->children; curr; curr = next)
{
next = curr->flink;
task_freechild(curr);
}
}
#endif /* CONFIG_SCHED_HAVE_PARENT && CONFIG_SCHED_CHILD_STATUS */