summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2007-03-09 15:27:47 +0000
committerpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2007-03-09 15:27:47 +0000
commitcb4bc1a2f49306879ecee08f0644300f0037d92c (patch)
treec299739a5089f9fb3cbc902726f66fdc7a9c708a
parent3551ee48a7f52425e953d4a3ea7bc2fd3b2a62ff (diff)
downloadnuttx-cb4bc1a2f49306879ecee08f0644300f0037d92c.tar.gz
nuttx-cb4bc1a2f49306879ecee08f0644300f0037d92c.tar.bz2
nuttx-cb4bc1a2f49306879ecee08f0644300f0037d92c.zip
Debug instrumentation
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@47 42af7a65-404d-4744-a932-0658087f49c3
-rw-r--r--nuttx/arch/c5471/src/up_exit.c60
-rw-r--r--nuttx/arch/c5471/src/up_internal.h1
-rw-r--r--nuttx/include/sched.h12
-rw-r--r--nuttx/include/stdio.h1
-rw-r--r--nuttx/lib/lib_fflush.c7
-rw-r--r--nuttx/lib/lib_init.c2
-rw-r--r--nuttx/sched/Makefile2
-rw-r--r--nuttx/sched/pthread_exit.c2
-rw-r--r--nuttx/sched/sched_foreach.c84
9 files changed, 168 insertions, 3 deletions
diff --git a/nuttx/arch/c5471/src/up_exit.c b/nuttx/arch/c5471/src/up_exit.c
index 8e211e0c2..606ea097b 100644
--- a/nuttx/arch/c5471/src/up_exit.c
+++ b/nuttx/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
************************************************************/
@@ -58,6 +62,57 @@
************************************************************/
/************************************************************
+ * 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/nuttx/arch/c5471/src/up_internal.h b/nuttx/arch/c5471/src/up_internal.h
index ef08d36a7..6f6f82c83 100644
--- a/nuttx/arch/c5471/src/up_internal.h
+++ b/nuttx/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/nuttx/include/sched.h b/nuttx/include/sched.h
index 0cf8d58d5..12cc29046 100644
--- a/nuttx/include/sched.h
+++ b/nuttx/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/nuttx/include/stdio.h b/nuttx/include/stdio.h
index 8b9a7e28e..f234a861c 100644
--- a/nuttx/include/stdio.h
+++ b/nuttx/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/nuttx/lib/lib_fflush.c b/nuttx/lib/lib_fflush.c
index d0f74bd2b..e7f4e6960 100644
--- a/nuttx/lib/lib_fflush.c
+++ b/nuttx/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/nuttx/lib/lib_init.c b/nuttx/lib/lib_init.c
index 90ccc358b..d6eb5f0a4 100644
--- a/nuttx/lib/lib_init.c
+++ b/nuttx/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/nuttx/sched/Makefile b/nuttx/sched/Makefile
index d110cb664..375cb6a3d 100644
--- a/nuttx/sched/Makefile
+++ b/nuttx/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/nuttx/sched/pthread_exit.c b/nuttx/sched/pthread_exit.c
index cd0833ba6..087076ac3 100644
--- a/nuttx/sched/pthread_exit.c
+++ b/nuttx/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/nuttx/sched/sched_foreach.c b/nuttx/sched/sched_foreach.c
new file mode 100644
index 000000000..f1c1dc05c
--- /dev/null
+++ b/nuttx/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);
+}
+
+