From 8300858eb811cc92011e98a5d89390df420e665e Mon Sep 17 00:00:00 2001 From: patacongo Date: Sat, 26 Jan 2013 20:17:29 +0000 Subject: Move file data from TCB to task group git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@5567 42af7a65-404d-4744-a932-0658087f49c3 --- nuttx/ChangeLog | 2 + nuttx/TODO | 23 +---- nuttx/arch/arm/src/common/up_exit.c | 8 +- nuttx/arch/avr/src/common/up_exit.c | 8 +- nuttx/arch/hc/src/common/up_exit.c | 8 +- nuttx/arch/mips/src/common/up_exit.c | 8 +- nuttx/arch/sh/src/common/up_exit.c | 9 +- nuttx/arch/x86/src/common/up_exit.c | 6 +- nuttx/arch/z16/src/common/up_exit.c | 11 +- nuttx/arch/z80/src/common/up_exit.c | 9 +- nuttx/fs/fs_fdopen.c | 8 +- nuttx/fs/fs_files.c | 101 ++++--------------- nuttx/include/nuttx/fs/fs.h | 89 +++++++---------- nuttx/include/nuttx/sched.h | 42 +++++--- nuttx/sched/group_leave.c | 16 ++- nuttx/sched/sched_getfiles.c | 5 +- nuttx/sched/sched_releasefiles.c | 13 ++- nuttx/sched/sched_releasetcb.c | 4 - nuttx/sched/sched_setupidlefiles.c | 15 +-- nuttx/sched/sched_setuppthreadfiles.c | 8 -- nuttx/sched/sched_setuptaskfiles.c | 49 +++++---- nuttx/sched/task_exithook.c | 182 +++++++++++++++++++++------------- 22 files changed, 288 insertions(+), 336 deletions(-) diff --git a/nuttx/ChangeLog b/nuttx/ChangeLog index 858f82819..ae7105b89 100644 --- a/nuttx/ChangeLog +++ b/nuttx/ChangeLog @@ -4034,3 +4034,5 @@ * sched/: Lots of file changed. Don't keep the parent task's task ID in the child task's TCB. Instead, keep the parent task group IN the child task's task group. + * fs/, sched/, include/nuttx/sched.h, and include/nutts/fs/fs.h: + Move file data from TCB to task group structure. diff --git a/nuttx/TODO b/nuttx/TODO index d6bd18d12..cb99f1bf7 100644 --- a/nuttx/TODO +++ b/nuttx/TODO @@ -1,4 +1,4 @@ -NuttX TODO List (Last updated January 24, 2013) +NuttX TODO List (Last updated January 26, 2013) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ This file summarizes known NuttX bugs, limitations, inconsistencies with @@ -6,7 +6,7 @@ standards, things that could be improved, and ideas for enhancements. nuttx/ - (11) Task/Scheduler (sched/) + (10) Task/Scheduler (sched/) (2) Memory Managment (mm/) (3) Signals (sched/, arch/) (2) pthreads (sched/) @@ -161,25 +161,6 @@ o Task/Scheduler (sched/) Status: Open Priority: Medium Low for now - Title: IMPROVED TASK CONTROL BLOCK STRUCTURE - Description: All task resources that are shared amongst threads have - their own "break-away", reference-counted structure. The - Task Control Block (TCB) of each thread holds a reference - to each breakaway structure (see include/nuttx/sched.h). - It would be more efficent to have one reference counted - structure that holds all of the shared resources. - - These are the current shared structures: - - Environment varaibles (struct environ_s) - - PIC data space and address environments (struct dspace_s) - - File descriptors (struct filelist) - - FILE streams (struct streamlist) - - Sockets (struct socketlist) - Status: Open - Priority: Low. This is an enhancement. It would slight reduce - memory usage but would also increase coupling. These - resources are nicely modular now. - Title: ISSUES WITH atexit() AND on_exit() Description: These functions execute with the following bad properties: diff --git a/nuttx/arch/arm/src/common/up_exit.c b/nuttx/arch/arm/src/common/up_exit.c index 6f6d54f76..5b469fd03 100644 --- a/nuttx/arch/arm/src/common/up_exit.c +++ b/nuttx/arch/arm/src/common/up_exit.c @@ -1,7 +1,7 @@ /**************************************************************************** * common/up_exit.c * - * Copyright (C) 2007-2009, 2012 Gregory Nutt. All rights reserved. + * Copyright (C) 2007-2009, 201-2013 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -85,12 +85,10 @@ static void _up_dumponexit(FAR _TCB *tcb, FAR void *arg) #if CONFIG_NFILE_DESCRIPTORS > 0 if (tcb->filelist) { - sdbg(" filelist refcount=%d\n", - tcb->filelist->fl_crefs); - + FAR struct filelist *list = tcb->group->tg_filelist; for (i = 0; i < CONFIG_NFILE_DESCRIPTORS; i++) { - struct inode *inode = tcb->filelist->fl_files[i].f_inode; + struct inode *inode = list->fl_files[i].f_inode; if (inode) { sdbg(" fd=%d refcount=%d\n", diff --git a/nuttx/arch/avr/src/common/up_exit.c b/nuttx/arch/avr/src/common/up_exit.c index 0a8cc0d18..0813754a0 100644 --- a/nuttx/arch/avr/src/common/up_exit.c +++ b/nuttx/arch/avr/src/common/up_exit.c @@ -1,7 +1,7 @@ /**************************************************************************** * arch/avr/src/common/up_exit.c * - * Copyright (C) 2010 Gregory Nutt. All rights reserved. + * Copyright (C) 2010, 2013 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -85,12 +85,10 @@ static void _up_dumponexit(FAR _TCB *tcb, FAR void *arg) #if CONFIG_NFILE_DESCRIPTORS > 0 if (tcb->filelist) { - sdbg(" filelist refcount=%d\n", - tcb->filelist->fl_crefs); - + FAR struct filelist *list = tcb->group->tg_filelist; for (i = 0; i < CONFIG_NFILE_DESCRIPTORS; i++) { - struct inode *inode = tcb->filelist->fl_files[i].f_inode; + struct inode *inode = list->fl_files[i].f_inode; if (inode) { sdbg(" fd=%d refcount=%d\n", diff --git a/nuttx/arch/hc/src/common/up_exit.c b/nuttx/arch/hc/src/common/up_exit.c index 7cd16b438..5313a1172 100644 --- a/nuttx/arch/hc/src/common/up_exit.c +++ b/nuttx/arch/hc/src/common/up_exit.c @@ -1,7 +1,7 @@ /**************************************************************************** * arch/hc/src/common/up_exit.c * - * Copyright (C) 2011 Gregory Nutt. All rights reserved. + * Copyright (C) 2011, 2013 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -85,12 +85,10 @@ static void _up_dumponexit(FAR _TCB *tcb, FAR void *arg) #if CONFIG_NFILE_DESCRIPTORS > 0 if (tcb->filelist) { - sdbg(" filelist refcount=%d\n", - tcb->filelist->fl_crefs); - + FAR struct filelist *list = tcb->group->tg_filelist; for (i = 0; i < CONFIG_NFILE_DESCRIPTORS; i++) { - struct inode *inode = tcb->filelist->fl_files[i].f_inode; + struct inode *inode = list->fl_files[i].f_inode; if (inode) { sdbg(" fd=%d refcount=%d\n", diff --git a/nuttx/arch/mips/src/common/up_exit.c b/nuttx/arch/mips/src/common/up_exit.c index 876b486b6..5a7b68a99 100644 --- a/nuttx/arch/mips/src/common/up_exit.c +++ b/nuttx/arch/mips/src/common/up_exit.c @@ -1,7 +1,7 @@ /**************************************************************************** * arch/mips/src/common/up_exit.c * - * Copyright (C) 2011 Gregory Nutt. All rights reserved. + * Copyright (C) 2011, 2013 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -87,12 +87,10 @@ static void _up_dumponexit(FAR _TCB *tcb, FAR void *arg) #if CONFIG_NFILE_DESCRIPTORS > 0 if (tcb->filelist) { - sdbg(" filelist refcount=%d\n", - tcb->filelist->fl_crefs); - + FAR struct filelist *list = tcb->group->tg_filelist; for (i = 0; i < CONFIG_NFILE_DESCRIPTORS; i++) { - struct inode *inode = tcb->filelist->fl_files[i].f_inode; + struct inode *inode = list->fl_files[i].f_inode; if (inode) { sdbg(" fd=%d refcount=%d\n", diff --git a/nuttx/arch/sh/src/common/up_exit.c b/nuttx/arch/sh/src/common/up_exit.c index 84a44a705..af270b335 100644 --- a/nuttx/arch/sh/src/common/up_exit.c +++ b/nuttx/arch/sh/src/common/up_exit.c @@ -1,7 +1,7 @@ /**************************************************************************** * common/up_exit.c * - * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved. + * Copyright (C) 2008-2009, 2013 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -81,16 +81,15 @@ static void _up_dumponexit(FAR _TCB *tcb, FAR void *arg) #endif sdbg(" TCB=%p name=%s\n", tcb, tcb->argv[0]); + sdbg(" priority=%d state=%d\n", tcb->sched_priority, tcb->task_state); #if CONFIG_NFILE_DESCRIPTORS > 0 if (tcb->filelist) { - sdbg(" filelist refcount=%d\n", - tcb->filelist->fl_crefs); - + FAR struct filelist *list = tcb->group->tg_filelist; for (i = 0; i < CONFIG_NFILE_DESCRIPTORS; i++) { - struct inode *inode = tcb->filelist->fl_files[i].f_inode; + struct inode *inode = list->fl_files[i].f_inode; if (inode) { sdbg(" fd=%d refcount=%d\n", diff --git a/nuttx/arch/x86/src/common/up_exit.c b/nuttx/arch/x86/src/common/up_exit.c index e3d27b0af..6a98c7dd0 100644 --- a/nuttx/arch/x86/src/common/up_exit.c +++ b/nuttx/arch/x86/src/common/up_exit.c @@ -85,12 +85,10 @@ static void _up_dumponexit(FAR _TCB *tcb, FAR void *arg) #if CONFIG_NFILE_DESCRIPTORS > 0 if (tcb->filelist) { - sdbg(" filelist refcount=%d\n", - tcb->filelist->fl_crefs); - + FAR struct filelist *list = tcb->group->tg_filelist; for (i = 0; i < CONFIG_NFILE_DESCRIPTORS; i++) { - struct inode *inode = tcb->filelist->fl_files[i].f_inode; + struct inode *inode = list->fl_files[i].f_inode; if (inode) { sdbg(" fd=%d refcount=%d\n", diff --git a/nuttx/arch/z16/src/common/up_exit.c b/nuttx/arch/z16/src/common/up_exit.c index 41f058347..ad0c55eed 100644 --- a/nuttx/arch/z16/src/common/up_exit.c +++ b/nuttx/arch/z16/src/common/up_exit.c @@ -1,7 +1,7 @@ /**************************************************************************** * common/up_exit.c * - * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved. + * Copyright (C) 2008-2009, 2013 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -81,17 +81,16 @@ static void _up_dumponexit(FAR _TCB *tcb, FAR void *arg) int i; #endif - dbg(" TCB=%p name=%s\n", tcb, tcb->argv[0]); + lldbg(" TCB=%p name=%s\n", tcb, tcb->argv[0]); + lldbg(" priority=%d state=%d\n", tcb->sched_priority, tcb->task_state); #if CONFIG_NFILE_DESCRIPTORS > 0 if (tcb->filelist) { - lldbg(" filelist refcount=%d\n", - tcb->filelist->fl_crefs); - + FAR struct filelist *list = tcb->group->tg_filelist; for (i = 0; i < CONFIG_NFILE_DESCRIPTORS; i++) { - struct inode *inode = tcb->filelist->fl_files[i].f_inode; + struct inode *inode = list->fl_files[i].f_inode; if (inode) { lldbg(" fd=%d refcount=%d\n", diff --git a/nuttx/arch/z80/src/common/up_exit.c b/nuttx/arch/z80/src/common/up_exit.c index 85ddd841e..50289f52b 100644 --- a/nuttx/arch/z80/src/common/up_exit.c +++ b/nuttx/arch/z80/src/common/up_exit.c @@ -82,17 +82,16 @@ static void _up_dumponexit(FAR _TCB *tcb, FAR void *arg) int i; #endif - dbg(" TCB=%p name=%s\n", tcb, tcb->argv[0]); + lldbg(" TCB=%p name=%s\n", tcb, tcb->argv[0]); + lldbg(" priority=%d state=%d\n", tcb->sched_priority, tcb->task_state); #if CONFIG_NFILE_DESCRIPTORS > 0 if (tcb->filelist) { - lldbg(" filelist refcount=%d\n", - tcb->filelist->fl_crefs); - + FAR struct filelist *list = tcb->group->tg_filelist; for (i = 0; i < CONFIG_NFILE_DESCRIPTORS; i++) { - struct inode *inode = tcb->filelist->fl_files[i].f_inode; + struct inode *inode = list->fl_files[i].f_inode; if (inode) { lldbg(" fd=%d refcount=%d\n", diff --git a/nuttx/fs/fs_fdopen.c b/nuttx/fs/fs_fdopen.c index fd6aa88a8..629083c77 100644 --- a/nuttx/fs/fs_fdopen.c +++ b/nuttx/fs/fs_fdopen.c @@ -1,7 +1,7 @@ /**************************************************************************** * fs/fs_fdopen.c * - * Copyright (C) 2007-2012 Gregory Nutt. All rights reserved. + * Copyright (C) 2007-2013 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -68,9 +68,11 @@ static inline int fs_checkfd(FAR _TCB *tcb, int fd, int oflags) FAR struct filelist *flist; FAR struct inode *inode; - /* Get the file list from the TCB */ + DEBUGASSERT(tcb && tcb->group); - flist = tcb->filelist; + /* Get the file list from the task group */ + + flist = &tcb->group->tg_filelist; /* Get the inode associated with the file descriptor. This should * normally be the case if fd >= 0. But not in the case where the diff --git a/nuttx/fs/fs_files.c b/nuttx/fs/fs_files.c index 06addb1ef..c68ec7e73 100644 --- a/nuttx/fs/fs_files.c +++ b/nuttx/fs/fs_files.c @@ -155,56 +155,19 @@ void files_initialize(void) } /**************************************************************************** - * Name: files_alloclist + * Name: files_initlist * - * Description: Allocate a list of files for a new task + * Description: Initializes the list of files for a new task * ****************************************************************************/ -FAR struct filelist *files_alloclist(void) +void files_initlist(FAR struct filelist *list) { - FAR struct filelist *list; - list = (FAR struct filelist*)kzalloc(sizeof(struct filelist)); - if (list) - { - /* Start with a reference count of one */ - - list->fl_crefs = 1; - - /* Initialize the list access mutex */ + DEBUGASSERT(list); - (void)sem_init(&list->fl_sem, 0, 1); - } + /* Initialize the list access mutex */ - return list; -} - -/**************************************************************************** - * Name: files_addreflist - * - * Description: - * Increase the reference count on a file list - * - ****************************************************************************/ - -int files_addreflist(FAR struct filelist *list) -{ - if (list) - { - /* Increment the reference count on the list. - * NOTE: that we disable interrupts to do this - * (vs. taking the list semaphore). We do this - * because file cleanup operations often must be - * done from the IDLE task which cannot wait - * on semaphores. - */ - - register irqstate_t flags = irqsave(); - list->fl_crefs++; - irqrestore(flags); - } - - return OK; + (void)sem_init(&list->fl_sem, 0, 1); } /**************************************************************************** @@ -215,51 +178,25 @@ int files_addreflist(FAR struct filelist *list) * ****************************************************************************/ -int files_releaselist(FAR struct filelist *list) +void files_releaselist(FAR struct filelist *list) { - int crefs; - if (list) - { - /* Decrement the reference count on the list. - * NOTE: that we disable interrupts to do this - * (vs. taking the list semaphore). We do this - * because file cleanup operations often must be - * done from the IDLE task which cannot wait - * on semaphores. - */ - - register irqstate_t flags = irqsave(); - crefs = --(list->fl_crefs); - irqrestore(flags); - - /* If the count decrements to zero, then there is no reference - * to the structure and it should be deallocated. Since there - * are references, it would be an error if any task still held - * a reference to the list's semaphore. - */ - - if (crefs <= 0) - { - int i; + int i; - /* Close each file descriptor .. Normally, you would need - * take the list semaphore, but it is safe to ignore the - * semaphore in this context because there are no references - */ + DEBUGASSERT(list); - for (i = 0; i < CONFIG_NFILE_DESCRIPTORS; i++) - { - (void)_files_close(&list->fl_files[i]); - } - - /* Destroy the semaphore and release the filelist */ + /* Close each file descriptor .. Normally, you would need take the list + * semaphore, but it is safe to ignore the semaphore in this context because + * there should not be any references in this context. + */ - (void)sem_destroy(&list->fl_sem); - sched_free(list); - } + for (i = 0; i < CONFIG_NFILE_DESCRIPTORS; i++) + { + (void)_files_close(&list->fl_files[i]); } - return OK; + /* Destroy the semaphore */ + + (void)sem_destroy(&list->fl_sem); } /**************************************************************************** diff --git a/nuttx/include/nuttx/fs/fs.h b/nuttx/include/nuttx/fs/fs.h index 327bf37ca..02855460c 100644 --- a/nuttx/include/nuttx/fs/fs.h +++ b/nuttx/include/nuttx/fs/fs.h @@ -240,7 +240,6 @@ struct file struct filelist { sem_t fl_sem; /* Manage access to the file list */ - int16_t fl_crefs; /* Reference count */ struct file fl_files[CONFIG_NFILE_DESCRIPTORS]; }; #endif @@ -318,7 +317,8 @@ typedef int (*foreach_mountpoint_t)(FAR const char *mountpoint, #undef EXTERN #if defined(__cplusplus) #define EXTERN extern "C" -extern "C" { +extern "C" +{ #else #define EXTERN extern #endif @@ -333,7 +333,7 @@ extern "C" { * ****************************************************************************/ -EXTERN void weak_function fs_initialize(void); +void weak_function fs_initialize(void); /* fs_foreachmountpoint.c ***************************************************/ /**************************************************************************** @@ -357,7 +357,7 @@ EXTERN void weak_function fs_initialize(void); ****************************************************************************/ #ifndef CONFIG_DISABLE_MOUNTPOUNT -EXTERN int foreach_mountpoint(foreach_mountpoint_t handler, FAR void *arg); +int foreach_mountpoint(foreach_mountpoint_t handler, FAR void *arg); #endif /* fs_registerdriver.c ******************************************************/ @@ -384,9 +384,8 @@ EXTERN int foreach_mountpoint(foreach_mountpoint_t handler, FAR void *arg); * ****************************************************************************/ -EXTERN int register_driver(const char *path, - const struct file_operations *fops, - mode_t mode, void *priv); +int register_driver(FAR const char *path, FAR const struct file_operations *fops, + mode_t mode, FAR void *priv); /* fs_registerblockdriver.c *************************************************/ /**************************************************************************** @@ -412,9 +411,9 @@ EXTERN int register_driver(const char *path, * ****************************************************************************/ -EXTERN int register_blockdriver(const char *path, - const struct block_operations *bops, - mode_t mode, void *priv); +int register_blockdriver(FAR const char *path, + FAR const struct block_operations *bops, mode_t mode, + FAR void *priv); /* fs_unregisterdriver.c ****************************************************/ /**************************************************************************** @@ -425,7 +424,7 @@ EXTERN int register_blockdriver(const char *path, * ****************************************************************************/ -EXTERN int unregister_driver(const char *path); +int unregister_driver(const char *path); /* fs_unregisterblockdriver.c ***********************************************/ /**************************************************************************** @@ -436,7 +435,7 @@ EXTERN int unregister_driver(const char *path); * ****************************************************************************/ -EXTERN int unregister_blockdriver(const char *path); +int unregister_blockdriver(const char *path); /* fs_open.c ****************************************************************/ /**************************************************************************** @@ -447,30 +446,19 @@ EXTERN int unregister_blockdriver(const char *path); * ****************************************************************************/ -EXTERN int inode_checkflags(FAR struct inode *inode, int oflags); +int inode_checkflags(FAR struct inode *inode, int oflags); /* fs_files.c ***************************************************************/ /**************************************************************************** - * Name: files_alloclist - * - * Description: Allocate a list of files for a new task - * - ****************************************************************************/ - -#if CONFIG_NFILE_DESCRIPTORS > 0 -EXTERN FAR struct filelist *files_alloclist(void); -#endif - -/**************************************************************************** - * Name: files_addreflist + * Name: files_initlist * * Description: - * Increase the reference count on a file list + * Initializes the list of files for a new task * ****************************************************************************/ #if CONFIG_NFILE_DESCRIPTORS > 0 -EXTERN int files_addreflist(FAR struct filelist *list); +void files_initlist(FAR struct filelist *list); #endif /**************************************************************************** @@ -482,7 +470,7 @@ EXTERN int files_addreflist(FAR struct filelist *list); ****************************************************************************/ #if CONFIG_NFILE_DESCRIPTORS > 0 -EXTERN int files_releaselist(FAR struct filelist *list); +void files_releaselist(FAR struct filelist *list); #endif /**************************************************************************** @@ -495,7 +483,7 @@ EXTERN int files_releaselist(FAR struct filelist *list); ****************************************************************************/ #if CONFIG_NFILE_DESCRIPTORS > 0 -EXTERN int files_dup(FAR struct file *filep1, FAR struct file *filep2); +int files_dup(FAR struct file *filep1, FAR struct file *filep2); #endif /* fs_filedup.c *************************************************************/ @@ -515,7 +503,7 @@ EXTERN int files_dup(FAR struct file *filep1, FAR struct file *filep2); ****************************************************************************/ #if CONFIG_NFILE_DESCRIPTORS > 0 -EXTERN int file_dup(int fd, int minfd); +int file_dup(int fd, int minfd); #endif /* fs_filedup2.c ************************************************************/ @@ -535,7 +523,7 @@ EXTERN int file_dup(int fd, int minfd); #if CONFIG_NFILE_DESCRIPTORS > 0 #if defined(CONFIG_NET) && CONFIG_NSOCKET_DESCRIPTORS > 0 -EXTERN int file_dup2(int fd1, int fd2); +int file_dup2(int fd1, int fd2); #else # define file_dup2(fd1, fd2) dup2(fd1, fd2) #endif @@ -566,8 +554,8 @@ EXTERN int file_dup2(int fd1, int fd2); ****************************************************************************/ #if CONFIG_NFILE_DESCRIPTORS > 0 -EXTERN int open_blockdriver(FAR const char *pathname, int mountflags, - FAR struct inode **ppinode); +int open_blockdriver(FAR const char *pathname, int mountflags, + FAR struct inode **ppinode); #endif /* fs_closeblockdriver.c ****************************************************/ @@ -589,7 +577,7 @@ EXTERN int open_blockdriver(FAR const char *pathname, int mountflags, ****************************************************************************/ #if CONFIG_NFILE_DESCRIPTORS > 0 -EXTERN int close_blockdriver(FAR struct inode *inode); +int close_blockdriver(FAR struct inode *inode); #endif /* fs_fdopen.c **************************************************************/ @@ -609,7 +597,7 @@ typedef struct _TCB _TCB; #define __TCB_DEFINED__ #endif -EXTERN FAR struct file_struct *fs_fdopen(int fd, int oflags, FAR _TCB *tcb); +FAR struct file_struct *fs_fdopen(int fd, int oflags, FAR _TCB *tcb); #endif /* lib/stdio/lib_fflush.c **************************************************/ @@ -623,7 +611,7 @@ EXTERN FAR struct file_struct *fs_fdopen(int fd, int oflags, FAR _TCB *tcb); ****************************************************************************/ #if CONFIG_NFILE_STREAMS > 0 -EXTERN int lib_flushall(FAR struct streamlist *list); +int lib_flushall(FAR struct streamlist *list); #endif /* drivers/dev_null.c *******************************************************/ @@ -635,7 +623,7 @@ EXTERN int lib_flushall(FAR struct streamlist *list); * ****************************************************************************/ -EXTERN void devnull_register(void); +void devnull_register(void); /* drivers/dev_zero.c *******************************************************/ /**************************************************************************** @@ -646,7 +634,7 @@ EXTERN void devnull_register(void); * ****************************************************************************/ -EXTERN void devzero_register(void); +void devzero_register(void); /* drivers/loop.c ***********************************************************/ /**************************************************************************** @@ -658,8 +646,8 @@ EXTERN void devzero_register(void); * ****************************************************************************/ -EXTERN int losetup(FAR const char *devname, FAR const char *filename, - uint16_t sectsize, off_t offset, bool readonly); +int losetup(FAR const char *devname, FAR const char *filename, + uint16_t sectsize, off_t offset, bool readonly); /**************************************************************************** * Name: loteardown @@ -669,7 +657,7 @@ EXTERN int losetup(FAR const char *devname, FAR const char *filename, * ****************************************************************************/ -EXTERN int loteardown(FAR const char *devname); +int loteardown(FAR const char *devname); /* drivers/bch/bchdev_register.c ********************************************/ /**************************************************************************** @@ -681,8 +669,8 @@ EXTERN int loteardown(FAR const char *devname); * ****************************************************************************/ -EXTERN int bchdev_register(FAR const char *blkdev, FAR const char *chardev, - bool readonly); +int bchdev_register(FAR const char *blkdev, FAR const char *chardev, + bool readonly); /* drivers/bch/bchdev_unregister.c ******************************************/ /**************************************************************************** @@ -694,7 +682,7 @@ EXTERN int bchdev_register(FAR const char *blkdev, FAR const char *chardev, * ****************************************************************************/ -EXTERN int bchdev_unregister(FAR const char *chardev); +int bchdev_unregister(FAR const char *chardev); /* Low level, direct access. NOTE: low-level access and character driver access * are incompatible. One and only one access method should be implemented. @@ -710,8 +698,7 @@ EXTERN int bchdev_unregister(FAR const char *chardev); * ****************************************************************************/ -EXTERN int bchlib_setup(FAR const char *blkdev, bool readonly, - FAR void **handle); +int bchlib_setup(FAR const char *blkdev, bool readonly, FAR void **handle); /* drivers/bch/bchlib_teardown.c ********************************************/ /**************************************************************************** @@ -723,7 +710,7 @@ EXTERN int bchlib_setup(FAR const char *blkdev, bool readonly, * ****************************************************************************/ -EXTERN int bchlib_teardown(FAR void *handle); +int bchlib_teardown(FAR void *handle); /* drivers/bch/bchlib_read.c ************************************************/ /**************************************************************************** @@ -735,8 +722,8 @@ EXTERN int bchlib_teardown(FAR void *handle); * ****************************************************************************/ -EXTERN ssize_t bchlib_read(FAR void *handle, FAR char *buffer, size_t offset, - size_t len); +ssize_t bchlib_read(FAR void *handle, FAR char *buffer, size_t offset, + size_t len); /* drivers/bch/bchlib_write.c ***********************************************/ /**************************************************************************** @@ -748,8 +735,8 @@ EXTERN ssize_t bchlib_read(FAR void *handle, FAR char *buffer, size_t offset, * ****************************************************************************/ -EXTERN ssize_t bchlib_write(FAR void *handle, FAR const char *buffer, - size_t offset, size_t len); +ssize_t bchlib_write(FAR void *handle, FAR const char *buffer, size_t offset, + size_t len); #undef EXTERN #if defined(__cplusplus) diff --git a/nuttx/include/nuttx/sched.h b/nuttx/include/nuttx/sched.h index 8ebb7db4c..1580a80d3 100644 --- a/nuttx/include/nuttx/sched.h +++ b/nuttx/include/nuttx/sched.h @@ -52,6 +52,7 @@ #include #include +#include #include /******************************************************************************** @@ -63,14 +64,24 @@ #undef HAVE_TASK_GROUP #undef HAVE_GROUP_MEMBERS +/* We need a group an group members if we are supportint the parent/child + * relationship. + */ + #if defined(CONFIG_SCHED_HAVE_PARENT) && defined(CONFIG_SCHED_CHILD_STATUS) -# define HAVE_TASK_GROUP 1 -# define HAVE_GROUP_MEMBERS 1 -#endif +# define HAVE_TASK_GROUP 1 +# define HAVE_GROUP_MEMBERS 1 -#if !defined(CONFIG_DISABLE_ENVIRON) -# undef HAVE_TASK_GROUP -# define HAVE_TASK_GROUP 1 +/* We need a group (but not members) if any other resources are shared within + * a task group. + */ + +#else +# if !defined(CONFIG_DISABLE_ENVIRON) +# define HAVE_TASK_GROUP 1 +# elif CONFIG_NFILE_DESCRIPTORS > 0 +# define HAVE_TASK_GROUP 1 +# endif #endif /* In any event, we don't need group members if support for pthreads is disabled */ @@ -79,7 +90,7 @@ # undef HAVE_GROUP_MEMBERS #endif -/* Task Management Definitins ***************************************************/ +/* Task Management Definitions **************************************************/ /* This is the maximum number of times that a lock can be set */ @@ -282,16 +293,19 @@ struct task_group_s FAR char *tg_envp; /* Allocated environment strings */ #endif - /* PIC data space and address environments */ + /* PIC data space and address environments ************************************/ /* Not yet (see struct dspace_s) */ - /* File descriptors */ - /* Not yet (see struct filelist) */ + /* File descriptors ***********************************************************/ - /* FILE streams */ +#if CONFIG_NFILE_DESCRIPTORS > 0 + struct filelist tg_filelist; /* Maps file descriptor to file */ +#endif + + /* FILE streams ***************************************************************/ /* Not yet (see streamlist) */ - /* Sockets */ + /* Sockets ********************************************************************/ /* Not yet (see struct socketlist) */ }; #endif @@ -433,10 +447,6 @@ struct _TCB /* File system support ********************************************************/ -#if CONFIG_NFILE_DESCRIPTORS > 0 - FAR struct filelist *filelist; /* Maps file descriptor to file */ -#endif - #if CONFIG_NFILE_STREAMS > 0 FAR struct streamlist *streams; /* Holds C buffered I/O info */ #endif diff --git a/nuttx/sched/group_leave.c b/nuttx/sched/group_leave.c index add424185..f5dca1829 100644 --- a/nuttx/sched/group_leave.c +++ b/nuttx/sched/group_leave.c @@ -176,6 +176,13 @@ void group_leave(FAR _TCB *tcb) #if defined(CONFIG_SCHED_HAVE_PARENT) && defined(CONFIG_SCHED_CHILD_STATUS) group_removechildren(tcb->group); +#endif + /* Free all file-related resources now. We really need to close + * files as soon as possible while we still have a functioning task. + */ + +#if CONFIG_NFILE_DESCRIPTORS > 0 + (void)sched_releasefiles(tcb); #endif /* Release all shared environment variables */ @@ -231,7 +238,14 @@ void group_leave(FAR _TCB *tcb) #if defined(CONFIG_SCHED_HAVE_PARENT) && defined(CONFIG_SCHED_CHILD_STATUS) group_removechildren(tcb->group); #endif - /* Release all shared environment variables */ + /* Free all file-related resources now. We really need to close + * files as soon as possible while we still have a functioning task. + */ + +#if CONFIG_NFILE_DESCRIPTORS > 0 + (void)sched_releasefiles(tcb); +#endif + /* Release all shared environment variables */ #ifndef CONFIG_DISABLE_ENVIRON env_release(tcb); diff --git a/nuttx/sched/sched_getfiles.c b/nuttx/sched/sched_getfiles.c index 256b4cb6b..eca4ba3ff 100644 --- a/nuttx/sched/sched_getfiles.c +++ b/nuttx/sched/sched_getfiles.c @@ -70,7 +70,10 @@ FAR struct filelist *sched_getfiles(void) { FAR _TCB *rtcb = (FAR _TCB*)g_readytorun.head; - return rtcb->filelist; + FAR struct task_group_s *group = rtcb->group; + + DEBUGASSERT(group); + return &group->tg_filelist; } #endif /* CONFIG_NFILE_DESCRIPTORS */ diff --git a/nuttx/sched/sched_releasefiles.c b/nuttx/sched/sched_releasefiles.c index a3ef71af4..4be92f4eb 100644 --- a/nuttx/sched/sched_releasefiles.c +++ b/nuttx/sched/sched_releasefiles.c @@ -1,7 +1,7 @@ /**************************************************************************** * sched/sched_releasefiles.c * - * Copyright (C) 2007, 2008, 2012 Gregory Nutt. All rights reserved. + * Copyright (C) 2007, 2008, 2012-2013 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -78,13 +78,12 @@ int sched_releasefiles(_TCB *tcb) if (tcb) { #if CONFIG_NFILE_DESCRIPTORS > 0 - /* Free the file descriptor list */ + FAR struct task_group_s *group = tcb->group; + DEBUGASSERT(group); - if (tcb->filelist) - { - files_releaselist(tcb->filelist); - tcb->filelist = NULL; - } + /* Free resources used by the file descriptor list */ + + files_releaselist(&group->tg_filelist); #if CONFIG_NFILE_STREAMS > 0 /* Free the stream list */ diff --git a/nuttx/sched/sched_releasetcb.c b/nuttx/sched/sched_releasetcb.c index 00d4c2c0c..02f7170c2 100644 --- a/nuttx/sched/sched_releasetcb.c +++ b/nuttx/sched/sched_releasetcb.c @@ -163,10 +163,6 @@ int sched_releasetcb(FAR _TCB *tcb) } } - /* Release any allocated file structures */ - - ret = sched_releasefiles(tcb); - /* Release this thread's reference to the address environment */ #ifdef CONFIG_ADDRENV diff --git a/nuttx/sched/sched_setupidlefiles.c b/nuttx/sched/sched_setupidlefiles.c index ae814e1a6..4bbd4d3b7 100644 --- a/nuttx/sched/sched_setupidlefiles.c +++ b/nuttx/sched/sched_setupidlefiles.c @@ -79,18 +79,21 @@ int sched_setupidlefiles(FAR _TCB *tcb) { +#if CONFIG_NFILE_DESCRIPTORS > 0 + FAR struct task_group_s *group = tcb->group; +#endif #if CONFIG_NFILE_DESCRIPTORS > 0 && defined(CONFIG_DEV_CONSOLE) int fd; #endif - /* Allocate file descriptors for the TCB */ +#if CONFIG_NFILE_DESCRIPTORS > 0 + DEBUGASSERT(group); +#endif + + /* Initialize file descriptors for the TCB */ #if CONFIG_NFILE_DESCRIPTORS > 0 - tcb->filelist = files_alloclist(); - if (!tcb->filelist) - { - return -ENOMEM; - } + files_initlist(&group->tg_filelist); #endif /* Allocate socket descriptors for the TCB */ diff --git a/nuttx/sched/sched_setuppthreadfiles.c b/nuttx/sched/sched_setuppthreadfiles.c index 648d9273e..78d6cbfec 100644 --- a/nuttx/sched/sched_setuppthreadfiles.c +++ b/nuttx/sched/sched_setuppthreadfiles.c @@ -79,14 +79,6 @@ int sched_setuppthreadfiles(FAR _TCB *tcb) { FAR _TCB *rtcb = (FAR _TCB*)g_readytorun.head; -#if CONFIG_NFILE_DESCRIPTORS > 0 - /* The child thread inherits the parent file descriptors */ - - tcb->filelist = rtcb->filelist; - files_addreflist(tcb->filelist); - -#endif /* CONFIG_NFILE_DESCRIPTORS */ - #if CONFIG_NSOCKET_DESCRIPTORS > 0 /* The child thread inherits the parent socket descriptors */ diff --git a/nuttx/sched/sched_setuptaskfiles.c b/nuttx/sched/sched_setuptaskfiles.c index d01b8d4cd..9e44147e9 100644 --- a/nuttx/sched/sched_setuptaskfiles.c +++ b/nuttx/sched/sched_setuptaskfiles.c @@ -1,7 +1,7 @@ /**************************************************************************** * sched/sched_setuptaskfiles.c * - * Copyright (C) 2007-2008, 2010, 2012 Gregory Nutt. All rights reserved. + * Copyright (C) 2007-2008, 2010, 2012-2013 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -93,34 +93,33 @@ static inline void sched_dupfiles(FAR _TCB *tcb) FAR struct file *child; int i; + DEBUGASSERT(tcb && tcb->group && rtcb->group); + /* Duplicate the file descriptors. This will be either all of the * file descriptors or just the first three (stdin, stdout, and stderr) * if CONFIG_FDCLONE_STDIO is defined. NFSDS_TOCLONE is set * accordingly above. */ - if (rtcb->filelist) - { - /* Get pointers to the parent and child task file lists */ + /* Get pointers to the parent and child task file lists */ - parent = rtcb->filelist->fl_files; - child = tcb->filelist->fl_files; + parent = rtcb->group->tg_filelist.fl_files; + child = tcb->group->tg_filelist.fl_files; - /* Check each file in the parent file list */ + /* Check each file in the parent file list */ - for (i = 0; i < NFDS_TOCLONE; i++) - { - /* Check if this file is opened by the parent. We can tell if - * if the file is open because it contain a reference to a non-NULL - * i-node structure. - */ + for (i = 0; i < NFDS_TOCLONE; i++) + { + /* Check if this file is opened by the parent. We can tell if + * if the file is open because it contain a reference to a non-NULL + * i-node structure. + */ - if (parent[i].f_inode) - { - /* Yes... duplicate it for the child */ + if (parent[i].f_inode) + { + /* Yes... duplicate it for the child */ - (void)files_dup(&parent[i], &child[i]); - } + (void)files_dup(&parent[i], &child[i]); } } } @@ -209,14 +208,14 @@ static inline void sched_dupsockets(FAR _TCB *tcb) int sched_setuptaskfiles(FAR _TCB *tcb) { - /* Allocate file descriptors for the TCB */ - #if CONFIG_NFILE_DESCRIPTORS > 0 - tcb->filelist = files_alloclist(); - if (!tcb->filelist) - { - return -ENOMEM; - } + FAR struct task_group_s *group = tcb->group; + + DEBUGASSERT(group); + + /* Initialize file descriptors for the TCB */ + + files_initlist(&group->tg_filelist); #endif /* Allocate socket descriptors for the TCB */ diff --git a/nuttx/sched/task_exithook.c b/nuttx/sched/task_exithook.c index 3fdf08bf7..5a2b9e57e 100644 --- a/nuttx/sched/task_exithook.c +++ b/nuttx/sched/task_exithook.c @@ -177,6 +177,89 @@ static inline void task_onexit(FAR _TCB *tcb, int status) # define task_onexit(tcb,status) #endif +/**************************************************************************** + * Name: task_exitstatus + * + * Description: + * Report exit status when main task of a task group exits + * + ****************************************************************************/ + +#ifdef CONFIG_SCHED_CHILD_STATUS +static inline void task_exitstatus(FAR struct task_group_s *group, int status) +{ + FAR struct child_status_s *child; + + /* Check if the parent task group has suppressed retention of + * child exit status information. + */ + + if ((group->tg_flags & GROUP_FLAG_NOCLDWAIT) == 0) + { + /* No.. Find the exit status entry for this task in the parent TCB */ + + child = group_findchild(group, getpid()); + DEBUGASSERT(child); + if (child) + { +#ifndef HAVE_GROUP_MEMBERS + /* No group members? Save the exit status */ + + child->ch_status = status; +#endif + /* Save the exit status.. For the case of HAVE_GROUP_MEMBERS, + * the child status will be as exited until the last member + * of the task group exits. + */ + + child->ch_status = status; + } + } +} +#else + +# define task_exitstatus(group,status) + +#endif /* CONFIG_SCHED_CHILD_STATUS */ + +/**************************************************************************** + * Name: task_groupexit + * + * Description: + * Mark that the final thread of a child task group as exited. + * + ****************************************************************************/ + +#ifdef CONFIG_SCHED_CHILD_STATUS +static inline void task_groupexit(FAR struct task_group_s *group) +{ + FAR struct child_status_s *child; + + /* Check if the parent task group has suppressed retention of child exit + * status information. + */ + + if ((group->tg_flags & GROUP_FLAG_NOCLDWAIT) == 0) + { + /* No.. Find the exit status entry for this task in the parent TCB */ + + child = group_findchild(group, getpid()); + DEBUGASSERT(child); + if (child) + { + /* Mark that all members of the child task group has exit'ed */ + + child->ch_flags |= CHILD_FLAG_EXITED; + } + } +} + +#else + +# define task_groupexit(group) + +#endif /* CONFIG_SCHED_CHILD_STATUS */ + /**************************************************************************** * Name: task_sigchild * @@ -195,55 +278,41 @@ static inline void task_sigchild(gid_t pgid, FAR _TCB *ctcb, int status) DEBUGASSERT(chgrp); - /* Only the final exiting thread in a task group should generate SIGCHLD. */ + /* Get the parent task group. It is possible that all of the members of + * the parent task group have exited. This would not be an error. In + * this case, the child task group has been orphaned. + */ - if (chgrp->tg_nmembers == 1) + pgrp = group_find(chgrp->tg_pgid); + if (!pgrp) { - /* Get the parent task group */ - - pgrp = group_find(chgrp->tg_pgid); - - /* It is possible that all of the members of the parent task group - * have exited. This would not be an error. In this case, the - * child task group has been orphaned. + /* Set the task group ID to an invalid group ID. The dead parent + * task group ID could get reused some time in the future. */ - if (!pgrp) - { - /* Set the task group ID to an invalid group ID. The dead parent - * task group ID could get reused some time in the future. - */ - - chgrp->tg_pgid = INVALID_GROUP_ID; - return; - } - -#ifdef CONFIG_SCHED_CHILD_STATUS - /* Check if the parent task group has suppressed retention of child exit - * status information. Only 'tasks' report exit status, not pthreads. - * pthreads have a different mechanism. - */ - - if ((pgrp->tg_flags & GROUP_FLAG_NOCLDWAIT) == 0) - { - FAR struct child_status_s *child; + chgrp->tg_pgid = INVALID_GROUP_ID; + return; + } - /* No.. Find the exit status entry for this task in the parent TCB */ + /* Save the exit status now if this is the main thread of the task group + * that is exiting. Only the exiting main task of a task group carries + * interpretable exit Check if this is the main task that is exiting. + */ - child = group_findchild(pgrp, getpid()); - DEBUGASSERT(child); - if (child) - { - /* Mark that the child has exit'ed */ + if ((ctcb->flags & TCB_FLAG_TTYPE_MASK) == TCB_FLAG_TTYPE_TASK) + { + task_exitstatus(pgrp, status); + } - child->ch_flags |= CHILD_FLAG_EXITED; + /* But only the final exiting thread in a task group, whatever it is, + * should generate SIGCHLD. + */ - /* Save the exit status */ + if (chgrp->tg_nmembers == 1) + { + /* Mark that all of the threads in the task group have exited */ - child->ch_status = status; - } - } -#endif /* CONFIG_SCHED_CHILD_STATUS */ + task_groupexit(pgrp); /* Create the siginfo structure. We don't actually know the cause. * That is a bug. Let's just say that the child task just exit-ted @@ -278,30 +347,9 @@ static inline void task_sigchild(FAR _TCB *ptcb, FAR _TCB *ctcb, int status) if ((ctcb->flags & TCB_FLAG_TTYPE_MASK) == TCB_FLAG_TTYPE_TASK) { #ifdef CONFIG_SCHED_CHILD_STATUS - /* Check if the parent task group has suppressed retention of child exit - * status information. Only 'tasks' report exit status, not pthreads. - * pthreads have a different mechanism. - */ + /* Save the exit status now of the main thread */ - if ((ptcb->group->tg_flags & GROUP_FLAG_NOCLDWAIT) == 0) - { - FAR struct child_status_s *child; - - /* No.. Find the exit status entry for this task in the parent TCB */ - - child = group_findchild(ptcb->group, getpid()); - DEBUGASSERT(child); - if (child) - { - /* Mark that the child has exit'ed */ - - child->ch_flags |= CHILD_FLAG_EXITED; - - /* Save the exit status */ - - child->ch_status = status; - } - } + task_exitstatus(ptcb->group, status); #else /* CONFIG_SCHED_CHILD_STATUS */ @@ -506,14 +554,6 @@ void task_exithook(FAR _TCB *tcb, int status) group_leave(tcb); #endif - /* Free all file-related resources now. This gets called again - * just be be certain when the TCB is delallocated. However, we - * really need to close files as soon as possible while we still - * have a functioning task. - */ - - (void)sched_releasefiles(tcb); - /* Deallocate anything left in the TCB's queues */ #ifndef CONFIG_DISABLE_SIGNALS -- cgit v1.2.3