summaryrefslogtreecommitdiffstats
path: root/src/H5CS.c
diff options
context:
space:
mode:
authorQuincey Koziol <koziol@hdfgroup.org>2003-02-07 21:14:19 (GMT)
committerQuincey Koziol <koziol@hdfgroup.org>2003-02-07 21:14:19 (GMT)
commit168d67dbd20923feef30fb76c6b569ef2e5add4a (patch)
tree2bcfd51c39665400804e92ac0fb13d42b2df96c3 /src/H5CS.c
parent4e8da9d2246a0bba1afb5c678346b2f1c4633c69 (diff)
downloadhdf5-168d67dbd20923feef30fb76c6b569ef2e5add4a.zip
hdf5-168d67dbd20923feef30fb76c6b569ef2e5add4a.tar.gz
hdf5-168d67dbd20923feef30fb76c6b569ef2e5add4a.tar.bz2
[svn-r6383] Purpose:
New feature for developers. Description: Added "function stack" tracing to library. This allows developers (there is no public API) to call H5FS_print within the library and get a listing of the functions traversed to reach that point in the library. Eventually, I may add support for reporting the parameters to each function also... Mainly for debugging parallel I/O programs, but I think it will come in handy in other cases also. The function stack tracking is controlled with a configure switch: --enable-funcstack, which defaults to enabled currently. When we branch for 1.6, we should change the default setting on the branch to be disabled. Also, added a destructor to the thread-specific keys when thread-safety is turned on in the library. Otherwise, they were leaking memory and causing difficult to debug errors in threaded programs (like the test/ttsafe test). Platforms tested: Tested h5committest {arabica (fortran), eirene (fortran, C++) modi4 (parallel, fortran)} FreeBSD 4.7 (sleipnir) w/thread-safety enabled. Misc. update: Updated MANIFEST with new files added (src/H5FS.c & src/H5FDprivate.h) Update release_docs/RELEASE with thread-safety bug fix.
Diffstat (limited to 'src/H5CS.c')
-rw-r--r--src/H5CS.c223
1 files changed, 223 insertions, 0 deletions
diff --git a/src/H5CS.c b/src/H5CS.c
new file mode 100644
index 0000000..b523251
--- /dev/null
+++ b/src/H5CS.c
@@ -0,0 +1,223 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * Copyright by the Board of Trustees of the University of Illinois. *
+ * All rights reserved. *
+ * *
+ * This file is part of HDF5. The full HDF5 copyright notice, including *
+ * terms governing use, modification, and redistribution, is contained in *
+ * the files COPYING and Copyright.html. COPYING can be found at the root *
+ * of the source code distribution tree; Copyright.html can be found at the *
+ * root level of an installed copy of the electronic HDF5 document set and *
+ * is linked from the top-level documents page. It can also be found at *
+ * http://hdf.ncsa.uiuc.edu/HDF5/doc/Copyright.html. If you do not have *
+ * access to either file, you may request a copy from hdfhelp@ncsa.uiuc.edu. *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+/*
+ * Purpose: Provides internal function tracing in the form of a stack.
+ * The FUNC_ENTER() macro adds the function name to the function
+ * stack whenever a function is entered.
+ * As the functions return with FUNC_LEAVE,
+ * entries are removed from the stack.
+ *
+ * A function stack has a fixed maximum size. If this size is
+ * exceeded then the stack will be truncated and only the
+ * first called functions will have entries on the stack. This is
+ * expected to be a rare condition.
+ *
+ * Each thread has its own function stack, but since
+ * multi-threading has not been added to the library yet, this
+ * package maintains a single function stack. The function stack
+ * is statically allocated to reduce the complexity of handling
+ * errors within the H5FS package.
+ *
+ */
+#include "H5private.h" /* Generic Functions */
+#include "H5FSprivate.h" /* Private function stack routines */
+#include "H5MMprivate.h" /* Memory management functions */
+
+#ifdef H5_HAVE_FUNCSTACK
+
+#define PABLO_MASK H5FS_mask
+
+/* Interface initialization? */
+#define INTERFACE_INIT NULL
+
+#ifdef H5_HAVE_THREADSAFE
+/*
+ * The per-thread function stack. pthread_once() initializes a special
+ * key that will be used by all threads to create a stack specific to
+ * each thread individually. The association of stacks to threads will
+ * be handled by the pthread library.
+ *
+ * In order for this macro to work, H5FS_get_my_stack() must be preceeded
+ * by "H5FS_t *fstack =".
+ */
+static H5FS_t *H5FS_get_stack(void);
+#define H5FS_get_my_stack() H5FS_get_stack()
+#else /* H5_HAVE_THREADSAFE */
+/*
+ * The function stack. Eventually we'll have some sort of global table so each
+ * thread has it's own stack. The stacks will be created on demand when the
+ * thread first calls H5FS_push(). */
+H5FS_t H5FS_stack_g[1];
+#define H5FS_get_my_stack() (H5FS_stack_g+0)
+#endif /* H5_HAVE_THREADSAFE */
+
+
+#ifdef H5_HAVE_THREADSAFE
+/*-------------------------------------------------------------------------
+ * Function: H5FS_get_stack
+ *
+ * Purpose: Support function for H5FS_get_my_stack() to initialize and
+ * acquire per-thread function stack.
+ *
+ * Return: Success: function stack (H5FS_t *)
+ *
+ * Failure: NULL
+ *
+ * Programmer: Quincey Koziol
+ * February 6, 2003
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static H5FS_t *
+H5FS_get_stack(void)
+{
+ H5FS_t *fstack;
+
+ FUNC_ENTER_NOAPI_NOFS(H5FS_get_stack);
+
+ fstack = pthread_getspecific(H5TS_funcstk_key_g);
+ if (!fstack) {
+ /* no associated value with current thread - create one */
+ fstack = (H5FS_t *)H5MM_malloc(sizeof(H5FS_t));
+ pthread_setspecific(H5TS_funcstk_key_g, (void *)fstack);
+ }
+
+ FUNC_LEAVE_NOAPI_NOFS(fstack);
+} /* end H5FS_get_stack() */
+#endif /* H5_HAVE_THREADSAFE */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5FS_print
+ *
+ * Purpose: Prints the function stack in some default way.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * THursday, February 6, 2003
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5FS_print(FILE *stream)
+{
+ H5FS_t *fstack = H5FS_get_my_stack (); /* Get the correct function stack */
+ const int indent = 2; /* Indention level */
+ int i; /* Local index ariable */
+
+ /* Don't push this function on the function stack... :-) */
+ FUNC_ENTER_NOAPI_NOFS(H5FS_print);
+
+ /* Sanity check */
+ assert(fstack);
+
+ /* Default to outputting information to stderr */
+ if (!stream)
+ stream = stderr;
+
+ HDfprintf (stream, "HDF5-DIAG: Function stack from %s ", H5_lib_vers_info_g);
+ /* try show the process or thread id in multiple processes cases*/
+#ifdef H5_HAVE_THREADSAFE
+ HDfprintf (stream, "thread %d.", (int)pthread_self());
+#else /* H5_HAVE_THREADSAFE */
+ HDfprintf (stream, "thread 0.");
+#endif /* H5_HAVE_THREADSAFE */
+ if (fstack && fstack->nused>0)
+ HDfprintf (stream, " Back trace follows.");
+ HDfputc ('\n', stream);
+
+ for (i=fstack->nused-1; i>=0; --i)
+ HDfprintf(stream, "%*s#%03d: Routine: %s\n", indent, "", i, fstack->slot[i]);
+
+ FUNC_LEAVE_NOAPI_NOFS(SUCCEED);
+} /* end H5FS_print() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5FS_push
+ *
+ * Purpose: Pushes a new record onto function stack for the current
+ * thread.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * Thursday, February 6, 2003
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5FS_push(const char *func_name)
+{
+ H5FS_t *fstack = H5FS_get_my_stack ();
+
+ /* Don't push this function on the function stack... :-) */
+ FUNC_ENTER_NOAPI_NOFS(H5FS_push);
+
+ /* Sanity check */
+ assert (fstack);
+ assert (func_name);
+
+ /*
+ * Push the function if there's room. Otherwise just increment count
+ */
+ if (fstack->nused<H5FS_NSLOTS)
+ fstack->slot[fstack->nused] = func_name;
+ fstack->nused++;
+
+ FUNC_LEAVE_NOAPI_NOFS(SUCCEED);
+} /* end H5FS_push() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5FS_pop
+ *
+ * Purpose: Pops a record off function stack for the current thread.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * Thursday, February 6, 2003
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5FS_pop(void)
+{
+ H5FS_t *fstack = H5FS_get_my_stack ();
+
+ /* Don't push this function on the function stack... :-) */
+ FUNC_ENTER_NOAPI_NOFS(H5FS_pop);
+
+ /* Sanity check */
+ assert (fstack);
+ assert (fstack->nused>0);
+
+ /* Pop the function. */
+ fstack->nused--;
+
+ FUNC_LEAVE_NOAPI_NOFS(SUCCEED);
+} /* end H5FS_pop() */
+
+#endif /* H5_HAVE_FUNCSTACK */