summaryrefslogtreecommitdiffstats
path: root/src/H5CS.c
diff options
context:
space:
mode:
authorQuincey Koziol <koziol@hdfgroup.org>2015-09-14 03:58:59 (GMT)
committerQuincey Koziol <koziol@hdfgroup.org>2015-09-14 03:58:59 (GMT)
commit102337449220dfc29be1cce29147704b9c760832 (patch)
tree2f57d117f2bd934eac2768be18dcc866619f390f /src/H5CS.c
parentf16361d5f1dc70c344d8143270aa4aeaa867f244 (diff)
downloadhdf5-102337449220dfc29be1cce29147704b9c760832.zip
hdf5-102337449220dfc29be1cce29147704b9c760832.tar.gz
hdf5-102337449220dfc29be1cce29147704b9c760832.tar.bz2
[svn-r27768] Description:
Complete revamp of package initialization/shutdown mechanism in the library. Each package now has a single init/term routine. This new way should avoid packages being re-initialized during library shutdown and is also be _much_ more proactive about giving feedback for resource leaks internal to the library. Introduces a new "module" header file for packages in the library (e.g src/H5Fmodule.h) which sets up some necessary package configuration macros for the FUNC_ENTER/LEAVE macros. (The VFL drivers have their own slightly modified version of this header, src/H5FDdrvr_module.h) Also cleaned up a bunch of resources leaks all across the library and tests, along with addressing many warnings, as I encountered them. Tested on: MacOSX/64 10.10.5 (amazon) w/serial & parallel Linux/64 3.10.x (kituo) w/serial & parallel Linux/64 2.6.x (ostrich) w/serial
Diffstat (limited to 'src/H5CS.c')
-rw-r--r--src/H5CS.c167
1 files changed, 85 insertions, 82 deletions
diff --git a/src/H5CS.c b/src/H5CS.c
index 29182ce..f1d3a8b 100644
--- a/src/H5CS.c
+++ b/src/H5CS.c
@@ -30,10 +30,19 @@
#include "H5private.h" /* Generic Functions */
#include "H5CSprivate.h" /* Function stack */
-#include "H5MMprivate.h" /* Memory management */
+#include "H5Eprivate.h" /* Error handling */
#ifdef H5_HAVE_CODESTACK
+#define H5CS_MIN_NSLOTS 16 /* Minimum number of records in an function stack */
+
+/* A function stack */
+typedef struct H5CS_t {
+ unsigned nused; /* Number of records currently used in stack */
+ unsigned nalloc; /* Number of records current allocated for stack */
+ const char **rec; /* Array of function records */
+} H5CS_t;
+
#ifdef H5_HAVE_THREADSAFE
/*
* The per-thread function stack. pthread_once() initializes a special
@@ -44,8 +53,8 @@
* In order for this macro to work, H5CS_get_my_stack() must be preceeded
* by "H5CS_t *fstack =".
*/
-static H5CS_t *H5CS_get_stack(void);
-#define H5CS_get_my_stack() H5CS_get_stack()
+static H5CS_t *H5CS__get_stack(void);
+#define H5CS_get_my_stack() H5CS__get_stack()
#else /* H5_HAVE_THREADSAFE */
/*
* The function stack. Eventually we'll have some sort of global table so each
@@ -58,7 +67,7 @@ H5CS_t H5CS_stack_g[1];
#ifdef H5_HAVE_THREADSAFE
/*-------------------------------------------------------------------------
- * Function: H5CS_get_stack
+ * Function: H5CS__get_stack
*
* Purpose: Support function for H5CS_get_my_stack() to initialize and
* acquire per-thread function stack.
@@ -70,19 +79,17 @@ H5CS_t H5CS_stack_g[1];
* Programmer: Quincey Koziol
* February 6, 2003
*
- * Modifications:
- *
*-------------------------------------------------------------------------
*/
static H5CS_t *
-H5CS_get_stack(void)
+H5CS__get_stack(void)
{
H5CS_t *fstack;
- FUNC_ENTER_NOAPI_NOERR_NOFS
+ FUNC_ENTER_STATIC_NOERR_NOFS
fstack = H5TS_get_thread_local_value(H5TS_funcstk_key_g);
- if (!fstack) {
+ if(!fstack) {
/* No associated value with current thread - create one */
#ifdef H5_HAVE_WIN_THREADS
fstack = (H5CS_t *)LocalAlloc(LPTR, sizeof(H5CS_t)); /* Win32 has to use LocalAlloc to match the LocalFree in DllMain */
@@ -92,17 +99,19 @@ H5CS_get_stack(void)
HDassert(fstack);
/* Set the thread-specific info */
- fstack->nused=0;
+ fstack->nused = 0;
+ fstack->nalloc = 0;
+ fstack->rec = NULL;
/* (It's not necessary to release this in this API, it is
* released by the "key destructor" set up in the H5TS
* routines. See calls to pthread_key_create() in H5TS.c -QAK)
*/
H5TS_set_thread_local_value(H5TS_funcstk_key_g, (void *)fstack);
- }
+ } /* end if */
- FUNC_LEAVE_NOAPI_NOFS(fstack);
-} /* end H5CS_get_stack() */
+ FUNC_LEAVE_NOAPI_NOFS(fstack)
+} /* end H5CS__get_stack() */
#endif /* H5_HAVE_THREADSAFE */
@@ -133,59 +142,28 @@ H5CS_print_stack(const H5CS_t *fstack, FILE *stream)
HDassert(fstack);
/* Default to outputting information to stderr */
- if (!stream)
+ if(!stream)
stream = stderr;
- HDfprintf (stream, "HDF5-DIAG: Function stack from %s ", H5_lib_vers_info_g);
+ 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 %lu.", HDpthread_self_ulong());
+ HDfprintf(stream, "thread %lu.", HDpthread_self_ulong());
#else /* H5_HAVE_THREADSAFE */
- HDfprintf (stream, "thread 0.");
+ HDfprintf(stream, "thread 0.");
#endif /* H5_HAVE_THREADSAFE */
- if (fstack && fstack->nused>0)
- HDfprintf (stream, " Back trace follows.");
- HDfputc ('\n', stream);
+ 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]);
+ for(i = fstack->nused - 1; i >= 0; --i)
+ HDfprintf(stream, "%*s#%03d: Routine: %s\n", indent, "", i, fstack->rec[i]);
- FUNC_LEAVE_NOAPI_NOFS(SUCCEED);
+ FUNC_LEAVE_NOAPI_NOFS(SUCCEED)
} /* end H5CS_print_stack() */
/*-------------------------------------------------------------------------
- * Function: H5CS_print
- *
- * Purpose: Prints the default function stack in some default way.
- *
- * Return: Non-negative on success/Negative on failure
- *
- * Programmer: Quincey Koziol
- * Thursday, February 6, 2003
- *
- * Modifications:
- *
- *-------------------------------------------------------------------------
- */
-herr_t
-H5CS_print(FILE *stream)
-{
- H5CS_t *fstack = H5CS_get_my_stack (); /* Get the correct function stack */
-
- /* Don't push this function on the function stack... :-) */
- FUNC_ENTER_NOAPI_NOERR_NOFS
-
- /* Sanity check */
- HDassert(fstack);
-
- H5CS_print_stack(fstack, stream);
-
- FUNC_LEAVE_NOAPI_NOFS(SUCCEED);
-} /* end H5CS_print() */
-
-
-/*-------------------------------------------------------------------------
* Function: H5CS_push
*
* Purpose: Pushes a new record onto function stack for the current
@@ -196,30 +174,37 @@ H5CS_print(FILE *stream)
* Programmer: Quincey Koziol
* Thursday, February 6, 2003
*
- * Modifications:
- *
*-------------------------------------------------------------------------
*/
herr_t
H5CS_push(const char *func_name)
{
- H5CS_t *fstack = H5CS_get_my_stack ();
+ H5CS_t *fstack = H5CS_get_my_stack(); /* Current function stack for library */
/* Don't push this function on the function stack... :-) */
FUNC_ENTER_NOAPI_NOERR_NOFS
/* Sanity check */
HDassert(fstack);
+ HDassert(fstack->nused <= fstack->nalloc);
HDassert(func_name);
- /*
- * Push the function if there's room. Otherwise just increment count
- */
- if (fstack->nused<H5CS_NSLOTS)
- fstack->slot[fstack->nused] = func_name;
+ /* Check if we need to expand the stack of records */
+ if(fstack->nused == fstack->nalloc) {
+ size_t na = MAX((fstack->nalloc * 2), H5CS_MIN_NSLOTS);
+ const char **x = (const char **)HDrealloc(fstack->rec, na * sizeof(const char *));
+
+ /* (Avoid returning an error from this routine, currently -QAK) */
+ HDassert(x);
+ fstack->rec = x;
+ fstack->nalloc = na;
+ } /* end if */
+
+ /* Push the function name */
+ fstack->rec[fstack->nused] = func_name;
fstack->nused++;
- FUNC_LEAVE_NOAPI_NOFS(SUCCEED);
+ FUNC_LEAVE_NOAPI_NOFS(SUCCEED)
} /* end H5CS_push() */
@@ -240,14 +225,14 @@ H5CS_push(const char *func_name)
herr_t
H5CS_pop(void)
{
- H5CS_t *fstack = H5CS_get_my_stack ();
+ H5CS_t *fstack = H5CS_get_my_stack();
/* Don't push this function on the function stack... :-) */
FUNC_ENTER_NOAPI_NOERR_NOFS
/* Sanity check */
HDassert(fstack);
- HDassert(fstack->nused>0);
+ HDassert(fstack->nused > 0);
/* Pop the function. */
fstack->nused--;
@@ -266,43 +251,52 @@ H5CS_pop(void)
* Programmer: Quincey Koziol
* Tuesday, August 9, 2005
*
- * Modifications:
- *
*-------------------------------------------------------------------------
*/
-herr_t
-H5CS_copy_stack(H5CS_t *new_stack)
+H5CS_t *
+H5CS_copy_stack(void)
{
- H5CS_t *old_stack = H5CS_get_my_stack ();
+ H5CS_t *old_stack = H5CS_get_my_stack(); /* Existing function stack for library */
+ H5CS_t *new_stack; /* New function stack, for copy */
unsigned u; /* Local index variable */
+ H5CS_t *ret_value = NULL; /* Return value */
/* Don't push this function on the function stack... :-) */
- FUNC_ENTER_NOAPI_NOERR_NOFS
+ FUNC_ENTER_NOAPI_NOFS
/* Sanity check */
HDassert(old_stack);
+ /* Allocate a new stack */
+ /* (Don't use library allocate code, since this code stack supports it) */
+ if(NULL == (new_stack = HDcalloc(1, sizeof(H5CS_t))))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, NULL, "can't allocate function stack")
+ if(NULL == (new_stack->rec = HDcalloc(old_stack->nused, sizeof(const char *))))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, NULL, "can't allocate function stack records")
+
/* Copy old stack to new one, duplicating the strings */
for(u = 0; u < old_stack->nused; u++)
- new_stack->slot[u] = H5MM_strdup(old_stack->slot[u]);
- new_stack->nused = old_stack->nused;
+ new_stack->rec[u] = HDstrdup(old_stack->rec[u]);
+ new_stack->nused = new_stack->nalloc = old_stack->nused;
- FUNC_LEAVE_NOAPI_NOFS(SUCCEED);
+ /* Set the return value */
+ ret_value = new_stack;
+
+done:
+ FUNC_LEAVE_NOAPI_NOFS(ret_value)
} /* end H5CS_copy_stack() */
/*-------------------------------------------------------------------------
* Function: H5CS_close_stack
*
- * Purpose: Closes a copy of a stack
+ * Purpose: Closes and frees a copy of a stack
*
* Return: Non-negative on success/Negative on failure
*
* Programmer: Quincey Koziol
* Tuesday, August 9, 2005
*
- * Modifications:
- *
*-------------------------------------------------------------------------
*/
herr_t
@@ -316,11 +310,20 @@ H5CS_close_stack(H5CS_t *stack)
/* Sanity check */
HDassert(stack);
- /* Free strings on stack */
- for(u = 0; u < stack->nused; u++)
- stack->slot[u] = H5MM_xfree((void *)stack->slot[u]);
-
- FUNC_LEAVE_NOAPI_NOFS(SUCCEED);
+ /* Free stack */
+ for(u = 0; u < stack->nused; u++) {
+ if(stack->rec[u])
+ HDfree((void *)stack->rec[u]);
+ stack->rec[u] = NULL;
+ } /* end for */
+ if(stack->rec) {
+ HDfree(stack->rec);
+ stack->rec = NULL;
+ } /* end if */
+ if(stack)
+ HDfree(stack);
+
+ FUNC_LEAVE_NOAPI_NOFS(SUCCEED)
} /* end H5CS_close_stack() */
#endif /* H5_HAVE_CODESTACK */