diff --git a/arch/c5471/src/up_exit.c b/arch/c5471/src/up_exit.c
index 8e211e0c2e948a9b4704cd670c89c7d8f6775485..606ea097b5ca7281cd74f8e32c94bfdaffdfd057 100644
--- a/arch/c5471/src/up_exit.c
+++ b/arch/c5471/src/up_exit.c
@@ -45,6 +45,10 @@
 #include "os_internal.h"
 #include "up_internal.h"
 
+#ifdef CONFIG_DUMP_ON_EXIT
+#include <nuttx/fs.h>
+#endif
+
 /************************************************************
  * Private Definitions
  ************************************************************/
@@ -57,6 +61,57 @@
  * Private Funtions
  ************************************************************/
 
+/************************************************************
+ * Name: _up_dumponexit
+ *
+ * Description:
+ *   Dump the state of all tasks whenever on task exits.  This
+ *   is debug instrumentation that was added to check file-
+ *   related reference counting but could be useful again
+ *   sometime in the future.
+ *
+ ************************************************************/
+
+#if defined(CONFIG_DUMP_ON_EXIT) && defined(CONFIG_DEBUG)
+static void _up_dumponexit(FAR _TCB *tcb, FAR void *arg)
+{
+  int i;
+  dbg("  TCB=%p name=%s\n", tcb, tcb->name);
+  if (tcb->filelist)
+    {
+      dbg("    filelist refcount=%d\n",
+          tcb->filelist->fl_crefs);
+
+      for (i = 0; i < CONFIG_NFILE_DESCRIPTORS; i++)
+        {
+          struct inode *inode = tcb->filelist->fl_files[i].f_inode;
+          if (inode)
+            {
+              dbg("      fd=%d refcount=%d\n",
+                  i, inode->i_crefs);
+            }
+        }
+    }
+
+  if (tcb->streams)
+    {
+      dbg("    streamlist refcount=%d\n",
+          tcb->streams->sl_crefs);
+
+      for (i = 0; i < CONFIG_NFILE_STREAMS; i++)
+        {
+          struct file_struct *filep = &tcb->streams->sl_streams[i];
+          if (filep->fs_filedes >= 0)
+            {
+              dbg("      fd=%d nbytes=%d\n",
+                  filep->fs_filedes,
+                  filep->fs_bufpos - filep->fs_bufstart);
+            }
+        }
+    }
+}
+#endif
+
 /************************************************************
  * Public Funtions
  ************************************************************/
@@ -76,6 +131,11 @@ void _exit(int status)
 
   dbg("TCB=%p exitting\n", tcb);
 
+#if defined(CONFIG_DUMP_ON_EXIT) && defined(CONFIG_DEBUG)
+  dbg("Other tasks:\n");
+  sched_foreach(_up_dumponexit, NULL);
+#endif
+
   /* Remove the tcb task from the ready-to-run list.  We can
    * ignore the return value because we know that a context
    * switch is needed.
diff --git a/arch/c5471/src/up_internal.h b/arch/c5471/src/up_internal.h
index ef08d36a7f54612bbec419cc75a4d3013e8f7dc0..6f6f82c835403a805aae9ce5f4975ebb3145c9d5 100644
--- a/arch/c5471/src/up_internal.h
+++ b/arch/c5471/src/up_internal.h
@@ -53,6 +53,7 @@
 #undef  CONFIG_SUPPRESS_TIMER_INTS    /* No timer */
 #define CONFIG_SUPPRESS_SERIAL_INTS 1 /* Console will poll */
 #undef  CONFIG_SUPPRESS_UART_CONFIG   /* Do not reconfig UART */
+#undef  CONFIG_DUMP_ON_EXIT           /* Dumpt task state on exit */
 
 /* LED definitions */
 
diff --git a/include/sched.h b/include/sched.h
index 0cf8d58d551f4b2af22f339ba26ced5329fe5d96..12cc290467a8399b3999f46ea9a940f9907d2643 100644
--- a/include/sched.h
+++ b/include/sched.h
@@ -254,6 +254,11 @@ struct _TCB
 
 };
 typedef struct _TCB _TCB;
+
+/* This is the callback type used by sched_foreach() */
+
+typedef void (sched_foreach_t)(FAR _TCB *tcb, FAR void *arg);
+
 #endif /* __ASSEMBLY__ */
 
 /************************************************************
@@ -341,6 +346,13 @@ EXTERN FAR struct streamlist *sched_getstreams(void);
 #endif /* CONFIG_NFILE_STREAMS */
 #endif /* CONFIG_NFILE_DESCRIPTORS */
 
+/* sched_foreach will enumerate over each task and provide the
+ * TCB of each task to a user callback functions.  Interrupts
+ * will be disabled throughout this enumeration!
+ */
+
+EXTERN void sched_foreach(sched_foreach_t handler, FAR void *arg);
+
 #undef EXTERN
 #if defined(__cplusplus)
 }
diff --git a/include/stdio.h b/include/stdio.h
index 8b9a7e28e4741bb246c1781d5cfb44b6a5eca1e3..f234a861c2ad7ccaa1952550ab4b7564fea7c6e4 100644
--- a/include/stdio.h
+++ b/include/stdio.h
@@ -131,6 +131,7 @@ struct _dirent
 {
   FAR char *d_name;           /* name of directory entry */
 };
+
 struct dirent
 {
   FAR char *d_name;           /* A pointer to d_szname */
diff --git a/lib/lib_fflush.c b/lib/lib_fflush.c
index d0f74bd2b1112172fdbbb1cd7ea5f694341958a6..e7f4e69609796348635d800a67a4ff29a0454af4 100644
--- a/lib/lib_fflush.c
+++ b/lib/lib_fflush.c
@@ -91,6 +91,7 @@
 void lib_flushall(FAR struct streamlist *list)
 {
   /* Make sure that there are streams associated with this thread */
+
   if (list)
     {
        int i;
@@ -131,6 +132,10 @@ int fflush(FILE *stream)
       return ERROR;
     }
 
+  /* Make sure that we have exclusive access to the stream */
+
+  lib_take_semaphore(stream);
+
   /* How many bytes are used in the buffer now */
 
   nbuffer = stream->fs_bufpos - stream->fs_bufstart;
@@ -141,6 +146,7 @@ int fflush(FILE *stream)
   bytes_written = write(stream->fs_filedes, src, nbuffer);
   if (bytes_written < 0)
     {
+      lib_give_semaphore(stream);
       return bytes_written;
     }
 
@@ -166,6 +172,7 @@ int fflush(FILE *stream)
 
   /* Return the number of bytes remaining in the buffer */
 
+  lib_give_semaphore(stream);
   return stream->fs_bufpos - stream->fs_bufstart;
 #else
   return 0;
diff --git a/lib/lib_init.c b/lib/lib_init.c
index 90ccc358b8f1e3a8bc8afa73706da6b4d4cb0ebc..d6eb5f0a4887640fff28c14db62a60bd40145ca8 100644
--- a/lib/lib_init.c
+++ b/lib/lib_init.c
@@ -166,7 +166,7 @@ void lib_releaselist(FAR struct streamlist *list)
        /* Decrement the reference count */
 
        _lib_semtake(list);
-       crefs = --list->sl_crefs;
+       crefs = --(list->sl_crefs);
        _lib_semgive(list);
 
        /* If the count decrements to zero, then there is no reference
diff --git a/sched/Makefile b/sched/Makefile
index d110cb664ae18b28efa620a0b1fe346511e6d4b1..375cb6a3d6e48e4b0809b89f2117f28cc1017626 100644
--- a/sched/Makefile
+++ b/sched/Makefile
@@ -51,7 +51,7 @@ TSK_SRCS	= task_create.c task_init.c task_delete.c task_restart.c \
 		  sched_free.c sched_gettcb.c sched_releasetcb.c
 SCHED_SRCS	= sched_setparam.c sched_getparam.c \
 		  sched_setscheduler.c sched_getscheduler.c \
-		  sched_yield.c sched_rrgetinterval.c \
+		  sched_yield.c sched_rrgetinterval.c sched_foreach.c \
 		  sched_getprioritymax.c sched_getprioritymin.c \
 		  sched_lock.c sched_unlock.c sched_lockcount.c
 WDOG_SRCS	= wd_initialize.c wd_create.c wd_start.c wd_cancel.c wd_delete.c
diff --git a/sched/pthread_exit.c b/sched/pthread_exit.c
index cd0833ba626a1cf5d32639e7caa0eab198a3cdc1..087076ac3d795fe9f906646d2bc06731fac06525 100644
--- a/sched/pthread_exit.c
+++ b/sched/pthread_exit.c
@@ -112,7 +112,7 @@ void pthread_exit(FAR void *exit_value)
     }
 
   /* Then just exit, retaining all file descriptors and without
-   * calling atexit() funcitons.
+   * calling atexit() functions.
    */
 
   _exit(error_code);
diff --git a/sched/sched_foreach.c b/sched/sched_foreach.c
new file mode 100644
index 0000000000000000000000000000000000000000..f1c1dc05c003e4307cb24c1149090a887ff37259
--- /dev/null
+++ b/sched/sched_foreach.c
@@ -0,0 +1,84 @@
+/************************************************************
+ * sched_foreach.c
+ *
+ *   Copyright (C) 2007 Gregory Nutt. All rights reserved.
+ *   Author: Gregory Nutt <spudmonkey@racsa.co.cr>
+ *
+ * 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 Gregory Nutt 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 <sched.h>
+#include "os_internal.h"
+
+/************************************************************
+ * Global Functions
+ ************************************************************/
+
+/************************************************************
+ * Function:  sched_foreach
+ *
+ * Description:
+ *   Enumerate over each task and provide the TCB of each
+ *   task to a user callback functions.  Interrupts will be
+ *   disabled throughout this enumeration!
+ *
+ * Parameters:
+ *   handler - The function to be called with the TCB of
+ *     each task
+ *
+ * Return Value:
+ *   None
+ *
+ * Assumptions:
+ *
+ ************************************************************/
+
+void sched_foreach(sched_foreach_t handler, FAR void *arg)
+{
+  FAR _TCB *tcb;
+  irqstate_t flags = irqsave();
+  int ndx;
+
+  /* Verify that the PID is within range */
+
+  for (ndx = 0; ndx < CONFIG_MAX_TASKS; ndx++)
+    {
+       if (g_pidhash[ndx].tcb)
+         {
+           handler(g_pidhash[ndx].tcb, arg);
+         }
+    }
+  irqrestore(flags);
+}
+
+