summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/H5.c10
-rw-r--r--src/H5CS.c10
-rw-r--r--src/H5E.c8
-rw-r--r--src/H5FS.c10
-rw-r--r--src/H5TS.c36
-rw-r--r--src/H5TSprivate.h3
-rw-r--r--src/H5private.h24
7 files changed, 67 insertions, 34 deletions
diff --git a/src/H5.c b/src/H5.c
index 3fda450..08feddc 100644
--- a/src/H5.c
+++ b/src/H5.c
@@ -720,16 +720,16 @@ herr_t
H5close(void)
{
/*
- * Don't call FUNC_ENTER() since we don't want to initialize the whole
- * thing just to release it all right away. It is safe to call this
- * function for an uninitialized library.
+ * Don't call normal FUNC_ENTER() since we don't want to initialize the
+ * whole library just to release it all right away. It is safe to call
+ * this function for an uninitialized library.
*/
- FUNC_ENTER_API_NOINIT(H5close)
+ FUNC_ENTER_API_NOINIT_NOFS(H5close)
H5TRACE0("e","");
H5_term_library();
- FUNC_LEAVE_API(SUCCEED)
+ FUNC_LEAVE_API_NOFS(SUCCEED)
}
diff --git a/src/H5CS.c b/src/H5CS.c
index 38d9e1b..ed7f8b6 100644
--- a/src/H5CS.c
+++ b/src/H5CS.c
@@ -84,8 +84,16 @@ H5FS_get_stack(void)
if (!fstack) {
/* no associated value with current thread - create one */
fstack = (H5FS_t *)HDmalloc(sizeof(H5FS_t)); /* Don't use H5MM_malloc() here, it causes infinite recursion */
- pthread_setspecific(H5TS_funcstk_key_g, (void *)fstack);
+ HDassert(fstack);
+
+ /* Set the thread-specific info */
fstack->nused=0;
+
+ /* (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)
+ */
+ pthread_setspecific(H5TS_funcstk_key_g, (void *)fstack);
}
FUNC_LEAVE_NOAPI_NOFS(fstack);
diff --git a/src/H5E.c b/src/H5E.c
index a3a363c..261a496 100644
--- a/src/H5E.c
+++ b/src/H5E.c
@@ -317,10 +317,18 @@ H5E_get_stack(void)
if (!estack) {
/* no associated value with current thread - create one */
estack = (H5E_t *)H5FL_MALLOC(H5E_t);
+ HDassert(estack);
+
+ /* Set the thread-specific info */
estack->nused = 0;
estack->new_api = TRUE;
estack->u.func_stack = (H5E_auto_stack_t)H5Eprint_stack;
estack->auto_data = 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)
+ */
pthread_setspecific(H5TS_errstk_key_g, (void *)estack);
}
diff --git a/src/H5FS.c b/src/H5FS.c
index 38d9e1b..ed7f8b6 100644
--- a/src/H5FS.c
+++ b/src/H5FS.c
@@ -84,8 +84,16 @@ H5FS_get_stack(void)
if (!fstack) {
/* no associated value with current thread - create one */
fstack = (H5FS_t *)HDmalloc(sizeof(H5FS_t)); /* Don't use H5MM_malloc() here, it causes infinite recursion */
- pthread_setspecific(H5TS_funcstk_key_g, (void *)fstack);
+ HDassert(fstack);
+
+ /* Set the thread-specific info */
fstack->nused=0;
+
+ /* (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)
+ */
+ pthread_setspecific(H5TS_funcstk_key_g, (void *)fstack);
}
FUNC_LEAVE_NOAPI_NOFS(fstack);
diff --git a/src/H5TS.c b/src/H5TS.c
index fa69fc8..184c0bd 100644
--- a/src/H5TS.c
+++ b/src/H5TS.c
@@ -95,8 +95,9 @@ H5TS_first_thread_init(void)
{
H5_g.H5_libinit_g = FALSE;
- /* set the two pthread_t objects to ``null'' */
- H5_g.init_lock.owner_thread = NULL;
+ /* set the owner objects to initial values */
+ H5_g.init_lock.owner_thread = pthread_self();
+ H5_g.init_lock.owner_valid = FALSE;
/* initialize global API mutex lock */
pthread_mutex_init(&H5_g.init_lock.atomic_lock, NULL);
@@ -148,36 +149,22 @@ H5TS_mutex_lock(H5TS_mutex_t *mutex)
if (ret_value)
return ret_value;
- if (mutex->owner_thread && pthread_equal(pthread_self(), *mutex->owner_thread)) {
+ if (mutex->owner_valid && pthread_equal(pthread_self(), mutex->owner_thread)) {
/* already owned by self - increment count */
mutex->lock_count++;
- } else if (!mutex->owner_thread) {
+ } else if (!mutex->owner_valid) {
/* no one else has locked it - set owner and grab lock */
- mutex->owner_thread = H5MM_malloc(sizeof(pthread_t));
-
- if (!mutex->owner_thread) {
- H5E_push_stack(NULL, "H5TS_mutex_lock", __FILE__, __LINE__,
- H5E_ERR_CLS_g, H5E_RESOURCE, H5E_NOSPACE, "memory allocation failed");
- return FAIL;
- }
-
- *mutex->owner_thread = pthread_self();
+ mutex->owner_thread = pthread_self();
+ mutex->owner_valid = TRUE;
mutex->lock_count = 1;
} else {
/* if already locked by someone else */
for (;;) {
pthread_cond_wait(&mutex->cond_var, &mutex->atomic_lock);
- if (!mutex->owner_thread) {
- mutex->owner_thread = H5MM_malloc(sizeof(pthread_t));
-
- if (!mutex->owner_thread) {
- H5E_push_stack(NULL, "H5TS_mutex_lock",
- __FILE__, __LINE__, H5E_ERR_CLS_g, H5E_RESOURCE, H5E_NOSPACE, "memory allocation failed");
- return FAIL;
- }
-
- *mutex->owner_thread = pthread_self();
+ if (!mutex->owner_valid) {
+ mutex->owner_thread = pthread_self();
+ mutex->owner_valid = TRUE;
mutex->lock_count = 1;
break;
}
@@ -226,8 +213,7 @@ H5TS_mutex_unlock(H5TS_mutex_t *mutex)
mutex->lock_count--;
if (mutex->lock_count == 0) {
- H5MM_xfree(mutex->owner_thread);
- mutex->owner_thread = NULL;
+ mutex->owner_valid = FALSE;
ret_value = pthread_cond_signal(&mutex->cond_var);
if (ret_value) {
diff --git a/src/H5TSprivate.h b/src/H5TSprivate.h
index f79e666..3ab08eb 100644
--- a/src/H5TSprivate.h
+++ b/src/H5TSprivate.h
@@ -35,7 +35,8 @@
/* Library level data structures */
typedef struct H5TS_mutex_struct {
- pthread_t *owner_thread; /* current lock owner */
+ pthread_t owner_thread; /* current lock owner */
+ unsigned owner_valid; /* if current lock owner info is valid */
pthread_mutex_t atomic_lock; /* lock for atomicity of new mechanism */
pthread_cond_t cond_var; /* condition variable */
unsigned int lock_count;
diff --git a/src/H5private.h b/src/H5private.h
index 28ec832..21e2d43 100644
--- a/src/H5private.h
+++ b/src/H5private.h
@@ -1238,7 +1238,7 @@ static herr_t H5_INTERFACE_INIT_FUNC(void);
/*
* Use this macro for API functions that shouldn't perform _any_ initialization
* of the library or an interface, just perform tracing, etc. Examples
- * are: H5close, H5check_version, etc.
+ * are: H5check_version, etc.
*
*/
#define FUNC_ENTER_API_NOINIT(func_name) {{ \
@@ -1249,6 +1249,20 @@ static herr_t H5_INTERFACE_INIT_FUNC(void);
BEGIN_MPE_LOG(func_name); \
{
+/*
+ * Use this macro for API functions that shouldn't perform _any_ initialization
+ * of the library or an interface or push themselves on the function
+ * stack, just perform tracing, etc. Examples
+ * are: H5close, etc.
+ *
+ */
+#define FUNC_ENTER_API_NOINIT_NOFS(func_name) {{ \
+ FUNC_ENTER_API_VARS(func_name) \
+ FUNC_ENTER_COMMON(func_name,H5_IS_API(#func_name)); \
+ FUNC_ENTER_API_THREADSAFE; \
+ BEGIN_MPE_LOG(func_name); \
+ {
+
/* Use this macro for all "normal" non-API functions */
#define FUNC_ENTER_NOAPI(func_name,err) { \
FUNC_ENTER_COMMON(func_name,!H5_IS_API(#func_name)); \
@@ -1353,6 +1367,14 @@ static herr_t H5_INTERFACE_INIT_FUNC(void);
} /*end scope from end of FUNC_ENTER*/ \
}} /*end scope from beginning of FUNC_ENTER*/
+#define FUNC_LEAVE_API_NOFS(ret_value) \
+ FINISH_MPE_LOG; \
+ H5TRACE_RETURN(ret_value); \
+ FUNC_LEAVE_API_THREADSAFE \
+ return (ret_value); \
+ } /*end scope from end of FUNC_ENTER*/ \
+}} /*end scope from beginning of FUNC_ENTER*/
+
#define FUNC_LEAVE_NOAPI(ret_value) \
H5_POP_FUNC; \
return (ret_value); \