diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/H5.c | 10 | ||||
-rw-r--r-- | src/H5CS.c | 10 | ||||
-rw-r--r-- | src/H5E.c | 8 | ||||
-rw-r--r-- | src/H5FS.c | 10 | ||||
-rw-r--r-- | src/H5TS.c | 36 | ||||
-rw-r--r-- | src/H5TSprivate.h | 3 | ||||
-rw-r--r-- | src/H5private.h | 24 |
7 files changed, 67 insertions, 34 deletions
@@ -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) } @@ -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); @@ -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); } @@ -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); @@ -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); \ |